From: Rafal Wojdyla Date: Wed, 4 Jul 2018 00:53:39 +0000 (+0200) Subject: Add a user mode library wrapper for XENIFACE IOCTLs X-Git-Tag: 9.0.0-rc1~19 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=883135b898a15e29c0253b9c1cc2a56359b80236;p=pvdrivers%2Fwin%2Fxeniface.git Add a user mode library wrapper for XENIFACE IOCTLs Signed-off-by: Rafal Wojdyla [fix compile warnings, update visual studio files] Signed-off-by: Marek Marczykowski-Górecki --- diff --git a/include/xencontrol.h b/include/xencontrol.h new file mode 100644 index 0000000..4560bc6 --- /dev/null +++ b/include/xencontrol.h @@ -0,0 +1,342 @@ +#ifndef _XENCONTROL_H_ +#define _XENCONTROL_H_ + +#include +#include +#include "xeniface_ioctls.h" + +#ifdef XENCONTROL_EXPORTS +# define XENCONTROL_API __declspec(dllexport) +#else +# define XENCONTROL_API __declspec(dllimport) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \typedef PXENCONTROL_CONTEXT + \brief Library handle representing a Xen Interface session +*/ +struct _XENCONTROL_CONTEXT; +typedef struct _XENCONTROL_CONTEXT *PXENCONTROL_CONTEXT; + +/*! \typedef XENCONTROL_LOG_LEVEL + \brief Log levels used by the library +*/ +typedef enum +_XENCONTROL_LOG_LEVEL { + XLL_ERROR = 1, + XLL_WARNING, + XLL_INFO, + XLL_DEBUG, + XLL_TRACE, +} XENCONTROL_LOG_LEVEL; + +/*! \typedef XENCONTROL_LOGGER + \brief Callback for receiving diagnostic messages from the library +*/ +typedef void +XENCONTROL_LOGGER( + IN XENCONTROL_LOG_LEVEL LogLevel, + IN const CHAR *Function, + IN const WCHAR *Message, + IN va_list Args + ); + +/*! \brief Register a callback for receiving library's diagnostic messages + \param Xc Xencontrol handle returned by XcOpen() + \param Logger Callback to register +*/ +XENCONTROL_API +void +XcRegisterLogger( + IN PXENCONTROL_CONTEXT Xc, + IN XENCONTROL_LOGGER *Logger + ); + +/*! \brief Set log level threshold for library's diagnostic messages + \param Xc Xencontrol handle returned by XcOpen() + \param LogLevel Only messages with this level and above will be sent to the logger callback +*/ +XENCONTROL_API +void +XcSetLogLevel( + IN PXENCONTROL_CONTEXT Xc, + IN XENCONTROL_LOG_LEVEL LogLevel + ); + +/*! \brief Open the Xen Interface device + \param Logger Callback for receiving library's diagnostic messages + \param Xc Xencontrol handle representing a Xen Interface session + \return Error code +*/ +XENCONTROL_API +DWORD +XcOpen( + IN XENCONTROL_LOGGER *Logger, + OUT PXENCONTROL_CONTEXT *Xc + ); + +/*! \brief Close the Xen Interface device + \param Xc Xencontrol handle returned by XcOpen() +*/ +XENCONTROL_API +void +XcClose( + IN PXENCONTROL_CONTEXT Xc + ); + +/*! \brief Open an unbound event channel + \param Xc Xencontrol handle returned by XcOpen() + \param RemoteDomain ID of a remote domain that will bind the channel + \param Event Handle to an event object that will receive event channel notifications + \param Mask Set to TRUE if the event channel should be initially masked + \param LocalPort Port number that is assigned to the event channel + \return Error code +*/ +XENCONTROL_API +DWORD +XcEvtchnOpenUnbound( + IN PXENCONTROL_CONTEXT Xc, + IN USHORT RemoteDomain, + IN HANDLE Event, + IN BOOL Mask, + OUT ULONG *LocalPort + ); + +/*! \brief Open an event channel that was already bound by a remote domain + \param Xc Xencontrol handle returned by XcOpen() + \param RemoteDomain ID of a remote domain that has already bound the channel + \param RemotePort Port number that is assigned to the event channel in the \a RemoteDomain + \param Event Handle to an event that will receive event channel notifications + \param Mask Set to TRUE if the event object channel should be initially masked + \param LocalPort Port number that is assigned to the event channel + \return Error code +*/ +XENCONTROL_API +DWORD +XcEvtchnBindInterdomain( + IN PXENCONTROL_CONTEXT Xc, + IN USHORT RemoteDomain, + IN ULONG RemotePort, + IN HANDLE Event, + IN BOOL Mask, + OUT ULONG *LocalPort + ); + +/*! \brief Close an event channel + \param Xc Xencontrol handle returned by XcOpen() + \param LocalPort Port number that is assigned to the event channel + \return Error code +*/ +XENCONTROL_API +DWORD +XcEvtchnClose( + IN PXENCONTROL_CONTEXT Xc, + IN ULONG LocalPort + ); + +/*! \brief Notify the remote end of an event channel + \param Xc Xencontrol handle returned by XcOpen() + \param LocalPort Port number that is assigned to the event channel + \return Error code +*/ +XENCONTROL_API +DWORD +XcEvtchnNotify( + IN PXENCONTROL_CONTEXT Xc, + IN ULONG LocalPort + ); + +/*! \brief Unmask an event channel + \param Xc Xencontrol handle returned by XcOpen() + \param LocalPort Port number that is assigned to the event channel + \return Error code +*/ +XENCONTROL_API +DWORD +XcEvtchnUnmask( + IN PXENCONTROL_CONTEXT Xc, + IN ULONG LocalPort + ); + +/*! \brief Grant a \a RemoteDomain permission to access local memory pages + \param Xc Xencontrol handle returned by XcOpen() + \param RemoteDomain ID of a remote domain that is being granted access + \param NumberPages Number of 4k pages to grant access to + \param NotifyOffset Offset of a byte in the granted region that will be set to 0 when the grant is revoked + \param NotifyPort Local port number of an open event channel that will be notified when the grant is revoked + \param Flags Grant options + \param Address Local user mode address of the granted memory region + \param References An array of Xen grant numbers for every granted page + \return Error code +*/ +XENCONTROL_API +DWORD +XcGnttabPermitForeignAccess( + IN PXENCONTROL_CONTEXT Xc, + IN USHORT RemoteDomain, + IN ULONG NumberPages, + IN ULONG NotifyOffset, + IN ULONG NotifyPort, + IN XENIFACE_GNTTAB_PAGE_FLAGS Flags, + OUT PVOID *Address, + OUT ULONG *References + ); + +/*! \brief Revoke a foreign domain access to previously granted memory region + \param Xc Xencontrol handle returned by XcOpen() + \param Address Local user mode address of the granted memory region + \return Error code +*/ +XENCONTROL_API +DWORD +XcGnttabRevokeForeignAccess( + IN PXENCONTROL_CONTEXT Xc, + IN PVOID Address + ); + +/*! \brief Map a foreign memory region into the current address space + \param Xc Xencontrol handle returned by XcOpen() + \param RemoteDomain ID of a remote domain that has granted access to the pages + \param NumberPages Number of 4k pages to map + \param References An array of Xen grant numbers for every granted page + \param NotifyOffset Offset of a byte in the mapped region that will be set to 0 when the region is unmapped + \param NotifyPort Local port number of an open event channel that will be notified when the region is unmapped + \param Flags Map options + \param Address Local user mode address of the mapped memory region + \return Error code +*/ +XENCONTROL_API +DWORD +XcGnttabMapForeignPages( + IN PXENCONTROL_CONTEXT Xc, + IN USHORT RemoteDomain, + IN ULONG NumberPages, + IN PULONG References, + IN ULONG NotifyOffset, + IN ULONG NotifyPort, + IN XENIFACE_GNTTAB_PAGE_FLAGS Flags, + OUT PVOID *Address + ); + +/*! \brief Unmap a foreign memory region from the current address space + \param Xc Xencontrol handle returned by XcOpen() + \param Address Local user mode address of the mapped memory region + \return Error code +*/ +XENCONTROL_API +DWORD +XcGnttabUnmapForeignPages( + IN PXENCONTROL_CONTEXT Xc, + IN PVOID Address + ); + +/*! \brief Read a XenStore key + \param Xc Xencontrol handle returned by XcOpen() + \param Path Path to the key + \param cbValue Size of the \a Value buffer, in bytes + \param Value Buffer that receives the value + \return Error code +*/ +XENCONTROL_API +DWORD +XcStoreRead( + IN PXENCONTROL_CONTEXT Xc, + IN PCHAR Path, + IN DWORD cbValue, + OUT CHAR *Value + ); + +/*! \brief Write a value to a XenStore key + \param Xc Xencontrol handle returned by XcOpen() + \param Path Path to the key + \param Value Value to write + \return Error code +*/ +XENCONTROL_API +DWORD +XcStoreWrite( + IN PXENCONTROL_CONTEXT Xc, + IN PCHAR Path, + IN PCHAR Value + ); + +/*! \brief Enumerate all immediate child keys of a XenStore key + \param Xc Xencontrol handle returned by XcOpen() + \param Path Path to the key + \param cbOutput Size of the \a Output buffer, in bytes + \param Output Buffer that receives a NUL-separated child key names + \return Error code +*/ +XENCONTROL_API +DWORD +XcStoreDirectory( + IN PXENCONTROL_CONTEXT Xc, + IN PCHAR Path, + IN DWORD cbOutput, + OUT CHAR *Output + ); + +/*! \brief Remove a XenStore key + \param Xc Xencontrol handle returned by XcOpen() + \param Path Path to the key + \return Error code +*/ +XENCONTROL_API +DWORD +XcStoreRemove( + IN PXENCONTROL_CONTEXT Xc, + IN PCHAR Path + ); + +/*! \brief Set permissions of a XenStore key + \param Xc Xencontrol handle returned by XcOpen() + \param Path Path to the key + \param Count Number of permissions + \param Permissions Array of permissions to set + \return Error code +*/ +XENCONTROL_API +DWORD +XcStoreSetPermissions( + IN PXENCONTROL_CONTEXT Xc, + IN PCHAR Path, + IN ULONG Count, + IN PXENIFACE_STORE_PERMISSION Permissions + ); + +/*! \brief Add a XenStore key watch + \param Xc Xencontrol handle returned by XcOpen() + \param Path Path to the key to be watched + \param Event Handle to an event that will be signaled when the watch fires + \param Handle An opaque value representing the watch + \return Error code +*/ +XENCONTROL_API +DWORD +XcStoreAddWatch( + IN PXENCONTROL_CONTEXT Xc, + IN PCHAR Path, + IN HANDLE Event, + OUT PVOID *Handle + ); + +/*! \brief Remove a XenStore watch + \param Xc Xencontrol handle returned by XcOpen() + \param Handle Watch handle returned by XcStoreAddWatch() + \return Error code +*/ +XENCONTROL_API +DWORD +XcStoreRemoveWatch( + IN PXENCONTROL_CONTEXT Xc, + IN PVOID Handle + ); + +#ifdef __cplusplus +} +#endif + +#endif // _XENCONTROL_H_ diff --git a/src/xencontrol/xencontrol.c b/src/xencontrol/xencontrol.c new file mode 100644 index 0000000..777fd29 --- /dev/null +++ b/src/xencontrol/xencontrol.c @@ -0,0 +1,919 @@ +#define INITGUID +#include +#include +#include +#include +#include + +#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 index 0000000..6c33e84 --- /dev/null +++ b/src/xencontrol/xencontrol.rc @@ -0,0 +1,24 @@ +#include +#include + +#undef VER_COMPANYNAME_STR +#undef VER_PRODUCTNAME_STR +#undef VER_PRODUCTVERSION +#undef VER_PRODUCTVERSION_STR + +#include + +#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 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 +#include "xencontrol.h" + +#define Log(level, format, ...) \ + _Log(Xc->Logger, level, Xc->LogLevel, __FUNCTION__, format, __VA_ARGS__) + +#define InitializeListHead(ListHead) ( \ + (ListHead)->Flink = (ListHead)->Blink = (ListHead)) + +#define InsertTailList(ListHead, Entry) { \ + PLIST_ENTRY _EX_Blink; \ + PLIST_ENTRY _EX_ListHead; \ + _EX_ListHead = (ListHead); \ + _EX_Blink = _EX_ListHead->Blink; \ + (Entry)->Flink = _EX_ListHead; \ + (Entry)->Blink = _EX_Blink; \ + _EX_Blink->Flink = (Entry); \ + _EX_ListHead->Blink = (Entry); \ + } + +#define RemoveEntryList(Entry) { \ + PLIST_ENTRY _EX_Blink; \ + PLIST_ENTRY _EX_Flink; \ + _EX_Flink = (Entry)->Flink; \ + _EX_Blink = (Entry)->Blink; \ + _EX_Blink->Flink = _EX_Flink; \ + _EX_Flink->Blink = _EX_Blink; \ + } + +typedef struct _XENCONTROL_CONTEXT { + HANDLE XenIface; + XENCONTROL_LOGGER *Logger; + XENCONTROL_LOG_LEVEL LogLevel; + ULONG RequestId; + LIST_ENTRY RequestList; + CRITICAL_SECTION RequestListLock; +} XENCONTROL_CONTEXT, *PXENCONTROL_CONTEXT; + +typedef struct _XENCONTROL_GNTTAB_REQUEST { + LIST_ENTRY ListEntry; + OVERLAPPED Overlapped; + ULONG Id; + PVOID Address; +} XENCONTROL_GNTTAB_REQUEST, *PXENCONTROL_GNTTAB_REQUEST; + +#endif // _XENCONTROL_PRIVATE_H_ diff --git a/vs2015/package/package.vcxproj b/vs2015/package/package.vcxproj index 0b8c7d0..34b07aa 100644 --- a/vs2015/package/package.vcxproj +++ b/vs2015/package/package.vcxproj @@ -42,6 +42,9 @@ {2E61D2CC-865E-442C-8C83-B8DAFD7BBD3B} + + {D386D8E9-D015-4AD2-A5C2-4F845A803FA2} + diff --git a/vs2015/xencontrol/xencontrol.vcxproj b/vs2015/xencontrol/xencontrol.vcxproj new file mode 100644 index 0000000..d1be4ca --- /dev/null +++ b/vs2015/xencontrol/xencontrol.vcxproj @@ -0,0 +1,67 @@ + + + + + Unicode + WindowsApplicationForDrivers10.0 + DynamicLibrary + + + + {D386D8E9-D015-4AD2-A5C2-4F845A803FA2} + + + + + $(IncludePath) + true + false + + + + $(SolutionDir)..\include;%(AdditionalIncludeDirectories) + WIN32;_WINDOWS;_USRDLL;XENCONTROL_EXPORTS;%(PreprocessorDefinitions) + EnableAllWarnings + 4127;4711;4548;4820;4668;4255;5045;6001;6054;28196;%(DisableSpecificWarnings) + true + true + false + true + MultiThreadedDebug + MultiThreaded + + + 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) + + + $(SolutionDir)..\include;%(AdditionalIncludeDirectories) + + + + + __i386__;%(PreprocessorDefinitions) + + + + + __x86_64__;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + diff --git a/vs2015/xeniface.sln b/vs2015/xeniface.sln index 040f071..7f08c1c 100644 --- a/vs2015/xeniface.sln +++ b/vs2015/xeniface.sln @@ -15,6 +15,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "package", "package\package. {2E61D2CC-865E-442C-8C83-B8DAFD7BBD3B} = {2E61D2CC-865E-442C-8C83-B8DAFD7BBD3B} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xencontrol", "xencontrol\xencontrol.vcxproj", "{D386D8E9-D015-4AD2-A5C2-4F845A803FA2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Windows 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 diff --git a/vs2017/package/package.vcxproj b/vs2017/package/package.vcxproj index 764511b..f9fd507 100644 --- a/vs2017/package/package.vcxproj +++ b/vs2017/package/package.vcxproj @@ -42,6 +42,9 @@ {2E61D2CC-865E-442C-8C83-B8DAFD7BBD3B} + + {D386D8E9-D015-4AD2-A5C2-4F845A803FA2} + diff --git a/vs2017/xencontrol/xencontrol.vcxproj b/vs2017/xencontrol/xencontrol.vcxproj new file mode 100644 index 0000000..18f471c --- /dev/null +++ b/vs2017/xencontrol/xencontrol.vcxproj @@ -0,0 +1,67 @@ + + + + + Unicode + WindowsApplicationForDrivers10.0 + DynamicLibrary + + + + {D386D8E9-D015-4AD2-A5C2-4F845A803FA2} + + + + + $(IncludePath) + true + false + + + + $(SolutionDir)..\include;%(AdditionalIncludeDirectories) + WIN32;_WINDOWS;_USRDLL;XENCONTROL_EXPORTS;%(PreprocessorDefinitions) + EnableAllWarnings + 4127;4711;4548;4820;4668;4255;5045;6001;6054;28196;%(DisableSpecificWarnings) + true + true + false + true + MultiThreadedDebug + MultiThreaded + + + 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) + + + $(SolutionDir)..\include;%(AdditionalIncludeDirectories) + + + + + __i386__;%(PreprocessorDefinitions) + + + + + __x86_64__;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + diff --git a/vs2017/xeniface.sln b/vs2017/xeniface.sln index 040f071..1eb8156 100644 --- a/vs2017/xeniface.sln +++ b/vs2017/xeniface.sln @@ -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