[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 |