]> xenbits.xensource.com Git - pvdrivers/win/xeniface.git/commitdiff
Add a user mode library wrapper for XENIFACE IOCTLs
authorRafal Wojdyla <omeg@invisiblethingslab.com>
Wed, 4 Jul 2018 00:53:39 +0000 (02:53 +0200)
committerPaul Durrant <paul.durrant@citrix.com>
Fri, 13 Jul 2018 14:40:11 +0000 (15:40 +0100)
Signed-off-by: Rafal Wojdyla <omeg@invisiblethingslab.com>
[fix compile warnings, update visual studio files]
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
include/xencontrol.h [new file with mode: 0644]
src/xencontrol/xencontrol.c [new file with mode: 0644]
src/xencontrol/xencontrol.rc [new file with mode: 0644]
src/xencontrol/xencontrol_private.h [new file with mode: 0644]
vs2015/package/package.vcxproj
vs2015/xencontrol/xencontrol.vcxproj [new file with mode: 0644]
vs2015/xeniface.sln
vs2017/package/package.vcxproj
vs2017/xencontrol/xencontrol.vcxproj [new file with mode: 0644]
vs2017/xeniface.sln

diff --git a/include/xencontrol.h b/include/xencontrol.h
new file mode 100644 (file)
index 0000000..4560bc6
--- /dev/null
@@ -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 (file)
index 0000000..777fd29
--- /dev/null
@@ -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,
+                                   FILE_SHARE_READ | FILE_SHARE_WRITE,
+                                   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_OUT, 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 (file)
index 0000000..6c33e84
--- /dev/null
@@ -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 (file)
index 0000000..685bcfa
--- /dev/null
@@ -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_
index 0b8c7d0707d61b49d2e4718bfa3051c8ee824777..34b07aa1a560859cd39b117b3350415c7ab5bf82 100644 (file)
@@ -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 (file)
index 0000000..d1be4ca
--- /dev/null
@@ -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;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;XENCONTROL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <WarningLevel>EnableAllWarnings</WarningLevel>
+      <DisableSpecificWarnings>4127;4711;4548;4820;4668;4255;5045;6001;6054;28196;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <EnablePREfast>true</EnablePREfast>
+      <ExceptionHandling>false</ExceptionHandling>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebug</RuntimeLibrary>
+      <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='false'">MultiThreaded</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>setupapi.lib;ws2_32.lib;shlwapi.lib;wtsapi32.lib;userenv.lib;version.lib;ntdll.lib;kernel32.lib;user32.lib;gdi32.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </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="$(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>
index 040f0717e19291331f5b40fa84171d06d5f38b7d..7f08c1cc59709ff47c4202280cdc56bdfb994551 100644 (file)
@@ -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 8 Debug|Win32 = Windows 8 Debug|Win32
@@ -123,6 +125,30 @@ 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 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
index 764511b5d5f27da64841e54c34c108f98ad46855..f9fd50794ec7a4df405d4d1cbaadac4e1ad65f78 100644 (file)
@@ -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 (file)
index 0000000..18f471c
--- /dev/null
@@ -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;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;XENCONTROL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <WarningLevel>EnableAllWarnings</WarningLevel>
+      <DisableSpecificWarnings>4127;4711;4548;4820;4668;4255;5045;6001;6054;28196;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <EnablePREfast>true</EnablePREfast>
+      <ExceptionHandling>false</ExceptionHandling>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebug</RuntimeLibrary>
+      <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='false'">MultiThreaded</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>setupapi.lib;ws2_32.lib;shlwapi.lib;wtsapi32.lib;userenv.lib;version.lib;ntdll.lib;kernel32.lib;user32.lib;gdi32.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </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="$(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>
index 040f0717e19291331f5b40fa84171d06d5f38b7d..1eb81563243b0c279b4d83523c16c7b32f509308 100644 (file)
@@ -8,11 +8,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xeniface", "xeniface\xenifa
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xenagent", "xenagent\xenagent.vcxproj", "{2E61D2CC-865E-442C-8C83-B8DAFD7BBD3B}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xencontrol", "xencontrol\xencontrol.vcxproj", "{D386D8E9-D015-4AD2-A5C2-4F845A803FA2}"
+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}
        EndProjectSection
 EndProject
 Global
@@ -123,6 +126,30 @@ 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 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