[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [win-pv-devel] [PATCH] Add a user mode library wrapper for XENIFACE IOCTLs



> -----Original Message-----
> From: win-pv-devel [mailto:win-pv-devel-bounces@xxxxxxxxxxxxxxxxxxxx] On
> Behalf Of Marek Marczykowski-Górecki
> Sent: 09 July 2018 11:22
> To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx
> Cc: Rafal Wojdyla <omeg@xxxxxxxxxxxxxxxxxxxxxx>; Marek Marczykowski-
> Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
> Subject: [win-pv-devel] [PATCH] Add a user mode library wrapper for
> XENIFACE IOCTLs
> 
> From: Rafal Wojdyla <omeg@xxxxxxxxxxxxxxxxxxxxxx>
> 
> Signed-off-by: Rafal Wojdyla <omeg@xxxxxxxxxxxxxxxxxxxxxx>
> [fix compile warnings, update visual studio files]
> Signed-off-by: Marek Marczykowski-Górecki
> <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
> ---
> This was posted before here:
> https://lists.xenproject.org/archives/html/win-pv-devel/2015-
> 11/msg00014.html
> 
> Back then I've raised a concern about code duplication caused by a
> different API than libxc (having libxenvchan in mind). But two years
> latter it looks like it isn't such a problem. libxenchan is the only
> piece being effectively duplicated (at least in Qubes OS), and
> everything else is really different anyway because of Linux/Windows
> differences. So, I think it isn't an issue.
> 
> Also I've renamed XcEvtchnBindUnbound to XcEvtchnOpenUnbound, as
> requested in review back then.
> 
> This has been tested with vs2017/WDK10 build for Windows 7 64bit, both
> on Windows 7 and Windows 10. The patch assume "Add Windows 7 build
> target" patches applied, but it should be easy to apply without them
> too.
> I've updated vs2015 files too, but don't have tools to test them (it
> isn't possible to download free vs2015 anymore).

Marek,

I seem to be having tremendous difficulty in persuading vs2017 to build this. 
No useful error message that I can find... just:

DriverBuildNotifications:
  Building 'xencontrol' with toolset 'WindowsApplicationForDrivers10.0' and the 
'Desktop' target platform.
InitializeBuildStatus:
  Touching "Windows8Debug\xencontrol.tlog\unsuccessfulbuild".
ClCompile:
  C:\Program Files (x86)\Microsoft Visual 
Studio\2017\Community\VC\Tools\MSVC\14.14.26428\bin\HostX86\x86\CL.exe /c 
/IC:\git\xeniface\vs2017\..\include /IWindows8Debug\ /Zi /nologo /Wall /WX 
/diagnostics:classic /MP /Od /Oy- /D CODE_ANALYSIS /D __i386__ /D WIN32 /D 
_WINDOWS /D _USRDLL /D XENCONTROL_EXPORTS /D _X86_=1 /D i386=1 /D STD_CALL /D 
WIN32_LEAN_AND_MEAN=1 /D _WIN32_WINNT=0x0602 /D WINVER=0x0602 /D WINNT=1 /D 
NTDDI_VERSION=0x06020000 /D DBG=1 /D _WINDLL /D _UNICODE /D UNICODE /Gm- /RTC1 
/MTd /GS /fp:precise /Zc:wchar_t- /Zc:forScope /Zc:inline /Fo"Windows8Debug\\" 
/Fd"Windows8Debug\vc141.pdb" /Gz /TC /wd4127 /wd4711 /wd4548 /wd4820 /wd4668 
/wd4255 /wd6001 /wd6054 /wd28196 /FI"C:\Program Files (x86)\Windows 
Kits\10\Include\10.0.17134.0\shared\warning.h" /analyze /analyze:quiet 
/analyze:plugin"C:\Program Files (x86)\Microsoft Visual 
Studio\2017\Community\VC\Tools\MSVC\14.14.26428\bin\HostX86\x86\EspXEngine.dll" 
/analyze:plugin"C:\Program Files (x86)\Microsoft Visual 
Studio\2017\Community\VC\Tools\MSVC\14.14.26428\bin\HostX86\x86\localespc.dll" 
/analyze:plugin"C:\Program Files (x86)\Windows 
Kits\10\bin\10.0.17134.0\x86\WindowsPrefast.dll" /analyze:plugin"C:\Program 
Files (x86)\Windows Kits\10\bin\10.0.17134.0\x86\drivers.dll" /FC 
/errorReport:queue  /analyze:ruleset"C:\Program Files (x86)\Microsoft Visual 
Studio\2017\Community\Team Tools\Static Analysis Tools\Rule 
Sets\NativeRecommendedRules.ruleset" ..\..\src\xencontrol\xencontrol.c
  xencontrol.c
c:\git\xeniface\src\xencontrol\xencontrol.c(924): error C2220: warning treated 
as error - no 'object' file generated 
[C:\git\xeniface\vs2017\xencontrol\xencontrol.vcxproj]
c1 : fatal error C1258: Failed to save XML Log file 
'c:\git\xeniface\vs2017\xencontrol\windows8debug\xencontrol.nativecodeanalysis.xml'.
 The system cannot find the path specified. 
[C:\git\xeniface\vs2017\xencontrol\xencontrol.vcxproj]
Done Building Project "C:\git\xeniface\vs2017\xencontrol\xencontrol.vcxproj" 
(default targets) -- FAILED.
Done Building Project "C:\git\xeniface\vs2017\xeniface.sln" (Build target(s)) 
-- FAILED.

Build FAILED.

I'm not convinced the patch applied correctly as exchange seemed to do its best 
to mangle the line endings and introduce line wrap in stupid places. Do you 
happen to have the code on a git branch I can get to, so I can grab it directly?

Thanks,

  Paul

> ---
>  include/xencontrol.h                         | 342 ++++++++++
>  src/xencontrol/xencontrol.c                  | 919
> +++++++++++++++++++++++++++
>  src/xencontrol/xencontrol.rc                 |  24 +
>  src/xencontrol/xencontrol_private.h          |  49 ++
>  vs2015/package/package.vcxproj               |   3 +
>  vs2015/xencontrol/xencontrol.vcxproj         |  67 ++
>  vs2015/xencontrol/xencontrol.vcxproj.filters |  13 +
>  vs2015/xeniface.sln                          |  38 ++
>  vs2017/package/package.vcxproj               |   3 +
>  vs2017/xencontrol/xencontrol.vcxproj         |  67 ++
>  vs2017/xencontrol/xencontrol.vcxproj.filters |  13 +
>  vs2017/xeniface.sln                          |  38 ++
>  12 files changed, 1576 insertions(+)
>  create mode 100644 include/xencontrol.h
>  create mode 100644 src/xencontrol/xencontrol.c
>  create mode 100644 src/xencontrol/xencontrol.rc
>  create mode 100644 src/xencontrol/xencontrol_private.h
>  create mode 100644 vs2015/xencontrol/xencontrol.vcxproj
>  create mode 100644 vs2015/xencontrol/xencontrol.vcxproj.filters
>  create mode 100644 vs2017/xencontrol/xencontrol.vcxproj
>  create mode 100644 vs2017/xencontrol/xencontrol.vcxproj.filters
> 
> diff --git a/include/xencontrol.h b/include/xencontrol.h
> new file mode 100644
> index 0000000..4560bc6
> --- /dev/null
> +++ b/include/xencontrol.h
> @@ -0,0 +1,342 @@
> +#ifndef _XENCONTROL_H_
> +#define _XENCONTROL_H_
> +
> +#include <windows.h>
> +#include <varargs.h>
> +#include "xeniface_ioctls.h"
> +
> +#ifdef XENCONTROL_EXPORTS
> +#    define XENCONTROL_API __declspec(dllexport)
> +#else
> +#    define XENCONTROL_API __declspec(dllimport)
> +#endif
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +/*! \typedef PXENCONTROL_CONTEXT
> +    \brief Library handle representing a Xen Interface session
> +*/
> +struct _XENCONTROL_CONTEXT;
> +typedef struct _XENCONTROL_CONTEXT *PXENCONTROL_CONTEXT;
> +
> +/*! \typedef XENCONTROL_LOG_LEVEL
> +    \brief Log levels used by the library
> +*/
> +typedef enum
> +_XENCONTROL_LOG_LEVEL {
> +    XLL_ERROR = 1,
> +    XLL_WARNING,
> +    XLL_INFO,
> +    XLL_DEBUG,
> +    XLL_TRACE,
> +} XENCONTROL_LOG_LEVEL;
> +
> +/*! \typedef XENCONTROL_LOGGER
> +    \brief Callback for receiving diagnostic messages from the library
> +*/
> +typedef void
> +XENCONTROL_LOGGER(
> +    IN  XENCONTROL_LOG_LEVEL LogLevel,
> +    IN  const CHAR *Function,
> +    IN  const WCHAR *Message,
> +    IN  va_list Args
> +    );
> +
> +/*! \brief Register a callback for receiving library's diagnostic messages
> +    \param Xc Xencontrol handle returned by XcOpen()
> +    \param Logger Callback to register
> +*/
> +XENCONTROL_API
> +void
> +XcRegisterLogger(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  XENCONTROL_LOGGER *Logger
> +    );
> +
> +/*! \brief Set log level threshold for library's diagnostic messages
> +    \param Xc Xencontrol handle returned by XcOpen()
> +    \param LogLevel Only messages with this level and above will be sent to
> the logger callback
> +*/
> +XENCONTROL_API
> +void
> +XcSetLogLevel(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  XENCONTROL_LOG_LEVEL LogLevel
> +    );
> +
> +/*! \brief Open the Xen Interface device
> +    \param Logger Callback for receiving library's diagnostic messages
> +    \param Xc Xencontrol handle representing a Xen Interface session
> +    \return Error code
> +*/
> +XENCONTROL_API
> +DWORD
> +XcOpen(
> +    IN  XENCONTROL_LOGGER *Logger,
> +    OUT PXENCONTROL_CONTEXT *Xc
> +    );
> +
> +/*! \brief Close the Xen Interface device
> +    \param Xc Xencontrol handle returned by XcOpen()
> +*/
> +XENCONTROL_API
> +void
> +XcClose(
> +    IN  PXENCONTROL_CONTEXT Xc
> +    );
> +
> +/*! \brief Open an unbound event channel
> +    \param Xc Xencontrol handle returned by XcOpen()
> +    \param RemoteDomain ID of a remote domain that will bind the channel
> +    \param Event Handle to an event object that will receive event channel
> notifications
> +    \param Mask Set to TRUE if the event channel should be initially masked
> +    \param LocalPort Port number that is assigned to the event channel
> +    \return Error code
> +*/
> +XENCONTROL_API
> +DWORD
> +XcEvtchnOpenUnbound(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  USHORT RemoteDomain,
> +    IN  HANDLE Event,
> +    IN  BOOL Mask,
> +    OUT ULONG *LocalPort
> +    );
> +
> +/*! \brief Open an event channel that was already bound by a remote
> domain
> +    \param Xc Xencontrol handle returned by XcOpen()
> +    \param RemoteDomain ID of a remote domain that has already bound
> the channel
> +    \param RemotePort Port number that is assigned to the event channel in
> the \a RemoteDomain
> +    \param Event Handle to an event that will receive event channel
> notifications
> +    \param Mask Set to TRUE if the event object channel should be initially
> masked
> +    \param LocalPort Port number that is assigned to the event channel
> +    \return Error code
> +*/
> +XENCONTROL_API
> +DWORD
> +XcEvtchnBindInterdomain(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  USHORT RemoteDomain,
> +    IN  ULONG RemotePort,
> +    IN  HANDLE Event,
> +    IN  BOOL Mask,
> +    OUT ULONG *LocalPort
> +    );
> +
> +/*! \brief Close an event channel
> +    \param Xc Xencontrol handle returned by XcOpen()
> +    \param LocalPort Port number that is assigned to the event channel
> +    \return Error code
> +*/
> +XENCONTROL_API
> +DWORD
> +XcEvtchnClose(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  ULONG LocalPort
> +    );
> +
> +/*! \brief Notify the remote end of an event channel
> +    \param Xc Xencontrol handle returned by XcOpen()
> +    \param LocalPort Port number that is assigned to the event channel
> +    \return Error code
> +*/
> +XENCONTROL_API
> +DWORD
> +XcEvtchnNotify(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  ULONG LocalPort
> +    );
> +
> +/*! \brief Unmask an event channel
> +    \param Xc Xencontrol handle returned by XcOpen()
> +    \param LocalPort Port number that is assigned to the event channel
> +    \return Error code
> +*/
> +XENCONTROL_API
> +DWORD
> +XcEvtchnUnmask(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  ULONG LocalPort
> +    );
> +
> +/*! \brief Grant a \a RemoteDomain permission to access local memory
> pages
> +    \param Xc Xencontrol handle returned by XcOpen()
> +    \param RemoteDomain ID of a remote domain that is being granted
> access
> +    \param NumberPages Number of 4k pages to grant access to
> +    \param NotifyOffset Offset of a byte in the granted region that will be 
> set
> to 0 when the grant is revoked
> +    \param NotifyPort Local port number of an open event channel that will
> be notified when the grant is revoked
> +    \param Flags Grant options
> +    \param Address Local user mode address of the granted memory region
> +    \param References An array of Xen grant numbers for every granted
> page
> +    \return Error code
> +*/
> +XENCONTROL_API
> +DWORD
> +XcGnttabPermitForeignAccess(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  USHORT RemoteDomain,
> +    IN  ULONG NumberPages,
> +    IN  ULONG NotifyOffset,
> +    IN  ULONG NotifyPort,
> +    IN  XENIFACE_GNTTAB_PAGE_FLAGS Flags,
> +    OUT PVOID *Address,
> +    OUT ULONG *References
> +    );
> +
> +/*! \brief Revoke a foreign domain access to previously granted memory
> region
> +    \param Xc Xencontrol handle returned by XcOpen()
> +    \param Address Local user mode address of the granted memory region
> +    \return Error code
> +*/
> +XENCONTROL_API
> +DWORD
> +XcGnttabRevokeForeignAccess(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  PVOID Address
> +    );
> +
> +/*! \brief Map a foreign memory region into the current address space
> +    \param Xc Xencontrol handle returned by XcOpen()
> +    \param RemoteDomain ID of a remote domain that has granted access to
> the pages
> +    \param NumberPages Number of 4k pages to map
> +    \param References An array of Xen grant numbers for every granted
> page
> +    \param NotifyOffset Offset of a byte in the mapped region that will be 
> set
> to 0 when the region is unmapped
> +    \param NotifyPort Local port number of an open event channel that will
> be notified when the region is unmapped
> +    \param Flags Map options
> +    \param Address Local user mode address of the mapped memory region
> +    \return Error code
> +*/
> +XENCONTROL_API
> +DWORD
> +XcGnttabMapForeignPages(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  USHORT RemoteDomain,
> +    IN  ULONG NumberPages,
> +    IN  PULONG References,
> +    IN  ULONG NotifyOffset,
> +    IN  ULONG NotifyPort,
> +    IN  XENIFACE_GNTTAB_PAGE_FLAGS Flags,
> +    OUT PVOID *Address
> +    );
> +
> +/*! \brief Unmap a foreign memory region from the current address space
> +    \param Xc Xencontrol handle returned by XcOpen()
> +    \param Address Local user mode address of the mapped memory region
> +    \return Error code
> +*/
> +XENCONTROL_API
> +DWORD
> +XcGnttabUnmapForeignPages(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  PVOID Address
> +    );
> +
> +/*! \brief Read a XenStore key
> +    \param Xc Xencontrol handle returned by XcOpen()
> +    \param Path Path to the key
> +    \param cbValue Size of the \a Value buffer, in bytes
> +    \param Value Buffer that receives the value
> +    \return Error code
> +*/
> +XENCONTROL_API
> +DWORD
> +XcStoreRead(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  PCHAR Path,
> +    IN  DWORD cbValue,
> +    OUT CHAR *Value
> +    );
> +
> +/*! \brief Write a value to a XenStore key
> +    \param Xc Xencontrol handle returned by XcOpen()
> +    \param Path Path to the key
> +    \param Value Value to write
> +    \return Error code
> +*/
> +XENCONTROL_API
> +DWORD
> +XcStoreWrite(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  PCHAR Path,
> +    IN  PCHAR Value
> +    );
> +
> +/*! \brief Enumerate all immediate child keys of a XenStore key
> +    \param Xc Xencontrol handle returned by XcOpen()
> +    \param Path Path to the key
> +    \param cbOutput Size of the \a Output buffer, in bytes
> +    \param Output Buffer that receives a NUL-separated child key names
> +    \return Error code
> +*/
> +XENCONTROL_API
> +DWORD
> +XcStoreDirectory(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  PCHAR Path,
> +    IN  DWORD cbOutput,
> +    OUT CHAR *Output
> +    );
> +
> +/*! \brief Remove a XenStore key
> +    \param Xc Xencontrol handle returned by XcOpen()
> +    \param Path Path to the key
> +    \return Error code
> +*/
> +XENCONTROL_API
> +DWORD
> +XcStoreRemove(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  PCHAR Path
> +    );
> +
> +/*! \brief Set permissions of a XenStore key
> +    \param Xc Xencontrol handle returned by XcOpen()
> +    \param Path Path to the key
> +    \param Count Number of permissions
> +    \param Permissions Array of permissions to set
> +    \return Error code
> +*/
> +XENCONTROL_API
> +DWORD
> +XcStoreSetPermissions(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  PCHAR Path,
> +    IN  ULONG Count,
> +    IN  PXENIFACE_STORE_PERMISSION Permissions
> +    );
> +
> +/*! \brief Add a XenStore key watch
> +    \param Xc Xencontrol handle returned by XcOpen()
> +    \param Path Path to the key to be watched
> +    \param Event Handle to an event that will be signaled when the watch
> fires
> +    \param Handle An opaque value representing the watch
> +    \return Error code
> +*/
> +XENCONTROL_API
> +DWORD
> +XcStoreAddWatch(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  PCHAR Path,
> +    IN  HANDLE Event,
> +    OUT PVOID *Handle
> +    );
> +
> +/*! \brief Remove a XenStore watch
> +    \param Xc Xencontrol handle returned by XcOpen()
> +    \param Handle Watch handle returned by XcStoreAddWatch()
> +    \return Error code
> +*/
> +XENCONTROL_API
> +DWORD
> +XcStoreRemoveWatch(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  PVOID Handle
> +    );
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif // _XENCONTROL_H_
> diff --git a/src/xencontrol/xencontrol.c b/src/xencontrol/xencontrol.c
> new file mode 100644
> index 0000000..f55d0a2
> --- /dev/null
> +++ b/src/xencontrol/xencontrol.c
> @@ -0,0 +1,919 @@
> +#define INITGUID
> +#include <windows.h>
> +#include <winioctl.h>
> +#include <setupapi.h>
> +#include <stdlib.h>
> +#include <assert.h>
> +
> +#include "xencontrol.h"
> +#include "xencontrol_private.h"
> +
> +BOOL APIENTRY
> +DllMain(
> +    IN  HMODULE Module,
> +    IN  DWORD ReasonForCall,
> +    IN  LPVOID Reserved
> +)
> +{
> +    UNREFERENCED_PARAMETER(Module);
> +    UNREFERENCED_PARAMETER(ReasonForCall);
> +    UNREFERENCED_PARAMETER(Reserved);
> +    return TRUE;
> +}
> +
> +static void
> +_Log(
> +    IN  XENCONTROL_LOGGER *Logger,
> +    IN  XENCONTROL_LOG_LEVEL LogLevel,
> +    IN  XENCONTROL_LOG_LEVEL CurrentLogLevel,
> +    IN  PCHAR Function,
> +    IN  PWCHAR Format,
> +    ...
> +    )
> +{
> +    va_list Args;
> +    DWORD LastError;
> +
> +    if (Logger == NULL)
> +        return;
> +
> +    if (LogLevel > CurrentLogLevel)
> +        return;
> +
> +    LastError = GetLastError();
> +    va_start(Args, Format);
> +    Logger(LogLevel, Function, Format, Args);
> +    va_end(Args);
> +    SetLastError(LastError);
> +}
> +
> +static void
> +_LogMultiSz(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  PCHAR Caller,
> +    IN  XENCONTROL_LOG_LEVEL Level,
> +    IN  PCHAR MultiSz
> +    )
> +{
> +    PCHAR Ptr;
> +    ULONG Len;
> +
> +    for (Ptr = MultiSz; *Ptr;) {
> +        Len = (ULONG)strlen(Ptr);
> +        _Log(Xc->Logger, Level, Xc->LogLevel, Caller, L"%S", Ptr);
> +        Ptr += ((ptrdiff_t)Len + 1);
> +    }
> +}
> +
> +void
> +XcRegisterLogger(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  XENCONTROL_LOGGER *Logger
> +    )
> +{
> +    Xc->Logger = Logger;
> +}
> +
> +void
> +XcSetLogLevel(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  XENCONTROL_LOG_LEVEL LogLevel
> +    )
> +{
> +    Xc->LogLevel = LogLevel;
> +}
> +
> +DWORD
> +XcOpen(
> +    IN  XENCONTROL_LOGGER *Logger,
> +    OUT PXENCONTROL_CONTEXT *Xc
> +    )
> +{
> +    HDEVINFO DevInfo;
> +    SP_DEVICE_INTERFACE_DATA InterfaceData;
> +    SP_DEVICE_INTERFACE_DETAIL_DATA *DetailData = NULL;
> +    DWORD BufferSize;
> +    PXENCONTROL_CONTEXT Context;
> +
> +    Context = malloc(sizeof(*Context));
> +    if (Context == NULL)
> +        return ERROR_NOT_ENOUGH_MEMORY;
> +
> +    Context->Logger = Logger;
> +    Context->LogLevel = XLL_INFO;
> +    Context->RequestId = 1;
> +    InitializeListHead(&Context->RequestList);
> +    InitializeCriticalSection(&Context->RequestListLock);
> +
> +    DevInfo = SetupDiGetClassDevs(&GUID_INTERFACE_XENIFACE, 0, NULL,
> DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
> +    if (DevInfo == INVALID_HANDLE_VALUE) {
> +        _Log(Logger, XLL_ERROR, Context->LogLevel, __FUNCTION__,
> +             L"XENIFACE device class doesn't exist");
> +        goto fail;
> +    }
> +
> +    InterfaceData.cbSize = sizeof(InterfaceData);
> +    if (!SetupDiEnumDeviceInterfaces(DevInfo, NULL,
> &GUID_INTERFACE_XENIFACE, 0, &InterfaceData)) {
> +        _Log(Logger, XLL_ERROR, Context->LogLevel, __FUNCTION__,
> +             L"Failed to enumerate XENIFACE devices");
> +        goto fail;
> +    }
> +
> +    SetupDiGetDeviceInterfaceDetail(DevInfo, &InterfaceData, NULL, 0,
> &BufferSize, NULL);
> +    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
> +        _Log(Logger, XLL_ERROR, Context->LogLevel, __FUNCTION__,
> +             L"Failed to get buffer size for device details");
> +        goto fail;
> +    }
> +
> +    // Using 'BufferSize' from failed function call
> +#pragma warning(suppress: 6102)
> +    DetailData = (SP_DEVICE_INTERFACE_DETAIL_DATA *)malloc(BufferSize);
> +    if (!DetailData) {
> +        SetLastError(ERROR_OUTOFMEMORY);
> +        goto fail;
> +    }
> +
> +    DetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
> +
> +    if (!SetupDiGetDeviceInterfaceDetail(DevInfo, &InterfaceData,
> DetailData, BufferSize, NULL, NULL)) {
> +        _Log(Logger, XLL_ERROR, Context->LogLevel, __FUNCTION__,
> +             L"Failed to get XENIFACE device path");
> +        goto fail;
> +    }
> +
> +    Context->XenIface = CreateFile(DetailData->DevicePath,
> +                                   FILE_GENERIC_READ | FILE_GENERIC_WRITE,
> +                                   0,
> +                                   NULL,
> +                                   OPEN_EXISTING,
> +                                   FILE_ATTRIBUTE_NORMAL | 
> FILE_FLAG_OVERLAPPED,
> +                                   NULL);
> +
> +    if (Context->XenIface == INVALID_HANDLE_VALUE) {
> +        _Log(Logger, XLL_ERROR, Context->LogLevel, __FUNCTION__,
> +             L"Failed to open XENIFACE device, path: %s", DetailData-
> >DevicePath);
> +        goto fail;
> +    }
> +
> +    _Log(Logger, XLL_ERROR, Context->LogLevel, __FUNCTION__,
> +         L"XenIface handle: %p", Context->XenIface);
> +
> +    free(DetailData);
> +    *Xc = Context;
> +    return ERROR_SUCCESS;
> +
> +fail:
> +    _Log(Logger, XLL_ERROR, Context->LogLevel, __FUNCTION__,
> +         L"Error: 0x%x", GetLastError());
> +
> +    free(DetailData);
> +    return GetLastError();
> +}
> +
> +void
> +XcClose(
> +    IN  PXENCONTROL_CONTEXT Xc
> +    )
> +{
> +    CloseHandle(Xc->XenIface);
> +    DeleteCriticalSection(&Xc->RequestListLock);
> +    free(Xc);
> +}
> +
> +DWORD
> +XcEvtchnOpenUnbound(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  USHORT RemoteDomain,
> +    IN  HANDLE Event,
> +    IN  BOOL Mask,
> +    OUT ULONG *LocalPort
> +    )
> +{
> +    XENIFACE_EVTCHN_BIND_UNBOUND_IN In;
> +    XENIFACE_EVTCHN_BIND_UNBOUND_OUT Out;
> +    DWORD Returned;
> +    BOOL Success;
> +
> +    In.RemoteDomain = RemoteDomain;
> +    In.Event = Event;
> +    In.Mask = !!Mask;
> +
> +    Log(XLL_DEBUG, L"RemoteDomain: %d, Event: %p, Mask: %d",
> RemoteDomain, Event, Mask);
> +    Success = DeviceIoControl(Xc->XenIface,
> +                              IOCTL_XENIFACE_EVTCHN_BIND_UNBOUND,
> +                              &In, sizeof(In),
> +                              &Out, sizeof(Out),
> +                              &Returned,
> +                              NULL);
> +
> +    if (!Success) {
> +        Log(XLL_ERROR, L"IOCTL_XENIFACE_EVTCHN_BIND_UNBOUND_PORT
> failed");
> +        goto fail;
> +    }
> +
> +    *LocalPort = Out.LocalPort;
> +    Log(XLL_DEBUG, L"LocalPort: %lu", *LocalPort);
> +
> +    return ERROR_SUCCESS;
> +
> +fail:
> +    Log(XLL_ERROR, L"Error: 0x%x", GetLastError());
> +    return GetLastError();
> +}
> +
> +DWORD
> +XcEvtchnBindInterdomain(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  USHORT RemoteDomain,
> +    IN  ULONG RemotePort,
> +    IN  HANDLE Event,
> +    IN  BOOL Mask,
> +    OUT ULONG *LocalPort
> +    )
> +{
> +    XENIFACE_EVTCHN_BIND_INTERDOMAIN_IN In;
> +    XENIFACE_EVTCHN_BIND_INTERDOMAIN_OUT Out;
> +    DWORD Returned;
> +    BOOL Success;
> +
> +    In.RemoteDomain = RemoteDomain;
> +    In.RemotePort = RemotePort;
> +    In.Event = Event;
> +    In.Mask = !!Mask;
> +
> +    Log(XLL_DEBUG, L"RemoteDomain: %d, RemotePort %lu, Event: %p,
> Mask: %d",
> +        RemoteDomain, RemotePort, Event, Mask);
> +    Success = DeviceIoControl(Xc->XenIface,
> +                              IOCTL_XENIFACE_EVTCHN_BIND_INTERDOMAIN,
> +                              &In, sizeof(In),
> +                              &Out, sizeof(Out),
> +                              &Returned,
> +                              NULL);
> +
> +    if (!Success) {
> +        Log(XLL_ERROR, L"IOCTL_XENIFACE_EVTCHN_BIND_INTERDOMAIN
> failed");
> +        goto fail;
> +    }
> +
> +    *LocalPort = Out.LocalPort;
> +    Log(XLL_DEBUG, L"LocalPort: %lu", *LocalPort);
> +
> +    return ERROR_SUCCESS;
> +
> +fail:
> +    Log(XLL_ERROR, L"Error: 0x%x", GetLastError());
> +    return GetLastError();
> +}
> +
> +DWORD
> +XcEvtchnClose(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  ULONG LocalPort
> +    )
> +{
> +    XENIFACE_EVTCHN_CLOSE_IN In;
> +    DWORD Returned;
> +    BOOL Success;
> +
> +    In.LocalPort = LocalPort;
> +
> +    Log(XLL_DEBUG, L"LocalPort: %lu", LocalPort);
> +    Success = DeviceIoControl(Xc->XenIface,
> +                              IOCTL_XENIFACE_EVTCHN_CLOSE,
> +                              &In, sizeof(In),
> +                              NULL, 0,
> +                              &Returned,
> +                              NULL);
> +
> +    if (!Success) {
> +        Log(XLL_ERROR, L"IOCTL_XENIFACE_EVTCHN_CLOSE failed");
> +        goto fail;
> +    }
> +
> +    return ERROR_SUCCESS;
> +
> +fail:
> +    Log(XLL_ERROR, L"Error: 0x%x", GetLastError());
> +    return GetLastError();
> +}
> +
> +DWORD
> +XcEvtchnNotify(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  ULONG LocalPort
> +    )
> +{
> +    XENIFACE_EVTCHN_NOTIFY_IN In;
> +    DWORD Returned;
> +    BOOL Success;
> +
> +    In.LocalPort = LocalPort;
> +
> +    Log(XLL_DEBUG, L"LocalPort: %lu", LocalPort);
> +    Success = DeviceIoControl(Xc->XenIface,
> +                              IOCTL_XENIFACE_EVTCHN_NOTIFY,
> +                              &In, sizeof(In),
> +                              NULL, 0,
> +                              &Returned,
> +                              NULL);
> +
> +    if (!Success) {
> +        Log(XLL_ERROR, L"IOCTL_XENIFACE_EVTCHN_NOTIFY failed");
> +        goto fail;
> +    }
> +
> +    return ERROR_SUCCESS;
> +
> +fail:
> +    Log(XLL_ERROR, L"Error: 0x%x", GetLastError());
> +    return GetLastError();
> +}
> +
> +DWORD
> +XcEvtchnUnmask(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  ULONG LocalPort
> +    )
> +{
> +    XENIFACE_EVTCHN_UNMASK_IN In;
> +    DWORD Returned;
> +    BOOL Success;
> +
> +    In.LocalPort = LocalPort;
> +
> +    Log(XLL_DEBUG, L"LocalPort: %lu", LocalPort);
> +    Success = DeviceIoControl(Xc->XenIface,
> +                              IOCTL_XENIFACE_EVTCHN_UNMASK,
> +                              &In, sizeof(In),
> +                              NULL, 0,
> +                              &Returned,
> +                              NULL);
> +
> +    if (!Success) {
> +        Log(XLL_ERROR, L"IOCTL_XENIFACE_EVTCHN_UNMASK failed");
> +        goto fail;
> +    }
> +
> +    return ERROR_SUCCESS;
> +
> +fail:
> +    Log(XLL_ERROR, L"Error: 0x%x", GetLastError());
> +    return GetLastError();
> +}
> +
> +static PXENCONTROL_GNTTAB_REQUEST
> +FindRequest(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  PVOID Address
> +    )
> +{
> +    PLIST_ENTRY Entry;
> +    PXENCONTROL_GNTTAB_REQUEST ReturnRequest = NULL;
> +
> +    EnterCriticalSection(&Xc->RequestListLock);
> +    Entry = Xc->RequestList.Flink;
> +    while (Entry != &Xc->RequestList) {
> +        PXENCONTROL_GNTTAB_REQUEST Request =
> CONTAINING_RECORD(Entry, XENCONTROL_GNTTAB_REQUEST, ListEntry);
> +
> +        if (Request->Address == Address) {
> +            ReturnRequest = Request;
> +            break;
> +        }
> +
> +        Entry = Entry->Flink;
> +    }
> +    LeaveCriticalSection(&Xc->RequestListLock);
> +
> +    return ReturnRequest;
> +}
> +
> +DWORD
> +XcGnttabPermitForeignAccess(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  USHORT RemoteDomain,
> +    IN  ULONG NumberPages,
> +    IN  ULONG NotifyOffset,
> +    IN  ULONG NotifyPort,
> +    IN  XENIFACE_GNTTAB_PAGE_FLAGS Flags,
> +    OUT PVOID *Address,
> +    OUT ULONG *References
> +    )
> +{
> +    XENIFACE_GNTTAB_PERMIT_FOREIGN_ACCESS_IN In;
> +    XENIFACE_GNTTAB_PERMIT_FOREIGN_ACCESS_OUT *Out;
> +    PXENCONTROL_GNTTAB_REQUEST Request;
> +    DWORD Returned, Size;
> +    BOOL Success;
> +    DWORD Status;
> +
> +    // lock the whole operation to not generate duplicate IDs
> +    EnterCriticalSection(&Xc->RequestListLock);
> +
> +    In.RequestId = Xc->RequestId;
> +    In.RemoteDomain = RemoteDomain;
> +    In.NumberPages = NumberPages;
> +    In.NotifyOffset = NotifyOffset;
> +    In.NotifyPort = NotifyPort;
> +    In.Flags = Flags;
> +
> +    Size =
> (ULONG)FIELD_OFFSET(XENIFACE_GNTTAB_PERMIT_FOREIGN_ACCESS_OU
> T, References[NumberPages]);
> +    Out = malloc(Size);
> +    Request = malloc(sizeof(*Request));
> +
> +    Status = ERROR_OUTOFMEMORY;
> +    if (!Request || !Out)
> +        goto fail;
> +
> +    ZeroMemory(Request, sizeof(*Request));
> +    Request->Id = In.RequestId;
> +
> +    Log(XLL_DEBUG, L"Id %lu, RemoteDomain: %d, NumberPages: %lu,
> NotifyOffset: 0x%x, NotifyPort: %lu, Flags: 0x%x",
> +        In.RequestId, RemoteDomain, NumberPages, NotifyOffset, NotifyPort,
> Flags);
> +
> +    Success = DeviceIoControl(Xc->XenIface,
> +                              IOCTL_XENIFACE_GNTTAB_PERMIT_FOREIGN_ACCESS,
> +                              &In, sizeof(In),
> +                              Out, Size,
> +                              &Returned,
> +                              &Request->Overlapped);
> +
> +    Status = GetLastError();
> +    // this IOCTL is expected to be pending on success
> +    if (!Success) {
> +        if (Status != ERROR_IO_PENDING) {
> +            Log(XLL_ERROR, L"IOCTL_XENIFACE_GNTTAB_GRANT_PAGES
> failed");
> +            goto fail;
> +        }
> +    } else {
> +        Log(XLL_ERROR, L"IOCTL_XENIFACE_GNTTAB_GRANT_PAGES not
> pending");
> +        Status = ERROR_UNIDENTIFIED_ERROR;
> +        goto fail;
> +    }
> +
> +    Request->Address = Out->Address;
> +
> +    InsertTailList(&Xc->RequestList, &Request->ListEntry);
> +    Xc->RequestId++;
> +    LeaveCriticalSection(&Xc->RequestListLock);
> +
> +    *Address = Out->Address;
> +    memcpy(References, &Out->References, NumberPages *
> sizeof(ULONG));
> +    Log(XLL_DEBUG, L"Address: %p", *Address);
> +    for (ULONG i = 0; i < NumberPages; i++)
> +        Log(XLL_DEBUG, L"Grant ref[%lu]: %lu", i, Out->References[i]);
> +
> +    free(Out);
> +    return ERROR_SUCCESS;
> +
> +fail:
> +    LeaveCriticalSection(&Xc->RequestListLock);
> +    Log(XLL_ERROR, L"Error: 0x%x", Status);
> +    free(Out);
> +    free(Request);
> +    return Status;
> +}
> +
> +DWORD
> +XcGnttabRevokeForeignAccess(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  PVOID Address
> +    )
> +{
> +    XENIFACE_GNTTAB_REVOKE_FOREIGN_ACCESS_IN In;
> +    PXENCONTROL_GNTTAB_REQUEST Request;
> +    DWORD Returned;
> +    BOOL Success;
> +    DWORD Status;
> +
> +    Log(XLL_DEBUG, L"Address: %p", Address);
> +
> +    Status = ERROR_NOT_FOUND;
> +    Request = FindRequest(Xc, Address);
> +    if (!Request) {
> +        Log(XLL_ERROR, L"Address %p not granted", Address);
> +        goto fail;
> +    }
> +
> +    In.RequestId = Request->Id;
> +
> +    Success = DeviceIoControl(Xc->XenIface,
> +                              IOCTL_XENIFACE_GNTTAB_REVOKE_FOREIGN_ACCESS,
> +                              &In, sizeof(In),
> +                              NULL, 0,
> +                              &Returned,
> +                              NULL);
> +
> +    Status = GetLastError();
> +    if (!Success) {
> +        Log(XLL_ERROR, L"IOCTL_XENIFACE_GNTTAB_UNGRANT_PAGES
> failed");
> +        goto fail;
> +    }
> +
> +    EnterCriticalSection(&Xc->RequestListLock);
> +    RemoveEntryList(&Request->ListEntry);
> +    LeaveCriticalSection(&Xc->RequestListLock);
> +    free(Request);
> +
> +    return Status;
> +
> +fail:
> +    Log(XLL_ERROR, L"Error: %d 0x%x", Status, Status);
> +    return Status;
> +}
> +
> +DWORD
> +XcGnttabMapForeignPages(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  USHORT RemoteDomain,
> +    IN  ULONG NumberPages,
> +    IN  PULONG References,
> +    IN  ULONG NotifyOffset,
> +    IN  ULONG NotifyPort,
> +    IN  XENIFACE_GNTTAB_PAGE_FLAGS Flags,
> +    OUT PVOID *Address
> +    )
> +{
> +    XENIFACE_GNTTAB_MAP_FOREIGN_PAGES_IN *In;
> +    XENIFACE_GNTTAB_MAP_FOREIGN_PAGES_OUT Out;
> +    PXENCONTROL_GNTTAB_REQUEST Request;
> +    DWORD Returned, Size;
> +    BOOL Success;
> +    DWORD Status;
> +
> +    // lock the whole operation to not generate duplicate IDs
> +    EnterCriticalSection(&Xc->RequestListLock);
> +
> +    Status = ERROR_OUTOFMEMORY;
> +    Size =
> (ULONG)FIELD_OFFSET(XENIFACE_GNTTAB_MAP_FOREIGN_PAGES_IN,
> References[NumberPages]);
> +    In = malloc(Size);
> +    Request = malloc(sizeof(*Request));
> +    if (!In || !Request)
> +        goto fail;
> +
> +    In->RequestId = Xc->RequestId;
> +    In->RemoteDomain = RemoteDomain;
> +    In->NumberPages = NumberPages;
> +    In->NotifyOffset = NotifyOffset;
> +    In->NotifyPort = NotifyPort;
> +    In->Flags = Flags;
> +    memcpy(&In->References, References, NumberPages * sizeof(ULONG));
> +
> +    ZeroMemory(Request, sizeof(*Request));
> +    Request->Id = In->RequestId;
> +
> +    Log(XLL_DEBUG, L"Id %lu, RemoteDomain: %d, NumberPages: %lu,
> NotifyOffset: 0x%x, NotifyPort: %lu, Flags: 0x%x",
> +        In->RequestId, RemoteDomain, NumberPages, NotifyOffset,
> NotifyPort, Flags);
> +
> +    for (ULONG i = 0; i < NumberPages; i++)
> +        Log(XLL_DEBUG, L"Grant ref[%lu]: %lu", i, References[i]);
> +
> +    Success = DeviceIoControl(Xc->XenIface,
> +                              IOCTL_XENIFACE_GNTTAB_MAP_FOREIGN_PAGES,
> +                              In, Size,
> +                              &Out, sizeof(Out),
> +                              &Returned,
> +                              &Request->Overlapped);
> +
> +    Status = GetLastError();
> +    // this IOCTL is expected to be pending on success
> +    if (!Success) {
> +        if (Status != ERROR_IO_PENDING) {
> +            Log(XLL_ERROR,
> L"IOCTL_XENIFACE_GNTTAB_MAP_FOREIGN_PAGES failed");
> +            goto fail;
> +        }
> +    } else {
> +        Log(XLL_ERROR, L"IOCTL_XENIFACE_GNTTAB_MAP_FOREIGN_PAGES
> not pending");
> +        Status = ERROR_UNIDENTIFIED_ERROR;
> +        goto fail;
> +    }
> +
> +    Request->Address = Out.Address;
> +    InsertTailList(&Xc->RequestList, &Request->ListEntry);
> +    Xc->RequestId++;
> +    LeaveCriticalSection(&Xc->RequestListLock);
> +
> +    *Address = Out.Address;
> +
> +    Log(XLL_DEBUG, L"Address: %p", *Address);
> +
> +    free(In);
> +    return ERROR_SUCCESS;
> +
> +fail:
> +    LeaveCriticalSection(&Xc->RequestListLock);
> +    Log(XLL_ERROR, L"Error: 0x%x", Status);
> +    free(In);
> +    free(Request);
> +    return Status;
> +}
> +
> +DWORD
> +XcGnttabUnmapForeignPages(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  PVOID Address
> +    )
> +{
> +    XENIFACE_GNTTAB_UNMAP_FOREIGN_PAGES_IN In;
> +    PXENCONTROL_GNTTAB_REQUEST Request;
> +    DWORD Returned;
> +    BOOL Success;
> +    DWORD Status;
> +
> +    Log(XLL_DEBUG, L"Address: %p", Address);
> +
> +    Status = ERROR_NOT_FOUND;
> +    Request = FindRequest(Xc, Address);
> +    if (!Request) {
> +        Log(XLL_ERROR, L"Address %p not mapped", Address);
> +        goto fail;
> +    }
> +
> +    In.RequestId = Request->Id;
> +
> +    Success = DeviceIoControl(Xc->XenIface,
> +                              IOCTL_XENIFACE_GNTTAB_UNMAP_FOREIGN_PAGES,
> +                              &In, sizeof(In),
> +                              NULL, 0,
> +                              &Returned,
> +                              NULL);
> +
> +    Status = GetLastError();
> +    if (!Success) {
> +        Log(XLL_ERROR,
> L"IOCTL_XENIFACE_GNTTAB_UNMAP_FOREIGN_PAGES failed");
> +        goto fail;
> +    }
> +
> +    EnterCriticalSection(&Xc->RequestListLock);
> +    RemoveEntryList(&Request->ListEntry);
> +    LeaveCriticalSection(&Xc->RequestListLock);
> +    free(Request);
> +
> +    return Status;
> +
> +fail:
> +    Log(XLL_ERROR, L"Error: 0x%x", Status);
> +    return Status;
> +}
> +
> +DWORD
> +XcStoreRead(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  PSTR Path,
> +    IN  DWORD cbValue,
> +    OUT CHAR *Value
> +    )
> +{
> +    DWORD Returned;
> +    BOOL Success;
> +
> +    Log(XLL_DEBUG, L"Path: '%S'", Path);
> +    Success = DeviceIoControl(Xc->XenIface,
> +                              IOCTL_XENIFACE_STORE_READ,
> +                              Path, (DWORD)strlen(Path) + 1,
> +                              Value, cbValue,
> +                              &Returned,
> +                              NULL);
> +
> +    if (!Success) {
> +        Log(XLL_ERROR, L"IOCTL_XENIFACE_STORE_READ failed");
> +        goto fail;
> +    }
> +
> +    Log(XLL_DEBUG, L"Value: '%S'", Value);
> +
> +    return ERROR_SUCCESS;
> +
> +fail:
> +    Log(XLL_ERROR, L"Error: 0x%x", GetLastError());
> +    return GetLastError();
> +}
> +
> +DWORD
> +XcStoreWrite(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  PCHAR Path,
> +    IN  PCHAR Value
> +    )
> +{
> +    PCHAR Buffer;
> +    DWORD cbBuffer;
> +    DWORD Returned;
> +    BOOL Success;
> +
> +    cbBuffer = (DWORD)(strlen(Path) + 1 + strlen(Value) + 1 + 1);
> +    Buffer = malloc(cbBuffer);
> +    if (!Buffer) {
> +        SetLastError(ERROR_OUTOFMEMORY);
> +        goto fail;
> +    }
> +
> +    ZeroMemory(Buffer, cbBuffer);
> +    memcpy(Buffer, Path, strlen(Path));
> +    memcpy(Buffer + strlen(Path) + 1, Value, strlen(Value));
> +
> +    Log(XLL_DEBUG, L"Path: '%S', Value: '%S'", Path, Value);
> +    Success = DeviceIoControl(Xc->XenIface,
> +                              IOCTL_XENIFACE_STORE_WRITE,
> +                              Buffer, cbBuffer,
> +                              NULL, 0,
> +                              &Returned,
> +                              NULL);
> +
> +    if (!Success) {
> +        Log(XLL_ERROR, L"IOCTL_XENIFACE_STORE_WRITE failed");
> +        goto fail;
> +    }
> +
> +    free(Buffer);
> +    return ERROR_SUCCESS;
> +
> +fail:
> +    Log(XLL_ERROR, L"Error: 0x%x", GetLastError());
> +    free(Buffer);
> +    return GetLastError();
> +}
> +
> +DWORD
> +XcStoreDirectory(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  PCHAR Path,
> +    IN  DWORD cbOutput,
> +    OUT CHAR *Output
> +    )
> +{
> +    DWORD Returned;
> +    BOOL Success;
> +
> +    Log(XLL_DEBUG, L"Path: '%S'", Path);
> +    Success = DeviceIoControl(Xc->XenIface,
> +                              IOCTL_XENIFACE_STORE_DIRECTORY,
> +                              Path, (DWORD)strlen(Path) + 1,
> +                              Output, cbOutput,
> +                              &Returned,
> +                              NULL);
> +
> +    if (!Success) {
> +        Log(XLL_ERROR, L"IOCTL_XENIFACE_STORE_DIRECTORY failed");
> +        goto fail;
> +    }
> +
> +    _LogMultiSz(Xc, __FUNCTION__, XLL_DEBUG, Output);
> +
> +    return ERROR_SUCCESS;
> +
> +fail:
> +    Log(XLL_ERROR, L"Error: 0x%x", GetLastError());
> +    return GetLastError();
> +}
> +
> +DWORD
> +XcStoreRemove(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  PCHAR Path
> +    )
> +{
> +    DWORD Returned;
> +    BOOL Success;
> +
> +    Log(XLL_DEBUG, L"Path: '%S'", Path);
> +    Success = DeviceIoControl(Xc->XenIface,
> +                              IOCTL_XENIFACE_STORE_REMOVE,
> +                              Path, (DWORD)strlen(Path) + 1,
> +                              NULL, 0,
> +                              &Returned,
> +                              NULL);
> +
> +    if (!Success) {
> +        Log(XLL_ERROR, L"IOCTL_XENIFACE_STORE_REMOVE failed");
> +        goto fail;
> +    }
> +
> +    return ERROR_SUCCESS;
> +
> +fail:
> +    Log(XLL_ERROR, L"Error: 0x%x", GetLastError());
> +    return GetLastError();
> +}
> +
> +DWORD
> +XcStoreSetPermissions(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  PCHAR Path,
> +    IN  ULONG Count,
> +    IN  PXENIFACE_STORE_PERMISSION Permissions
> +    )
> +{
> +    DWORD Returned, Size;
> +    BOOL Success;
> +    XENIFACE_STORE_SET_PERMISSIONS_IN *In = NULL;
> +
> +    Log(XLL_DEBUG, L"Path: '%S', Count: %lu", Path, Count);
> +    for (ULONG i = 0; i < Count; i++)
> +        Log(XLL_DEBUG, L"Domain: %d, Mask: 0x%x", Permissions[i].Domain,
> Permissions[i].Mask);
> +
> +    Size = (ULONG)FIELD_OFFSET(XENIFACE_STORE_SET_PERMISSIONS_IN,
> Permissions[Count]);
> +    In = malloc(Size);
> +    if (!In) {
> +        SetLastError(ERROR_OUTOFMEMORY);
> +        goto fail;
> +    }
> +
> +    In->Path = Path;
> +    In->PathLength = (DWORD)strlen(In->Path) + 1;
> +    In->NumberPermissions = Count;
> +    memcpy(&In->Permissions, Permissions, Count *
> sizeof(XENIFACE_STORE_PERMISSION));
> +
> +    Success = DeviceIoControl(Xc->XenIface,
> +                              IOCTL_XENIFACE_STORE_SET_PERMISSIONS,
> +                              In, Size,
> +                              NULL, 0,
> +                              &Returned,
> +                              NULL);
> +
> +    if (!Success) {
> +        Log(XLL_ERROR, L"IOCTL_XENIFACE_STORE_SET_PERMISSIONS failed");
> +        goto fail;
> +    }
> +
> +    free(In);
> +    return ERROR_SUCCESS;
> +
> +fail:
> +    Log(XLL_ERROR, L"Error: 0x%x", GetLastError());
> +    free(In);
> +    return GetLastError();
> +}
> +
> +DWORD
> +XcStoreAddWatch(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  PCHAR Path,
> +    IN  HANDLE Event,
> +    OUT PVOID *Handle
> +    )
> +{
> +    DWORD Returned;
> +    BOOL Success;
> +    XENIFACE_STORE_ADD_WATCH_IN In;
> +    XENIFACE_STORE_ADD_WATCH_OUT Out;
> +
> +    Log(XLL_DEBUG, L"Path: '%S', Event: %p", Path, Event);
> +
> +    In.Path = Path;
> +    In.PathLength = (DWORD)strlen(Path) + 1;
> +    In.Event = Event;
> +    Success = DeviceIoControl(Xc->XenIface,
> +                              IOCTL_XENIFACE_STORE_ADD_WATCH,
> +                              &In, sizeof(In),
> +                              &Out, sizeof(Out),
> +                              &Returned,
> +                              NULL);
> +
> +    if (!Success) {
> +        Log(XLL_ERROR, L"IOCTL_XENIFACE_STORE_ADD_WATCH failed");
> +        goto fail;
> +    }
> +
> +    *Handle = Out.Context;
> +
> +    Log(XLL_DEBUG, L"Handle: %p", *Handle);
> +
> +    return ERROR_SUCCESS;
> +
> +fail:
> +    Log(XLL_ERROR, L"Error: 0x%x", GetLastError());
> +    return GetLastError();
> +}
> +
> +DWORD
> +XcStoreRemoveWatch(
> +    IN  PXENCONTROL_CONTEXT Xc,
> +    IN  PVOID Handle
> +    )
> +{
> +    DWORD Returned;
> +    BOOL Success;
> +    XENIFACE_STORE_REMOVE_WATCH_IN In;
> +
> +    Log(XLL_DEBUG, L"Handle: %p", Handle);
> +
> +    In.Context = Handle;
> +    Success = DeviceIoControl(Xc->XenIface,
> +                              IOCTL_XENIFACE_STORE_REMOVE_WATCH,
> +                              &In, sizeof(In),
> +                              NULL, 0,
> +                              &Returned,
> +                              NULL);
> +
> +    if (!Success) {
> +        Log(XLL_ERROR, L"IOCTL_XENIFACE_STORE_REMOVE_WATCH failed");
> +        goto fail;
> +    }
> +
> +    return ERROR_SUCCESS;
> +
> +fail:
> +    Log(XLL_ERROR, L"Error: 0x%x", GetLastError());
> +    return GetLastError();
> +}
> diff --git a/src/xencontrol/xencontrol.rc b/src/xencontrol/xencontrol.rc
> new file mode 100644
> index 0000000..6c33e84
> --- /dev/null
> +++ b/src/xencontrol/xencontrol.rc
> @@ -0,0 +1,24 @@
> +#include <windows.h>
> +#include <ntverp.h>
> +
> +#undef VER_COMPANYNAME_STR
> +#undef VER_PRODUCTNAME_STR
> +#undef VER_PRODUCTVERSION
> +#undef VER_PRODUCTVERSION_STR
> +
> +#include <version.h>
> +
> +#define VER_COMPANYNAME_STR         VENDOR_NAME_STR
> +#define VER_LEGALCOPYRIGHT_STR      "Copyright (c) Invisible Things Lab"
> +
> +#define VER_PRODUCTNAME_STR         "XENIFACE"
> +#define VER_PRODUCTVERSION
> MAJOR_VERSION,MINOR_VERSION,MICRO_VERSION,BUILD_NUMBER
> +#define VER_PRODUCTVERSION_STR      MAJOR_VERSION_STR "."
> MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR
> +
> +#define VER_INTERNALNAME_STR        "XENCONTROL.DLL"
> +#define VER_FILEDESCRIPTION_STR     "Xen interface user library"
> +
> +#define VER_FILETYPE                VFT_DLL
> +#define VER_FILESUBTYPE             0
> +
> +#include <common.ver>
> diff --git a/src/xencontrol/xencontrol_private.h
> b/src/xencontrol/xencontrol_private.h
> new file mode 100644
> index 0000000..685bcfa
> --- /dev/null
> +++ b/src/xencontrol/xencontrol_private.h
> @@ -0,0 +1,49 @@
> +#ifndef _XENCONTROL_PRIVATE_H_
> +#define _XENCONTROL_PRIVATE_H_
> +
> +#include <windows.h>
> +#include "xencontrol.h"
> +
> +#define Log(level, format, ...) \
> +        _Log(Xc->Logger, level, Xc->LogLevel, __FUNCTION__, format,
> __VA_ARGS__)
> +
> +#define InitializeListHead(ListHead) ( \
> +    (ListHead)->Flink = (ListHead)->Blink = (ListHead))
> +
> +#define InsertTailList(ListHead, Entry) { \
> +    PLIST_ENTRY _EX_Blink; \
> +    PLIST_ENTRY _EX_ListHead; \
> +    _EX_ListHead = (ListHead); \
> +    _EX_Blink = _EX_ListHead->Blink; \
> +    (Entry)->Flink = _EX_ListHead; \
> +    (Entry)->Blink = _EX_Blink; \
> +    _EX_Blink->Flink = (Entry); \
> +    _EX_ListHead->Blink = (Entry); \
> +    }
> +
> +#define RemoveEntryList(Entry) { \
> +    PLIST_ENTRY _EX_Blink; \
> +    PLIST_ENTRY _EX_Flink; \
> +    _EX_Flink = (Entry)->Flink; \
> +    _EX_Blink = (Entry)->Blink; \
> +    _EX_Blink->Flink = _EX_Flink; \
> +    _EX_Flink->Blink = _EX_Blink; \
> +    }
> +
> +typedef struct _XENCONTROL_CONTEXT {
> +    HANDLE XenIface;
> +    XENCONTROL_LOGGER *Logger;
> +    XENCONTROL_LOG_LEVEL LogLevel;
> +    ULONG RequestId;
> +    LIST_ENTRY RequestList;
> +    CRITICAL_SECTION RequestListLock;
> +} XENCONTROL_CONTEXT, *PXENCONTROL_CONTEXT;
> +
> +typedef struct _XENCONTROL_GNTTAB_REQUEST {
> +    LIST_ENTRY  ListEntry;
> +    OVERLAPPED  Overlapped;
> +    ULONG       Id;
> +    PVOID       Address;
> +} XENCONTROL_GNTTAB_REQUEST, *PXENCONTROL_GNTTAB_REQUEST;
> +
> +#endif // _XENCONTROL_PRIVATE_H_
> diff --git a/vs2015/package/package.vcxproj
> b/vs2015/package/package.vcxproj
> index 0b8c7d0..34b07aa 100644
> --- a/vs2015/package/package.vcxproj
> +++ b/vs2015/package/package.vcxproj
> @@ -42,6 +42,9 @@
>      <ProjectReference Include="..\xenagent\xenagent.vcxproj">
>        <Project>{2E61D2CC-865E-442C-8C83-B8DAFD7BBD3B}</Project>
>      </ProjectReference>
> +    <ProjectReference Include="..\xencontrol\xencontrol.vcxproj">
> +      <Project>{D386D8E9-D015-4AD2-A5C2-4F845A803FA2}</Project>
> +    </ProjectReference>
>    </ItemGroup>
>    <ItemGroup>
>      <FilesToPackage Include="$(DPINST_REDIST)\x86\dpinst.exe"
> Condition="'$(Platform)'=='Win32'" />
> diff --git a/vs2015/xencontrol/xencontrol.vcxproj
> b/vs2015/xencontrol/xencontrol.vcxproj
> new file mode 100644
> index 0000000..6b8319d
> --- /dev/null
> +++ b/vs2015/xencontrol/xencontrol.vcxproj
> @@ -0,0 +1,67 @@
> +<?xml version="1.0" encoding="utf-8"?>
> +<Project DefaultTargets="Build" ToolsVersion="14.0"
> xmlns="http://schemas.microsoft.com/developer/msbuild/2003";>
> +  <Import Project="..\configs.props" />
> +  <PropertyGroup Label="PropertySheets">
> +    <CharacterSet>Unicode</CharacterSet>
> +    <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
> +    <ConfigurationType>DynamicLibrary</ConfigurationType>
> +  </PropertyGroup>
> +  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
> +  <PropertyGroup Label="Globals">
> +    <ProjectGuid>{D386D8E9-D015-4AD2-A5C2-
> 4F845A803FA2}</ProjectGuid>
> +  </PropertyGroup>
> +  <Import Project="..\targets.props" />
> +  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
> +  <PropertyGroup>
> +    <IncludePath>$(IncludePath)</IncludePath>
> +    <RunCodeAnalysis>true</RunCodeAnalysis>
> +    <EnableInf2cat>false</EnableInf2cat>
> +  </PropertyGroup>
> +  <ItemDefinitionGroup>
> +    <ClCompile>
> +
> <AdditionalIncludeDirectories>$(SolutionDir)..\include;%(AdditionalIncludeDi
> rectories)</AdditionalIncludeDirectories>
> +
> <PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;XENCONTROL_EXPO
> RTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
> +      <WarningLevel>EnableAllWarnings</WarningLevel>
> +
> <DisableSpecificWarnings>4127;4711;4548;4820;4668;4255;6001;6054;28196;%
> (DisableSpecificWarnings)</DisableSpecificWarnings>
> +      <MultiProcessorCompilation>true</MultiProcessorCompilation>
> +      <EnablePREfast>true</EnablePREfast>
> +      <ExceptionHandling>false</ExceptionHandling>
> +      <TreatWarningAsError>true</TreatWarningAsError>
> +      <RuntimeLibrary
> Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebug</Runtime
> Library>
> +      <RuntimeLibrary
> Condition="'$(UseDebugLibraries)'=='false'">MultiThreaded</RuntimeLibrar
> y>
> +    </ClCompile>
> +    <Link>
> +
> <AdditionalDependencies>setupapi.lib;ws2_32.lib;shlwapi.lib;wtsapi32.lib;us
> erenv.lib;version.lib;ntdll.lib;kernel32.lib;user32.lib;gdi32.lib;comdlg32.lib;adv
> api32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;%(AdditionalDependencies)
> </AdditionalDependencies>
> +    </Link>
> +    <ResourceCompile>
> +
> <AdditionalIncludeDirectories>$(SolutionDir)..\include;%(AdditionalIncludeDi
> rectories)</AdditionalIncludeDirectories>
> +    </ResourceCompile>
> +  </ItemDefinitionGroup>
> +  <ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
> +    <ClCompile>
> +
> <PreprocessorDefinitions>__i386__;%(PreprocessorDefinitions)</Preproces
> sorDefinitions>
> +    </ClCompile>
> +  </ItemDefinitionGroup>
> +  <ItemDefinitionGroup Condition="'$(Platform)'=='x64'">
> +    <ClCompile>
> +
> <PreprocessorDefinitions>__x86_64__;%(PreprocessorDefinitions)</Prepro
> cessorDefinitions>
> +    </ClCompile>
> +  </ItemDefinitionGroup>
> +  <ItemGroup>
> +    <FilesToPackage Include="$(TargetPath)" />
> +    <FilesToPackage Include="$(OutDir)$(TargetName).pdb" />
> +    <FilesToPackage Include="$(OutDir)$(TargetName).dll" />
> +    <FilesToPackage Include="$(OutDir)$(TargetName).lib" />
> +  </ItemGroup>
> +  <ItemGroup>
> +    <ClCompile Include="..\..\src\xencontrol\xencontrol.c" />
> +  </ItemGroup>
> +  <ItemGroup>
> +    <ClInclude Include="..\..\include\xencontrol.h" />
> +    <ClInclude Include="..\..\src\xencontrol\xencontrol_private.h" />
> +  </ItemGroup>
> +  <ItemGroup>
> +    <ResourceCompile Include="..\..\src\xencontrol\xencontrol.rc" />
> +  </ItemGroup>
> +  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
> +</Project>
> diff --git a/vs2015/xencontrol/xencontrol.vcxproj.filters
> b/vs2015/xencontrol/xencontrol.vcxproj.filters
> new file mode 100644
> index 0000000..394e363
> --- /dev/null
> +++ b/vs2015/xencontrol/xencontrol.vcxproj.filters
> @@ -0,0 +1,13 @@
> +<?xml version="1.0" encoding="utf-8"?>
> +<Project ToolsVersion="4.0"
> xmlns="http://schemas.microsoft.com/developer/msbuild/2003";>
> +  <ItemGroup>
> +    <ClInclude Include="..\..\include\xencontrol.h" />
> +    <ClInclude Include="..\..\src\xencontrol\xencontrol_private.h" />
> +  </ItemGroup>
> +  <ItemGroup>
> +    <ResourceCompile Include="..\..\src\xencontrol\xencontrol.rc" />
> +  </ItemGroup>
> +  <ItemGroup>
> +    <ClCompile Include="..\..\src\xencontrol\xencontrol.c" />
> +  </ItemGroup>
> +</Project>
> \ No newline at end of file
> diff --git a/vs2015/xeniface.sln b/vs2015/xeniface.sln
> index 56b8471..4cdc44c 100644
> --- a/vs2015/xeniface.sln
> +++ b/vs2015/xeniface.sln
> @@ -15,6 +15,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}")
> = "package", "package\package.
>               {2E61D2CC-865E-442C-8C83-B8DAFD7BBD3B} = {2E61D2CC-
> 865E-442C-8C83-B8DAFD7BBD3B}
>       EndProjectSection
>  EndProject
> +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xencontrol",
> "xencontrol\xencontrol.vcxproj", "{D386D8E9-D015-4AD2-A5C2-
> 4F845A803FA2}"
> +EndProject
>  Global
>       GlobalSection(SolutionConfigurationPlatforms) = preSolution
>               Windows 7 Debug|Win32 = Windows 7 Debug|Win32
> @@ -175,6 +177,42 @@ Global
>               {9B071A35-897C-477A-AEB7-95F77618A21D}.Windows 10
> Release|x64.ActiveCfg = Windows 10 Release|x64
>               {9B071A35-897C-477A-AEB7-95F77618A21D}.Windows 10
> Release|x64.Build.0 = Windows 10 Release|x64
>               {9B071A35-897C-477A-AEB7-95F77618A21D}.Windows 10
> Release|x64.Deploy.0 = Windows 10 Release|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
> Debug|Win32.ActiveCfg = Windows 7 Debug|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
> Debug|Win32.Build.0 = Windows 7 Debug|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
> Debug|Win32.Deploy.0 = Windows 7 Debug|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
> Debug|x64.ActiveCfg = Windows 7 Debug|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
> Debug|x64.Build.0 = Windows 7 Debug|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
> Debug|x64.Deploy.0 = Windows 7 Debug|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
> Release|Win32.ActiveCfg = Windows 7 Release|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
> Release|Win32.Build.0 = Windows 7 Release|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
> Release|Win32.Deploy.0 = Windows 7 Release|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
> Release|x64.ActiveCfg = Windows 7 Release|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
> Release|x64.Build.0 = Windows 7 Release|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
> Release|x64.Deploy.0 = Windows 7 Release|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 8
> Debug|Win32.ActiveCfg = Windows 8 Debug|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 8
> Debug|Win32.Build.0 = Windows 8 Debug|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 8
> Debug|Win32.Deploy.0 = Windows 8 Debug|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 8
> Debug|x64.ActiveCfg = Windows 8 Debug|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 8
> Debug|x64.Build.0 = Windows 8 Debug|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 8
> Debug|x64.Deploy.0 = Windows 8 Debug|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 8
> Release|Win32.ActiveCfg = Windows 8 Release|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 8
> Release|Win32.Build.0 = Windows 8 Release|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 8
> Release|Win32.Deploy.0 = Windows 8 Release|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 8
> Release|x64.ActiveCfg = Windows 8 Release|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 8
> Release|x64.Build.0 = Windows 8 Release|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 8
> Release|x64.Deploy.0 = Windows 8 Release|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 10
> Debug|Win32.ActiveCfg = Windows 10 Debug|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 10
> Debug|Win32.Build.0 = Windows 10 Debug|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 10
> Debug|Win32.Deploy.0 = Windows 10 Debug|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 10
> Debug|x64.ActiveCfg = Windows 10 Debug|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 10
> Debug|x64.Build.0 = Windows 10 Debug|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 10
> Debug|x64.Deploy.0 = Windows 10 Debug|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 10
> Release|Win32.ActiveCfg = Windows 10 Release|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 10
> Release|Win32.Build.0 = Windows 10 Release|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 10
> Release|Win32.Deploy.0 = Windows 10 Release|Win32
> +             {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
>       EndGlobalSection
>       GlobalSection(SolutionProperties) = preSolution
>               HideSolutionNode = FALSE
> diff --git a/vs2017/package/package.vcxproj
> b/vs2017/package/package.vcxproj
> index 764511b..f9fd507 100644
> --- a/vs2017/package/package.vcxproj
> +++ b/vs2017/package/package.vcxproj
> @@ -42,6 +42,9 @@
>      <ProjectReference Include="..\xenagent\xenagent.vcxproj">
>        <Project>{2E61D2CC-865E-442C-8C83-B8DAFD7BBD3B}</Project>
>      </ProjectReference>
> +    <ProjectReference Include="..\xencontrol\xencontrol.vcxproj">
> +      <Project>{D386D8E9-D015-4AD2-A5C2-4F845A803FA2}</Project>
> +    </ProjectReference>
>    </ItemGroup>
>    <ItemGroup>
>      <FilesToPackage Include="$(DPINST_REDIST)\x86\dpinst.exe"
> Condition="'$(Platform)'=='Win32'" />
> diff --git a/vs2017/xencontrol/xencontrol.vcxproj
> b/vs2017/xencontrol/xencontrol.vcxproj
> new file mode 100644
> index 0000000..52b816c
> --- /dev/null
> +++ b/vs2017/xencontrol/xencontrol.vcxproj
> @@ -0,0 +1,67 @@
> +<?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>Unicode</CharacterSet>
> +    <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
> +    <ConfigurationType>DynamicLibrary</ConfigurationType>
> +  </PropertyGroup>
> +  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
> +  <PropertyGroup Label="Globals">
> +    <ProjectGuid>{D386D8E9-D015-4AD2-A5C2-
> 4F845A803FA2}</ProjectGuid>
> +  </PropertyGroup>
> +  <Import Project="..\targets.props" />
> +  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
> +  <PropertyGroup>
> +    <IncludePath>$(IncludePath)</IncludePath>
> +    <RunCodeAnalysis>true</RunCodeAnalysis>
> +    <EnableInf2cat>false</EnableInf2cat>
> +  </PropertyGroup>
> +  <ItemDefinitionGroup>
> +    <ClCompile>
> +
> <AdditionalIncludeDirectories>$(SolutionDir)..\include;%(AdditionalIncludeDi
> rectories)</AdditionalIncludeDirectories>
> +
> <PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;XENCONTROL_EXPO
> RTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
> +      <WarningLevel>EnableAllWarnings</WarningLevel>
> +
> <DisableSpecificWarnings>4127;4711;4548;4820;4668;4255;6001;6054;28196;%
> (DisableSpecificWarnings)</DisableSpecificWarnings>
> +      <MultiProcessorCompilation>true</MultiProcessorCompilation>
> +      <EnablePREfast>true</EnablePREfast>
> +      <ExceptionHandling>false</ExceptionHandling>
> +      <TreatWarningAsError>true</TreatWarningAsError>
> +      <RuntimeLibrary
> Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebug</Runtime
> Library>
> +      <RuntimeLibrary
> Condition="'$(UseDebugLibraries)'=='false'">MultiThreaded</RuntimeLibrar
> y>
> +    </ClCompile>
> +    <Link>
> +
> <AdditionalDependencies>setupapi.lib;ws2_32.lib;shlwapi.lib;wtsapi32.lib;us
> erenv.lib;version.lib;ntdll.lib;kernel32.lib;user32.lib;gdi32.lib;comdlg32.lib;adv
> api32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;%(AdditionalDependencies)
> </AdditionalDependencies>
> +    </Link>
> +    <ResourceCompile>
> +
> <AdditionalIncludeDirectories>$(SolutionDir)..\include;%(AdditionalIncludeDi
> rectories)</AdditionalIncludeDirectories>
> +    </ResourceCompile>
> +  </ItemDefinitionGroup>
> +  <ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
> +    <ClCompile>
> +
> <PreprocessorDefinitions>__i386__;%(PreprocessorDefinitions)</Preproces
> sorDefinitions>
> +    </ClCompile>
> +  </ItemDefinitionGroup>
> +  <ItemDefinitionGroup Condition="'$(Platform)'=='x64'">
> +    <ClCompile>
> +
> <PreprocessorDefinitions>__x86_64__;%(PreprocessorDefinitions)</Prepro
> cessorDefinitions>
> +    </ClCompile>
> +  </ItemDefinitionGroup>
> +  <ItemGroup>
> +    <FilesToPackage Include="$(TargetPath)" />
> +    <FilesToPackage Include="$(OutDir)$(TargetName).pdb" />
> +    <FilesToPackage Include="$(OutDir)$(TargetName).dll" />
> +    <FilesToPackage Include="$(OutDir)$(TargetName).lib" />
> +  </ItemGroup>
> +  <ItemGroup>
> +    <ClCompile Include="..\..\src\xencontrol\xencontrol.c" />
> +  </ItemGroup>
> +  <ItemGroup>
> +    <ClInclude Include="..\..\include\xencontrol.h" />
> +    <ClInclude Include="..\..\src\xencontrol\xencontrol_private.h" />
> +  </ItemGroup>
> +  <ItemGroup>
> +    <ResourceCompile Include="..\..\src\xencontrol\xencontrol.rc" />
> +  </ItemGroup>
> +  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
> +</Project>
> diff --git a/vs2017/xencontrol/xencontrol.vcxproj.filters
> b/vs2017/xencontrol/xencontrol.vcxproj.filters
> new file mode 100644
> index 0000000..394e363
> --- /dev/null
> +++ b/vs2017/xencontrol/xencontrol.vcxproj.filters
> @@ -0,0 +1,13 @@
> +<?xml version="1.0" encoding="utf-8"?>
> +<Project ToolsVersion="4.0"
> xmlns="http://schemas.microsoft.com/developer/msbuild/2003";>
> +  <ItemGroup>
> +    <ClInclude Include="..\..\include\xencontrol.h" />
> +    <ClInclude Include="..\..\src\xencontrol\xencontrol_private.h" />
> +  </ItemGroup>
> +  <ItemGroup>
> +    <ResourceCompile Include="..\..\src\xencontrol\xencontrol.rc" />
> +  </ItemGroup>
> +  <ItemGroup>
> +    <ClCompile Include="..\..\src\xencontrol\xencontrol.c" />
> +  </ItemGroup>
> +</Project>
> \ No newline at end of file
> diff --git a/vs2017/xeniface.sln b/vs2017/xeniface.sln
> index 56b8471..4cdc44c 100644
> --- a/vs2017/xeniface.sln
> +++ b/vs2017/xeniface.sln
> @@ -15,6 +15,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}")
> = "package", "package\package.
>               {2E61D2CC-865E-442C-8C83-B8DAFD7BBD3B} = {2E61D2CC-
> 865E-442C-8C83-B8DAFD7BBD3B}
>       EndProjectSection
>  EndProject
> +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xencontrol",
> "xencontrol\xencontrol.vcxproj", "{D386D8E9-D015-4AD2-A5C2-
> 4F845A803FA2}"
> +EndProject
>  Global
>       GlobalSection(SolutionConfigurationPlatforms) = preSolution
>               Windows 7 Debug|Win32 = Windows 7 Debug|Win32
> @@ -175,6 +177,42 @@ Global
>               {9B071A35-897C-477A-AEB7-95F77618A21D}.Windows 10
> Release|x64.ActiveCfg = Windows 10 Release|x64
>               {9B071A35-897C-477A-AEB7-95F77618A21D}.Windows 10
> Release|x64.Build.0 = Windows 10 Release|x64
>               {9B071A35-897C-477A-AEB7-95F77618A21D}.Windows 10
> Release|x64.Deploy.0 = Windows 10 Release|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
> Debug|Win32.ActiveCfg = Windows 7 Debug|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
> Debug|Win32.Build.0 = Windows 7 Debug|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
> Debug|Win32.Deploy.0 = Windows 7 Debug|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
> Debug|x64.ActiveCfg = Windows 7 Debug|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
> Debug|x64.Build.0 = Windows 7 Debug|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
> Debug|x64.Deploy.0 = Windows 7 Debug|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
> Release|Win32.ActiveCfg = Windows 7 Release|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
> Release|Win32.Build.0 = Windows 7 Release|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
> Release|Win32.Deploy.0 = Windows 7 Release|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
> Release|x64.ActiveCfg = Windows 7 Release|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
> Release|x64.Build.0 = Windows 7 Release|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
> Release|x64.Deploy.0 = Windows 7 Release|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 8
> Debug|Win32.ActiveCfg = Windows 8 Debug|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 8
> Debug|Win32.Build.0 = Windows 8 Debug|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 8
> Debug|Win32.Deploy.0 = Windows 8 Debug|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 8
> Debug|x64.ActiveCfg = Windows 8 Debug|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 8
> Debug|x64.Build.0 = Windows 8 Debug|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 8
> Debug|x64.Deploy.0 = Windows 8 Debug|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 8
> Release|Win32.ActiveCfg = Windows 8 Release|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 8
> Release|Win32.Build.0 = Windows 8 Release|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 8
> Release|Win32.Deploy.0 = Windows 8 Release|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 8
> Release|x64.ActiveCfg = Windows 8 Release|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 8
> Release|x64.Build.0 = Windows 8 Release|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 8
> Release|x64.Deploy.0 = Windows 8 Release|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 10
> Debug|Win32.ActiveCfg = Windows 10 Debug|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 10
> Debug|Win32.Build.0 = Windows 10 Debug|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 10
> Debug|Win32.Deploy.0 = Windows 10 Debug|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 10
> Debug|x64.ActiveCfg = Windows 10 Debug|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 10
> Debug|x64.Build.0 = Windows 10 Debug|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 10
> Debug|x64.Deploy.0 = Windows 10 Debug|x64
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 10
> Release|Win32.ActiveCfg = Windows 10 Release|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 10
> Release|Win32.Build.0 = Windows 10 Release|Win32
> +             {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 10
> Release|Win32.Deploy.0 = Windows 10 Release|Win32
> +             {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
>       EndGlobalSection
>       GlobalSection(SolutionProperties) = preSolution
>               HideSolutionNode = FALSE
> --
> 2.13.6
> 
> 
> _______________________________________________
> win-pv-devel mailing list
> win-pv-devel@xxxxxxxxxxxxxxxxxxxx
> https://lists.xenproject.org/mailman/listinfo/win-pv-devel
_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/win-pv-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.