summaryrefslogtreecommitdiff
path: root/general/installwdf
diff options
context:
space:
mode:
Diffstat (limited to 'general/installwdf')
-rw-r--r--general/installwdf/Install.cpp509
-rw-r--r--general/installwdf/InstallWdf.vcxproj187
-rw-r--r--general/installwdf/InstallWdf.vcxproj.Filters22
-rw-r--r--general/installwdf/ReadMe.md9
-rw-r--r--general/installwdf/installwdf.sln28
5 files changed, 755 insertions, 0 deletions
diff --git a/general/installwdf/Install.cpp b/general/installwdf/Install.cpp
new file mode 100644
index 00000000..cd89e284
--- /dev/null
+++ b/general/installwdf/Install.cpp
@@ -0,0 +1,509 @@
+#include <Windows.h>
+#include <stdio.h>
+#include <strsafe.h>
+#include <wuerror.h>
+
+//
+// These defines control which packages need to be updated. In order to
+// to customize this for your drivers needs, edit needed packages to 1 and
+// unneeded packages to 0.
+//
+// If your UMDF driver uses USB functionality, you also need KMDF and WinUSB
+//
+#define INSTALL_KMDF (TRUE)
+#define INSTALL_WINUSB (TRUE)
+#define INSTALL_UMDF (TRUE)
+
+//
+// Reference strings that are used to build our MSU package name. These will
+// change between releases of the framework and will need to be updated
+//
+#define WINUSB_UPDATE_NAME L"WinUSB_1.9.msu"
+
+//
+// MSU names are of the format:
+// <kmdf|umdf>-<wdf major version>.<wdf minor version>-
+// Win-<windows major version>.<windows minor version>.msu
+//
+#define MSU_FORMAT_STRING L"%s-%d.%d-Win-%d.%d.msu"
+
+#define WUSA_EXE L"%windir%\\system32\\wusa.exe"
+
+#define WUSA_EXE_ARGUMENTS L"/quiet /norestart"
+
+#define WDF_MAJOR_VERSION 1
+#define WDF_MINOR_VERSION 11
+
+DWORD
+ApplyUpdate(
+ PCWSTR MSUName
+)
+{
+ DWORD error = ERROR_SUCCESS;
+ size_t cmdLengthBytes;
+ size_t applicationLengthBytes;
+ BOOL ok;
+ PROCESS_INFORMATION pInfo;
+ STARTUPINFOW startInfo;
+ PWCHAR applicationName = NULL;
+ PWCHAR commandLine = NULL;
+ HRESULT hr;
+
+ ZeroMemory(&startInfo,sizeof(startInfo)) ;
+ startInfo.cb = sizeof(STARTUPINFO) ;
+
+ ZeroMemory(&pInfo,sizeof(pInfo));
+ //
+ // Check that the update package exists
+ //
+ error = GetFileAttributes(MSUName);
+
+ if (error == INVALID_FILE_ATTRIBUTES) {
+ error = GetLastError();
+ wprintf(L"Error: Could not find update file %s; error %x\n", MSUName, error);
+ goto exit;
+ }
+
+ //
+ // Invoke wusa
+ //
+ applicationName = (PWCHAR) LocalAlloc(LPTR, (MAX_PATH + 1)*sizeof(WCHAR));
+ if (applicationName == NULL) {
+ error = ERROR_INSTALL_FAILURE;
+ wprintf(L"Failed to allocate applicationName buffer\n");
+ goto exit;
+ }
+
+ applicationName[0] = L'\0';
+
+ applicationLengthBytes = ExpandEnvironmentStrings(WUSA_EXE,
+ applicationName,
+ MAX_PATH+1);
+
+ if ((applicationLengthBytes == 0) ||
+ (applicationLengthBytes > MAX_PATH+1)) {
+ wprintf(L"Could not expland %s\n", WUSA_EXE);
+ error = ERROR_INSTALL_FAILURE;
+ goto exit;
+ }
+
+ applicationLengthBytes = sizeof(WCHAR) * applicationLengthBytes;
+
+ hr = StringCbLength(MSUName,
+ MAX_PATH * sizeof(WCHAR),
+ &cmdLengthBytes);
+
+ if (hr != S_OK) {
+
+ error = ERROR_INSTALL_FAILURE;
+ wprintf(L"StringCbLength failed MSUName, %x\n",
+ hr);
+ goto exit;
+ }
+ //
+ // Add enough padding for 2 \". The size returned by sizeof() includes
+ // the terminating L'\0'
+ //
+ cmdLengthBytes = applicationLengthBytes + cmdLengthBytes + sizeof(WUSA_EXE_ARGUMENTS) + 3*sizeof(WCHAR);
+
+ commandLine = (PWCHAR) LocalAlloc(LPTR, cmdLengthBytes );
+
+ if (commandLine == NULL) {
+ wprintf(L"Failed to allocate applicationName buffer\n");
+ error = ERROR_INSTALL_FAILURE;
+ goto exit;
+ }
+
+ hr = StringCbPrintf(commandLine,
+ cmdLengthBytes,
+ L"%s \"%s\" %s",
+ applicationName,
+ MSUName,
+ WUSA_EXE_ARGUMENTS);
+ if (hr != S_OK) {
+
+ error = ERROR_INSTALL_FAILURE;
+ wprintf(L"StringCbPrintf failed for applicationParameters, %x\n",
+ hr);
+ goto exit;
+ }
+
+ wprintf(L"Invoking: %s\n", commandLine);
+
+ ok = CreateProcess(applicationName, // name of executable module
+ commandLine, // command line string
+ NULL, // SD
+ NULL, // SD
+ TRUE, // handle inheritance option
+ 0, // creation flags CREATE_NO_WINDOW
+ NULL, // new environment block
+ NULL, // current directory name
+ &startInfo, // startup information
+ &pInfo // process information
+ );
+
+ if (ok == FALSE) {
+
+ error = GetLastError();
+ wprintf(L"Create process failed : %x\n",
+ error);
+ goto exit;
+
+ } else {
+
+ //
+ // Wait until child process exits.
+ //
+
+ error = WaitForSingleObject( pInfo.hProcess, INFINITE );
+
+ if ( error != WAIT_OBJECT_0 ) {
+ //
+ // It can't hurt to add this
+ //
+ TerminateProcess(pInfo.hProcess, (UINT)-1);
+ }
+
+ GetExitCodeProcess(pInfo.hProcess, &error);
+
+ //
+ // The possible return values for wusa.exe are:
+ // 1)ERROR_SUCCESS (0) : installation was successfull
+ // 2)ERROR_SUCCESS_REBOOT_REQUIRED (3010) : installation was successful,
+ // however a reboot is required, so that the binaries will be
+ // loaded to memory
+ // 3)S_FALSE (1) (Vista) OR WU_S_ALREADY_INSTALLED (240006) (Win7):
+ // No action was taken (i.e. files were already installed)
+ // 4)Everything else (e.g. ERROR_INSTALL_FAILURE) is an error
+ //
+
+ switch (error) {
+ case S_FALSE:
+ case WU_S_ALREADY_INSTALLED:
+ wprintf(L"The package was already installed in the system\n");
+ error = ERROR_SUCCESS;
+ break;
+ case ERROR_SUCCESS:
+ wprintf(L"The package was installed successfully\n");
+ break;
+ case ERROR_SUCCESS_REBOOT_REQUIRED:
+ wprintf(L"The package was installed successfully but requires a reboot\n");
+ break;
+ case ERROR_SERVICE_DISABLED:
+ case WU_E_WU_DISABLED:
+
+ //
+ // If the "Windows Update" service is disabled, then wusa
+ // returns ERROR_SERVICE_DISABLED
+ //
+
+ wprintf(L"The \"Windows Update\" service is disabled. It "
+ L"has to be enabled for the installation to succeed."
+ L"\n");
+ break;
+ default:
+ wprintf(L"The update process returned error code :%x. ",
+ error);
+ wprintf(L"For additional information please look at the log "
+ L"files %%windir%%\\windowsupdate.log and "
+ L"%%windir%%\\Logs\\CBS\\CBS.log\n");
+ break;
+ }
+
+ CloseHandle(pInfo.hProcess);
+ CloseHandle(pInfo.hThread);
+ }
+
+exit:
+ if (commandLine != NULL) {
+ LocalFree(commandLine);
+ commandLine = NULL;
+ }
+
+ if (applicationName != NULL) {
+ LocalFree(applicationName);
+ applicationName = NULL;
+ }
+
+ return error;
+}
+
+BOOL
+PromptRestart()
+{
+ HANDLE hToken; // handle to process token
+ TOKEN_PRIVILEGES tkp; // pointer to token structure
+ BOOL fResult; // system shutdown flag
+
+ // Get the current process token handle so we can get shutdown
+ // privilege.
+
+ if (!OpenProcessToken(GetCurrentProcess(),
+ TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
+ return FALSE;
+
+ // Get the LUID for shutdown privilege.
+
+ LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
+ &tkp.Privileges[0].Luid);
+
+ tkp.PrivilegeCount = 1; // one privilege to set
+ tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+ // Get shutdown privilege for this process.
+
+ AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
+ (PTOKEN_PRIVILEGES) NULL, 0);
+
+ // Cannot test the return value of AdjustTokenPrivileges.
+
+ if (GetLastError() != ERROR_SUCCESS) {
+ return FALSE;
+ }
+
+ // Display the shutdown dialog box and start the countdown.
+
+ #pragma prefast(suppress:28159, "Ignore the suggestion against system shutdown.")
+ fResult = InitiateSystemShutdownEx(
+ NULL, // shut down local computer
+ NULL, // message for user
+ 0, // time-out period, in seconds
+ FALSE, // ask user to close apps
+ TRUE, // reboot after shutdown
+ SHTDN_REASON_FLAG_PLANNED // shutdown reason
+ | SHTDN_REASON_MAJOR_SOFTWARE
+ | SHTDN_REASON_MINOR_UPGRADE);
+
+ // Disable shutdown privilege.
+
+ tkp.Privileges[0].Attributes = 0;
+ AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
+ (PTOKEN_PRIVILEGES) NULL, 0);
+
+ return fResult;
+
+}
+
+DWORD
+UpdateWdf(
+ VOID
+ )
+{
+ BOOL ok;
+ OSVERSIONINFO curOsvi;
+ OSVERSIONINFOEX targetOsvi;
+ DWORDLONG dwlConditionMask = 0;
+ WCHAR MSUName[MAX_PATH];
+ BOOL rebootNeeded = FALSE;
+ DWORD error = ERROR_SUCCESS;
+ HRESULT hr;
+
+ //
+ // Make sure updates are valid for this operating system.
+ // Vista SP1/SP2; Win7 RTM
+ // TODO: what happens on Vista RTM/SP3+/Win7 SP1+
+ //
+
+ ZeroMemory(&targetOsvi, sizeof(OSVERSIONINFOEX));
+ dwlConditionMask = 0;
+
+ targetOsvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+ targetOsvi.dwMajorVersion = 6;
+ targetOsvi.dwMinorVersion = 0;
+ targetOsvi.wServicePackMajor = 0;
+
+ VER_SET_CONDITION( dwlConditionMask, VER_MAJORVERSION, VER_LESS_EQUAL );
+ VER_SET_CONDITION( dwlConditionMask, VER_MINORVERSION, VER_LESS_EQUAL );
+ VER_SET_CONDITION( dwlConditionMask, VER_SERVICEPACKMAJOR, VER_LESS_EQUAL );
+
+ ok = VerifyVersionInfo( &targetOsvi,
+ VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR,
+ dwlConditionMask);
+
+ if (ok) {
+ wprintf(L"Error: Updates are not supported on OS before Vista or Vista RTM\n");
+ error = ERROR_OLD_WIN_VERSION;
+ goto exit;
+ }
+
+ //
+ // No need to update on Win8+
+ //
+ ZeroMemory(&targetOsvi, sizeof(OSVERSIONINFOEX));
+ dwlConditionMask = 0;
+
+ targetOsvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+ targetOsvi.dwMajorVersion = 6;
+ targetOsvi.dwMinorVersion = 2;
+
+ VER_SET_CONDITION( dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL );
+ VER_SET_CONDITION( dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL );
+
+ ok = VerifyVersionInfo( &targetOsvi,
+ VER_MAJORVERSION | VER_MINORVERSION,
+ dwlConditionMask);
+
+ if (ok) {
+ wprintf(L"Updates are not needed to Windows 8, they are already inbox\n");
+ error = ERROR_SUCCESS;
+ goto exit;
+ }
+
+ //
+ // Create MSU name
+ //
+
+ ZeroMemory(&curOsvi, sizeof(OSVERSIONINFO));
+ curOsvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+#pragma warning( push )
+#pragma warning( disable : 4996 ) // 'GetVersionEx': was declared deprecated
+ ok = GetVersionEx(&curOsvi);
+
+ if (ok == FALSE) {
+
+ error = GetLastError();
+ wprintf(L"GetVersionEx failed: %x\n", error);
+ goto exit;
+ }
+
+ //
+ // We want to apply the updates in a specific order. This is because UMDF
+ // is potentially dependent on WinUSB. WinUSB is dependent on KMDF. If we
+ // fail to apply an update, we want to make sure the machine is in a good
+ // state. This we apply required framework updates first.
+ // KMDF > WinUSB > UMDF
+ //
+
+#if INSTALL_KMDF
+ hr = StringCchPrintf(MSUName,
+ MAX_PATH,
+ MSU_FORMAT_STRING,
+ L"kmdf",
+ WDF_MAJOR_VERSION,
+ WDF_MINOR_VERSION,
+ curOsvi.dwMajorVersion,
+ curOsvi.dwMinorVersion);
+
+ if (hr != S_OK) {
+ wprintf(L"StringCchPrintf for KMDF MSU failed: %x\n", hr);
+ error = ERROR_INSTALL_FAILURE;
+ goto exit;
+ }
+
+ error = ApplyUpdate(MSUName);
+
+ if (error == ERROR_SUCCESS_REBOOT_REQUIRED) {
+ rebootNeeded = TRUE;
+ } else if (error != ERROR_SUCCESS) {
+ goto exit;
+ }
+#endif // INSTALL_KMDF
+#pragma warning( pop ) // 'GetVersionEx': was declared deprecated
+
+#if (INSTALL_WINUSB)
+ //
+ // WinUSB update only applies to Vista
+ //
+
+ ZeroMemory(&targetOsvi, sizeof(OSVERSIONINFOEX));
+ dwlConditionMask = 0;
+
+ targetOsvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+ targetOsvi.dwMajorVersion = 6;
+ targetOsvi.dwMinorVersion = 0;
+
+ VER_SET_CONDITION( dwlConditionMask, VER_MAJORVERSION, VER_EQUAL );
+ VER_SET_CONDITION( dwlConditionMask, VER_MINORVERSION, VER_EQUAL );
+
+ ok = VerifyVersionInfo( &targetOsvi,
+ VER_MAJORVERSION | VER_MINORVERSION,
+ dwlConditionMask);
+
+ if (ok) {
+ error = ApplyUpdate(WINUSB_UPDATE_NAME);
+
+ if (error == ERROR_SUCCESS_REBOOT_REQUIRED) {
+ rebootNeeded = TRUE;
+ } else if (error != ERROR_SUCCESS) {
+ goto exit;
+ }
+ }
+#endif // INSTALL_WINUSB
+
+#if INSTALL_UMDF
+ hr = StringCchPrintf(MSUName,
+ MAX_PATH,
+ MSU_FORMAT_STRING,
+ L"umdf",
+ WDF_MAJOR_VERSION,
+ WDF_MINOR_VERSION,
+ curOsvi.dwMajorVersion,
+ curOsvi.dwMinorVersion);
+
+ if (hr != S_OK) {
+ wprintf(L"StringCchPrintf for UMDF MSU failed: %x\n", hr);
+ error = ERROR_INSTALL_FAILURE;
+ goto exit;
+ }
+
+ error = ApplyUpdate(MSUName);
+
+ if (error == ERROR_SUCCESS_REBOOT_REQUIRED) {
+ rebootNeeded = TRUE;
+ } else if (error != ERROR_SUCCESS) {
+ goto exit;
+ }
+#endif // INSTALL_UMDF
+
+ //
+ // If we have made it to this point there have been no fatal errors. If
+ // there were fatal errors, these should be caught and we would've jumped
+ // to exit.
+ //
+ // We must account for the fact the latest update applied did not require
+ // a reboot but earlier updates did.
+ //
+ if (rebootNeeded == TRUE) {
+
+ error = ERROR_SUCCESS_REBOOT_REQUIRED;
+ goto exit;
+ }
+
+ error = ERROR_SUCCESS;
+
+exit:
+
+ return error;
+}
+
+int __cdecl
+wmain(
+ _In_ int argc,
+ _In_reads_(argc) char* argv[]
+ )
+{
+ DWORD updateStatus;
+
+ UNREFERENCED_PARAMETER(argc);
+ UNREFERENCED_PARAMETER(argv);
+
+ updateStatus = UpdateWdf();
+
+ if (updateStatus == ERROR_SUCCESS_REBOOT_REQUIRED) {
+
+ int msgboxID = MessageBox(
+ NULL,
+ L"A restart is needed for these changes to take effect\nRestart now?",
+ L"Restart Required",
+ MB_ICONEXCLAMATION | MB_YESNO
+ );
+
+ if (msgboxID == IDYES)
+ {
+ PromptRestart();
+ }
+ }
+
+ return updateStatus;
+}
diff --git a/general/installwdf/InstallWdf.vcxproj b/general/installwdf/InstallWdf.vcxproj
new file mode 100644
index 00000000..566e44b1
--- /dev/null
+++ b/general/installwdf/InstallWdf.vcxproj
@@ -0,0 +1,187 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{242C8F74-1471-4876-ABE9-F9B3798F7537}</ProjectGuid>
+ <RootNamespace>$(MSBuildProjectName)</RootNamespace>
+ <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <SampleGuid>{EC6592EB-25EF-40EB-8E93-87FABB3C6085}</SampleGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ItemGroup Label="WrappedTaskItems" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>InstallWdf</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>InstallWdf</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>InstallWdf</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>InstallWdf</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib;user32.lib</AdditionalDependencies>
+ </Link>
+ <ClCompile>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib;user32.lib</AdditionalDependencies>
+ </Link>
+ <ClCompile>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib;user32.lib</AdditionalDependencies>
+ </Link>
+ <ClCompile>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib;user32.lib</AdditionalDependencies>
+ </Link>
+ <ClCompile>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="install.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Exclude="@(Inf)" Include="*.inf" />
+ <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
+ <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
+ <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
+ <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project> \ No newline at end of file
diff --git a/general/installwdf/InstallWdf.vcxproj.Filters b/general/installwdf/InstallWdf.vcxproj.Filters
new file mode 100644
index 00000000..aded6d8a
--- /dev/null
+++ b/general/installwdf/InstallWdf.vcxproj.Filters
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
+ <UniqueIdentifier>{5F54DABF-B262-4C6D-922E-4458AB12ED8C}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ <UniqueIdentifier>{7D22CB0D-9813-4E12-B539-5F8A9BCC71F1}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
+ <UniqueIdentifier>{13558A71-E018-47D4-B9A5-45A8C27B32B1}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="install.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/general/installwdf/ReadMe.md b/general/installwdf/ReadMe.md
new file mode 100644
index 00000000..429957d5
--- /dev/null
+++ b/general/installwdf/ReadMe.md
@@ -0,0 +1,9 @@
+WDF Installation Package
+========================
+
+This sample contains example code that demonstrates how to install WDF packages on a system. This code can be used as-is to install the needed WDF components onto a user system. This code can also be reworked into an existing setup application to provide a better experience.
+
+
+Related technologies
+--------------------
+[Installation Components for Framework-based Drivers](http://msdn.microsoft.com/en-us/library/windows/hardware/ff544208)
diff --git a/general/installwdf/installwdf.sln b/general/installwdf/installwdf.sln
new file mode 100644
index 00000000..e520c1dc
--- /dev/null
+++ b/general/installwdf/installwdf.sln
@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0
+MinimumVisualStudioVersion = 12.0
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "InstallWdf", "InstallWdf.vcxproj", "{242C8F74-1471-4876-ABE9-F9B3798F7537}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {242C8F74-1471-4876-ABE9-F9B3798F7537}.Debug|Win32.ActiveCfg = Debug|Win32
+ {242C8F74-1471-4876-ABE9-F9B3798F7537}.Debug|Win32.Build.0 = Debug|Win32
+ {242C8F74-1471-4876-ABE9-F9B3798F7537}.Release|Win32.ActiveCfg = Release|Win32
+ {242C8F74-1471-4876-ABE9-F9B3798F7537}.Release|Win32.Build.0 = Release|Win32
+ {242C8F74-1471-4876-ABE9-F9B3798F7537}.Debug|x64.ActiveCfg = Debug|x64
+ {242C8F74-1471-4876-ABE9-F9B3798F7537}.Debug|x64.Build.0 = Debug|x64
+ {242C8F74-1471-4876-ABE9-F9B3798F7537}.Release|x64.ActiveCfg = Release|x64
+ {242C8F74-1471-4876-ABE9-F9B3798F7537}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal