]> xenbits.xensource.com Git - people/pauldu/xeniface.git/commitdiff
NOT FOR UPSTEAM: Add 'magic' support for-app-layering-demo
authorPaul Durrant <paul.durrant@citrix.com>
Wed, 5 Sep 2018 12:47:48 +0000 (13:47 +0100)
committerPaul Durrant <paul.durrant@citrix.com>
Wed, 26 Sep 2018 10:14:50 +0000 (11:14 +0100)
Add a new XcMagic() function to xencontrol.dll and an example application
('magic') that will link to it and call it.

The function takes a UNC path as input, writes it to a xentore key
(/local/domain/X/data/unc-path), and then waits for a value to be
written to another xenstore key (/local/domain/X/data/device-id). That
value (interpreted as a numeric) is passed back to the caller.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
include/xencontrol.h
include/xeniface_ioctls.h
src/magic/magic.c [new file with mode: 0644]
src/xencontrol/xencontrol.c
src/xeniface.inf
src/xeniface/ioctls.c
vs2017/magic/magic.vcxproj [new file with mode: 0644]
vs2017/magic/magic.vcxproj.user [new file with mode: 0644]
vs2017/package/package.vcxproj
vs2017/xeniface.sln

index 4560bc68984ed99ccb5b7a0004c5a9f3c652342b..febd239fdb17cec9252fcb91e9f7f8e12046e8d7 100644 (file)
@@ -335,6 +335,14 @@ XcStoreRemoveWatch(
     IN  PVOID Handle
     );
 
+XENCONTROL_API
+DWORD
+XcMagic(
+    IN  PXENCONTROL_CONTEXT Xc,
+    IN  PCHAR Path,
+    OUT PDWORD Device
+    );
+
 #ifdef __cplusplus
 }
 #endif
index dfb91dad0c530181c8e4bd22ea3d58729299ff43..8e0e4e5dec36a728d33c86a4465b74cb8569221e 100644 (file)
@@ -380,6 +380,10 @@ typedef struct _XENIFACE_SUSPEND_REGISTER_OUT {
 #define IOCTL_XENIFACE_LOG \
     CTL_CODE(FILE_DEVICE_UNKNOWN, 0x84F, METHOD_BUFFERED, FILE_ANY_ACCESS)
 
+
+#define IOCTL_XENIFACE_MAGIC \
+    CTL_CODE(FILE_DEVICE_UNKNOWN, 0x900, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
 /*! \brief Maximum number of CHARs for IOCTL_XENIFACE_LOG, including NUL terminator
 */
 #define XENIFACE_LOG_MAX_LENGTH         256
diff --git a/src/magic/magic.c b/src/magic/magic.c
new file mode 100644 (file)
index 0000000..aadc78c
--- /dev/null
@@ -0,0 +1,125 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source 1and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * *   Redistributions of source code must retain the above
+ *     copyright notice, this list of conditions and the23
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the
+ *     following disclaimer in the documentation and/or other
+ *     materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <windows.h>
+#include <stdio.h>
+
+#include <xencontrol.h>
+
+static void
+Logger(
+    _In_    XENCONTROL_LOG_LEVEL LogLevel,
+    _In_    const CHAR *Function,
+    _In_    const WCHAR *Message,
+    _In_    va_list Args
+    )
+{
+    UNREFERENCED_PARAMETER(LogLevel);
+
+    printf("%hs: ", Function);
+    vwprintf(Message, Args);
+    printf("\n");
+}
+
+static PWCHAR
+GetErrorMessage(
+    IN  DWORD   Error
+    )
+{
+    PWCHAR      Message;
+    ULONG       Index;
+
+    if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                       FORMAT_MESSAGE_FROM_SYSTEM |
+                       FORMAT_MESSAGE_IGNORE_INSERTS,
+                       NULL,
+                       Error,
+                       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                       (LPTSTR)&Message,
+                       0,
+                       NULL))
+        return NULL;
+
+    for (Index = 0; Message[Index] != '\0'; Index++) {
+        if (Message[Index] == '\r' || Message[Index] == '\n') {
+            Message[Index] = '\0';
+            break;
+        }
+    }
+
+    return Message;
+}
+
+int __cdecl
+main(
+    _In_    int         argc,
+    _In_    CHAR        *argv[]
+    )
+{
+    PCHAR               Path;
+    PXENCONTROL_CONTEXT Context;
+    DWORD               Error;
+    DWORD               Device;
+
+    if (argc != 2)
+        return 1;
+
+    Path = argv[1];
+
+    Error = XcOpen(Logger, &Context);
+    if (Error != ERROR_SUCCESS)
+        goto fail1;
+
+    Error = XcMagic(Context, Path, &Device);
+    if (Error != ERROR_SUCCESS)
+        goto fail2;
+
+    printf("Device = %u\n", (unsigned int)Device);
+
+    XcClose(Context);
+    return 0;
+
+fail2:
+    printf("fail2\n");
+
+    XcClose(Context);
+
+fail1:
+    {
+        PWCHAR  Message;
+        Message = GetErrorMessage(Error);
+
+        printf("fail1: %ws\n", Message);
+        LocalFree(Message);
+    }
+
+    return 1;
+}
index 777fd297c47288a73413767337a0df310c5dc3ee..e4bb41aa456e322209f849e2898fb811fdf02b1b 100644 (file)
@@ -917,3 +917,33 @@ fail:
     Log(XLL_ERROR, L"Error: 0x%x", GetLastError());
     return GetLastError();
 }
+
+DWORD
+XcMagic(
+    IN  PXENCONTROL_CONTEXT Xc,
+    IN  PCHAR Path,
+    OUT PDWORD Device
+    )
+{
+    DWORD Returned;
+    BOOL Success;
+
+    Log(XLL_DEBUG, L"Path: '%S'", Path);
+    Success = DeviceIoControl(Xc->XenIface,
+                              IOCTL_XENIFACE_MAGIC,
+                              Path, (DWORD)(strlen(Path) + 1),
+                              Device, sizeof(*Device),
+                              &Returned,
+                              NULL);
+
+    if (!Success) {
+        Log(XLL_ERROR, L"IOCTL_XENIFACE_MAGIC failed");
+        goto fail;
+    }
+
+    return ERROR_SUCCESS;
+
+fail:
+    Log(XLL_ERROR, L"Error: 0x%x", GetLastError());
+    return GetLastError();
+}
index 75d44eb4711f9be66f59a59acc48ece4720f461d..9615a41b05c6758752ba15730ad2a0c1e70833a6 100644 (file)
@@ -40,7 +40,8 @@ DriverPackageDisplayName=%DiskId1%
 [DestinationDirs]
 DefaultDestDir = 12
 Coinst.NT.Copy = 11
-ServiceDestDir.NT.Copy = 11
+Service.NT.Copy = 11
+Lib.NT.Copy = 11
 
 [Manufacturer]
 %Vendor%=Inst,NT$ARCH$
@@ -55,7 +56,8 @@ ServiceDestDir.NT.Copy = 11
 
 [XenIface_Device.NT$ARCH$]
 CopyFiles=XenIface_Device.NT.Copy
-CopyFiles=ServiceDestDir.NT.Copy
+CopyFiles=Service.NT.Copy
+CopyFiles=Lib.NT.Copy
 
 [XenIFace_Device.NT.Copy]
 xeniface.sys
@@ -63,10 +65,14 @@ xeniface.sys
 [CoInst.NT.Copy]
 xeniface_coinst_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.dll,xeniface_coinst.dll
 
-[ServiceDestDir.NT.Copy]
+[Service.NT.Copy]
 xenagent_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.exe,xenagent.exe
 xenagent_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.dll,xenagent.dll
 
+[Lib.NT.Copy]
+xencontrol.dll
+magic.exe
+
 [Xeniface_Device.NT$ARCH$.Services]
 AddService = xeniface, %SPSVCINST_ASSOCSERVICE%, xeniface_Service_Inst
 AddService = xenagent, %XENAGENT_FLAGS%, xenagent_Service_Inst,xenagent_EventLog
@@ -111,7 +117,9 @@ HKR,,TypesSupported,0x00010001,7
 xeniface.sys  = 1,,
 xenagent.exe = 1,,
 xenagent.dll = 1,,
-xeniface_coinst.dll=1,,
+xeniface_coinst.dll = 1,,
+xencontrol.dll = 1,,
+magic.exe = 1,,
 
 [Strings]
 SPSVCINST_ASSOCSERVICE= 0x00000002
index bf280cbbfe413de1aaab20bce6d176a1bd7f0770..5fd5a46cdc5e6c54152877ace074d5a6102b5010 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <ntifs.h>
 #include <procgrp.h>
+#include <stdlib.h>
 #include "driver.h"
 #include "ioctls.h"
 #include "xeniface_ioctls.h"
@@ -141,6 +142,91 @@ fail1:
     return status;
 }
 
+#define TIME_US(_us)            ((_us) * 10ll)
+#define TIME_MS(_ms)            (TIME_US((_ms) * 1000ll))
+#define TIME_S(_s)              (TIME_MS((_s) * 1000ll))
+#define TIME_RELATIVE(_t)       (-(_t))
+
+DECLSPEC_NOINLINE
+NTSTATUS
+IoctlMagic(
+    __in  PXENIFACE_FDO     Fdo,
+    __in  PCHAR             Buffer,
+    __in  ULONG             InLen,
+    __in  ULONG             OutLen,
+    __in  PULONG_PTR        Info
+    )
+{
+    PCHAR                   Value;
+    NTSTATUS                status;
+
+    status = STATUS_INVALID_BUFFER_SIZE;
+    if (InLen == 0 || InLen > _MAX_PATH || OutLen != sizeof(ULONG))
+        goto fail1;
+
+    status = STATUS_INVALID_PARAMETER;
+    if (!__IsValidStr(Buffer, InLen))
+        goto fail2;
+
+    Trace("PATH: %s\n", Buffer);
+
+    (VOID) XENBUS_STORE(Remove,
+                        &Fdo->StoreInterface,
+                        NULL,
+                        NULL,
+                        "data/device-id");
+
+    status = XENBUS_STORE(Printf,
+                          &Fdo->StoreInterface,
+                          NULL,
+                          NULL,
+                          "data/unc-path",
+                          "%s",
+                          Buffer);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+again:
+    status = XENBUS_STORE(Read,
+                          &Fdo->StoreInterface,
+                          NULL,
+                          NULL,
+                          "data/device-id",
+                          &Value);
+    if (!NT_SUCCESS(status)) {
+        if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
+            LARGE_INTEGER   Delay;
+
+            Delay.QuadPart = TIME_RELATIVE(TIME_S(1));
+
+            KeDelayExecutionThread(KernelMode, FALSE, &Delay);
+            goto again;
+        }
+
+        goto fail4;
+    }
+
+    *(PULONG)Buffer = strtol(Value, NULL, 0);
+
+    XENBUS_STORE(Free,
+                 &Fdo->StoreInterface,
+                 Value);
+
+    *Info = (ULONG_PTR)sizeof(ULONG);
+
+    return STATUS_SUCCESS;
+
+fail4:
+    Error("Fail4\n");
+fail3:
+    Error("Fail3\n");
+fail2:
+    Error("Fail2\n");
+fail1:
+    Error("Fail1 (%08x)\n", status);
+    return status;
+}
+
 // Cleanup store watches and event channels, called on file object close.
 _IRQL_requires_(PASSIVE_LEVEL) // EvtchnFree calls KeFlushQueuedDpcs
 VOID
@@ -337,6 +423,10 @@ XenIfaceIoctl(
         status = IoctlLog(Fdo, Buffer, InLen, OutLen);
         break;
 
+    case IOCTL_XENIFACE_MAGIC:
+        status = IoctlMagic(Fdo, Buffer, InLen, OutLen, &Irp->IoStatus.Information);
+        break;
+
     default:
         status = STATUS_INVALID_DEVICE_REQUEST;
         break;
diff --git a/vs2017/magic/magic.vcxproj b/vs2017/magic/magic.vcxproj
new file mode 100644 (file)
index 0000000..e05ba23
--- /dev/null
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\configs.props" />
+  <PropertyGroup Label="PropertySheets">
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+    <ConfigurationType>Application</ConfigurationType>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{A29E3210-7562-46EC-A26B-200C99646313}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="..\targets.props" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <PropertyGroup>
+    <IncludePath>$(IncludePath)</IncludePath>
+    <RunCodeAnalysis>true</RunCodeAnalysis>
+    <EnableInf2cat>false</EnableInf2cat>
+  </PropertyGroup>
+  <PropertyGroup>
+    <CustomBuildAfterTargets>Link</CustomBuildAfterTargets>
+  </PropertyGroup>
+  <ItemDefinitionGroup>
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(SolutionDir)..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>PROJECT=$(ProjectName);WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <WarningLevel>EnableAllWarnings</WarningLevel>
+      <DisableSpecificWarnings>4127;4350;4365;4571;4625;4626;4711;4774;4548;4820;4668;4255;5026;5027;5038;5039;6001;6054;28196;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <EnablePREfast>true</EnablePREfast>
+      <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebug</RuntimeLibrary>
+      <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='false'">MultiThreaded</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>$(OutDir)xencontrol.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <SubSystem>Console</SubSystem>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>$(SolutionDir)..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
+    <ClCompile>
+      <PreprocessorDefinitions>__i386__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Platform)'=='x64'">
+    <ClCompile>
+      <PreprocessorDefinitions>__x86_64__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <FilesToPackage Include="$(TargetPath)" />
+    <FilesToPackage Include="$(OutDir)$(TargetName).pdb" />
+    <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\src\magic\magic.c" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/vs2017/magic/magic.vcxproj.user b/vs2017/magic/magic.vcxproj.user
new file mode 100644 (file)
index 0000000..510ca8a
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup />
+</Project>
index 70603122710782bc3b5c0659792028a3cbc8ca40..930789b61e5226c81d00fbf0e3ff2cd4f0968520 100644 (file)
@@ -45,6 +45,9 @@
     <ProjectReference Include="..\xencontrol\xencontrol.vcxproj">
       <Project>{D386D8E9-D015-4AD2-A5C2-4F845A803FA2}</Project>
     </ProjectReference>
+    <ProjectReference Include="..\magic\magic.vcxproj">
+      <Project>{A29E3210-7562-46EC-A26B-200C99646313}</Project>
+    </ProjectReference>
   </ItemGroup>
   <ItemGroup Condition="Exists('$(DPINST_REDIST)')">
     <FilesToPackage Include="$(DPINST_REDIST)\x86\dpinst.exe" Condition="'$(Platform)'=='Win32'" />
index 1eb81563243b0c279b4d83523c16c7b32f509308..579a0f210e91f3f6c5589d79b233ef9c7c7f209b 100644 (file)
@@ -10,12 +10,18 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xenagent", "xenagent\xenage
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xencontrol", "xencontrol\xencontrol.vcxproj", "{D386D8E9-D015-4AD2-A5C2-4F845A803FA2}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "magic", "magic\magic.vcxproj", "{A29E3210-7562-46EC-A26B-200C99646313}"
+       ProjectSection(ProjectDependencies) = postProject
+               {D386D8E9-D015-4AD2-A5C2-4F845A803FA2} = {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}
+       EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "package", "package\package.vcxproj", "{9B071A35-897C-477A-AEB7-95F77618A21D}"
        ProjectSection(ProjectDependencies) = postProject
                {22166290-65D8-49D2-BB88-33201797C7D8} = {22166290-65D8-49D2-BB88-33201797C7D8}
                {85C731AD-2EA2-4049-A542-D2D38EDE938C} = {85C731AD-2EA2-4049-A542-D2D38EDE938C}
                {2E61D2CC-865E-442C-8C83-B8DAFD7BBD3B} = {2E61D2CC-865E-442C-8C83-B8DAFD7BBD3B}
                {D386D8E9-D015-4AD2-A5C2-4F845A803FA2} = {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}
+               {A29E3210-7562-46EC-A26B-200C99646313} = {A29E3210-7562-46EC-A26B-200C99646313}
        EndProjectSection
 EndProject
 Global
@@ -150,6 +156,30 @@ Global
                {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 10 Release|x64.ActiveCfg = Windows 10 Release|x64
                {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 10 Release|x64.Build.0 = Windows 10 Release|x64
                {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 10 Release|x64.Deploy.0 = Windows 10 Release|x64
+               {A29E3210-7562-46EC-A26B-200C99646313}.Windows 8 Debug|Win32.ActiveCfg = Windows 8 Debug|Win32
+               {A29E3210-7562-46EC-A26B-200C99646313}.Windows 8 Debug|Win32.Build.0 = Windows 8 Debug|Win32
+               {A29E3210-7562-46EC-A26B-200C99646313}.Windows 8 Debug|Win32.Deploy.0 = Windows 8 Debug|Win32
+               {A29E3210-7562-46EC-A26B-200C99646313}.Windows 8 Debug|x64.ActiveCfg = Windows 8 Debug|x64
+               {A29E3210-7562-46EC-A26B-200C99646313}.Windows 8 Debug|x64.Build.0 = Windows 8 Debug|x64
+               {A29E3210-7562-46EC-A26B-200C99646313}.Windows 8 Debug|x64.Deploy.0 = Windows 8 Debug|x64
+               {A29E3210-7562-46EC-A26B-200C99646313}.Windows 8 Release|Win32.ActiveCfg = Windows 8 Release|Win32
+               {A29E3210-7562-46EC-A26B-200C99646313}.Windows 8 Release|Win32.Build.0 = Windows 8 Release|Win32
+               {A29E3210-7562-46EC-A26B-200C99646313}.Windows 8 Release|Win32.Deploy.0 = Windows 8 Release|Win32
+               {A29E3210-7562-46EC-A26B-200C99646313}.Windows 8 Release|x64.ActiveCfg = Windows 8 Release|x64
+               {A29E3210-7562-46EC-A26B-200C99646313}.Windows 8 Release|x64.Build.0 = Windows 8 Release|x64
+               {A29E3210-7562-46EC-A26B-200C99646313}.Windows 8 Release|x64.Deploy.0 = Windows 8 Release|x64
+               {A29E3210-7562-46EC-A26B-200C99646313}.Windows 10 Debug|Win32.ActiveCfg = Windows 10 Debug|Win32
+               {A29E3210-7562-46EC-A26B-200C99646313}.Windows 10 Debug|Win32.Build.0 = Windows 10 Debug|Win32
+               {A29E3210-7562-46EC-A26B-200C99646313}.Windows 10 Debug|Win32.Deploy.0 = Windows 10 Debug|Win32
+               {A29E3210-7562-46EC-A26B-200C99646313}.Windows 10 Debug|x64.ActiveCfg = Windows 10 Debug|x64
+               {A29E3210-7562-46EC-A26B-200C99646313}.Windows 10 Debug|x64.Build.0 = Windows 10 Debug|x64
+               {A29E3210-7562-46EC-A26B-200C99646313}.Windows 10 Debug|x64.Deploy.0 = Windows 10 Debug|x64
+               {A29E3210-7562-46EC-A26B-200C99646313}.Windows 10 Release|Win32.ActiveCfg = Windows 10 Release|Win32
+               {A29E3210-7562-46EC-A26B-200C99646313}.Windows 10 Release|Win32.Build.0 = Windows 10 Release|Win32
+               {A29E3210-7562-46EC-A26B-200C99646313}.Windows 10 Release|Win32.Deploy.0 = Windows 10 Release|Win32
+               {A29E3210-7562-46EC-A26B-200C99646313}.Windows 10 Release|x64.ActiveCfg = Windows 10 Release|x64
+               {A29E3210-7562-46EC-A26B-200C99646313}.Windows 10 Release|x64.Build.0 = Windows 10 Release|x64
+               {A29E3210-7562-46EC-A26B-200C99646313}.Windows 10 Release|x64.Deploy.0 = Windows 10 Release|x64
        EndGlobalSection
        GlobalSection(SolutionProperties) = preSolution
                HideSolutionNode = FALSE