|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH] Add a user mode library wrapper for XENIFACE IOCTLs
Signed-off-by: Rafal Wojdyla <omeg@xxxxxxxxxxxxxxxxxxxxxx>
---
include/xencontrol.h | 342 ++++++++++
src/xencontrol/xencontrol.c | 915 +++++++++++++++++++++++++++
src/xencontrol/xencontrol.rc | 24 +
src/xencontrol/xencontrol_private.h | 49 ++
vs2013/xencontrol.props | 84 +++
vs2013/xencontrol/xencontrol.vcxproj | 62 ++
vs2013/xencontrol/xencontrol.vcxproj.filters | 13 +
vs2013/xeniface.sln | 38 ++
8 files changed, 1527 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 vs2013/xencontrol.props
create mode 100644 vs2013/xencontrol/xencontrol.vcxproj
create mode 100644 vs2013/xencontrol/xencontrol.vcxproj.filters
diff --git a/include/xencontrol.h b/include/xencontrol.h
new file mode 100644
index 0000000..0a2f8f2
--- /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
+XcEvtchnBindUnbound(
+ 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..92ac9d0
--- /dev/null
+++ b/src/xencontrol/xencontrol.c
@@ -0,0 +1,915 @@
+#define INITGUID
+#include <windows.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
+)
+{
+ 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 += (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
+XcEvtchnBindUnbound(
+ 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
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/vs2013/xencontrol.props b/vs2013/xencontrol.props
new file mode 100644
index 0000000..22c1704
--- /dev/null
+++ b/vs2013/xencontrol.props
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+ <ImportGroup Label="PropertySheets" />
+
+ <PropertyGroup Label="UserMacros" />
+
+ <PropertyGroup>
+ <IncludePath>$(SolutionDir)\..\include;$(IncludePath)</IncludePath>
+
<LibraryPath>$(SolutionDir)\$(Configuration)\$(Platform);$(LibraryPath)</LibraryPath>
+ <OutDir>$(SolutionDir)\$(Configuration)\$(Platform)\</OutDir>
+
<IntDir>$(SolutionDir)\$(ProjectName)\$(Configuration)\$(Platform)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+
+ <PropertyGroup Label="Configuration">
+ <LinkIncremental>false</LinkIncremental>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+
+ <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
+ <RunCodeAnalysis>true</RunCodeAnalysis>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+
+ <PropertyGroup Condition="'$(Configuration)'=='Release'"
Label="Configuration">
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+
+ <ItemDefinitionGroup>
+ <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>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ <ClCompile>
+
<PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <SDLCheck>true</SDLCheck>
+ <ExceptionHandling>false</ExceptionHandling>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ </ClCompile>
+ <CustomBuildStep>
+ <Command>xcopy /y $(TargetPath)
$(SolutionDir)\..\xeniface\$(PlatformTarget)\
+xcopy /y $(TargetDir)$(TargetName).pdb
$(SolutionDir)\..\xeniface\$(PlatformTarget)\
+if exist $(TargetDir)$(TargetName).lib xcopy /y $(TargetDir)$(TargetName).lib
$(SolutionDir)\..\xeniface\$(PlatformTarget)\</Command>
+ </CustomBuildStep>
+ <CustomBuildStep>
+ <Message>Copying output files</Message>
+ </CustomBuildStep>
+ <CustomBuildStep>
+
<Outputs>$(SolutionDir)\..\xeniface\$(PlatformTarget)$(TargetFileName);$(SolutionDir)\..\xeniface\$(PlatformTarget)$(TargetName).pdb;$(SolutionDir)\..\xeniface\$(PlatformTarget)$(TargetName).lib;%(Outputs)</Outputs>
+ </CustomBuildStep>
+ <CustomBuildStep>
+
<Inputs>$(TargetPath);$(TargetDir)$(TargetName).pdb;$(TargetDir)$(TargetName).lib</Inputs>
+ </CustomBuildStep>
+ </ItemDefinitionGroup>
+
+ <ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
+ <ClCompile>
+
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Optimization>Disabled</Optimization>
+ <EnablePREfast>true</EnablePREfast>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ </ClCompile>
+ </ItemDefinitionGroup>
+
+ <ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
+ <ClCompile>
+
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+
+ <ItemGroup />
+</Project>
\ No newline at end of file
diff --git a/vs2013/xencontrol/xencontrol.vcxproj
b/vs2013/xencontrol/xencontrol.vcxproj
new file mode 100644
index 0000000..4d91a38
--- /dev/null
+++ b/vs2013/xencontrol/xencontrol.vcxproj
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{D386D8E9-D015-4AD2-A5C2-4F845A803FA2}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>xencontrol</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')"
Label="LocalAppDataPlatform" />
+ <Import Project="..\xencontrol.props" />
+ </ImportGroup>
+ <ItemDefinitionGroup>
+ <ClCompile>
+
<PreprocessorDefinitions>_WINDOWS;_USRDLL;XENCONTROL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ </Link>
+ </ItemDefinitionGroup>
+ <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" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+ <ProjectExtensions>
+ <VisualStudio>
+ <UserProperties />
+ </VisualStudio>
+ </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/vs2013/xencontrol/xencontrol.vcxproj.filters
b/vs2013/xencontrol/xencontrol.vcxproj.filters
new file mode 100644
index 0000000..c6de099
--- /dev/null
+++ b/vs2013/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/vs2013/xeniface.sln b/vs2013/xeniface.sln
index 3c74c79..76d06b4 100644
--- a/vs2013/xeniface.sln
+++ b/vs2013/xeniface.sln
@@ -17,6 +17,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
@@ -165,6 +167,42 @@ Global
{9B071A35-897C-477A-AEB7-95F77618A21D}.Windows Vista
Release|x64.ActiveCfg = Windows Vista Release|x64
{9B071A35-897C-477A-AEB7-95F77618A21D}.Windows Vista
Release|x64.Build.0 = Windows Vista Release|x64
{9B071A35-897C-477A-AEB7-95F77618A21D}.Windows Vista
Release|x64.Deploy.0 = Windows Vista Release|x64
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
Debug|Win32.ActiveCfg = Debug|Win32
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
Debug|Win32.Build.0 = Debug|Win32
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
Debug|Win32.Deploy.0 = Debug|Win32
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
Debug|x64.ActiveCfg = Debug|x64
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
Debug|x64.Build.0 = Debug|x64
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
Debug|x64.Deploy.0 = Debug|x64
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
Release|Win32.ActiveCfg = Release|Win32
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
Release|Win32.Build.0 = Release|Win32
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
Release|Win32.Deploy.0 = Release|Win32
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
Release|x64.ActiveCfg = Release|x64
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
Release|x64.Build.0 = Release|x64
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows 7
Release|x64.Deploy.0 = Release|x64
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows Developer
Preview Debug|Win32.ActiveCfg = Debug|Win32
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows Developer
Preview Debug|Win32.Build.0 = Debug|Win32
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows Developer
Preview Debug|Win32.Deploy.0 = Debug|Win32
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows Developer
Preview Debug|x64.ActiveCfg = Debug|x64
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows Developer
Preview Debug|x64.Build.0 = Debug|x64
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows Developer
Preview Debug|x64.Deploy.0 = Debug|x64
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows Developer
Preview Release|Win32.ActiveCfg = Release|Win32
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows Developer
Preview Release|Win32.Build.0 = Release|Win32
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows Developer
Preview Release|Win32.Deploy.0 = Release|Win32
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows Developer
Preview Release|x64.ActiveCfg = Release|x64
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows Developer
Preview Release|x64.Build.0 = Release|x64
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows Developer
Preview Release|x64.Deploy.0 = Release|x64
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows Vista
Debug|Win32.ActiveCfg = Debug|Win32
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows Vista
Debug|Win32.Build.0 = Debug|Win32
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows Vista
Debug|Win32.Deploy.0 = Debug|Win32
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows Vista
Debug|x64.ActiveCfg = Debug|x64
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows Vista
Debug|x64.Build.0 = Debug|x64
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows Vista
Debug|x64.Deploy.0 = Debug|x64
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows Vista
Release|Win32.ActiveCfg = Release|Win32
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows Vista
Release|Win32.Build.0 = Release|Win32
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows Vista
Release|Win32.Deploy.0 = Release|Win32
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows Vista
Release|x64.ActiveCfg = Release|x64
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows Vista
Release|x64.Build.0 = Release|x64
+ {D386D8E9-D015-4AD2-A5C2-4F845A803FA2}.Windows Vista
Release|x64.Deploy.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
--
1.8.1.msysgit.1
_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |