├── .gitignore ├── .gitlab-ci.yml ├── .qubesbuilder ├── Makefile ├── Makefile.builder ├── archlinux └── PKGBUILD.in ├── build-deps.list ├── debian-quilt ├── debian ├── README ├── README.configuration ├── changelog ├── compat ├── control ├── copyright ├── libvchan-xen-dev.install ├── libvchan-xen1.install ├── libvchan-xen1.shlibs ├── patches │ └── .gitignore ├── rules └── source │ ├── format │ └── options ├── pkgs └── .gitignore ├── rpm_spec └── libvchan.spec.in ├── series-debian-vm.conf ├── test ├── .gitignore ├── Makefile ├── node-select.c └── node.c ├── vchan ├── .gitignore ├── Makefile.linux ├── Makefile.stubdom ├── init.c ├── io.c ├── libvchan.h ├── libvchan_private.h └── vchan-xen.pc.in ├── version └── windows ├── .gitignore ├── README.md ├── include ├── .gitignore └── libvchan.h ├── set_version.ps1 ├── src ├── dllmain.c ├── init.c ├── io.c ├── libvchan_private.h ├── vchan-test.c └── version.rc └── vs2022 ├── .gitignore ├── core-vchan-xen.sln ├── libvchan ├── libvchan.vcxproj └── libvchan.vcxproj.filters └── vchan-test ├── vchan-test.vcxproj └── vchan-test.vcxproj.filters /.gitignore: -------------------------------------------------------------------------------- 1 | rpm/ 2 | deb/ 3 | *~ 4 | *.o 5 | *.so 6 | *.pc 7 | *.o.dep 8 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | include: 2 | - file: /r4.2/gitlab-base.yml 3 | project: QubesOS/qubes-continuous-integration 4 | ref: $CI_BRANCH_REF 5 | - file: /r4.2/gitlab-host.yml 6 | project: QubesOS/qubes-continuous-integration 7 | ref: $CI_BRANCH_REF 8 | - file: /r4.2/gitlab-vm.yml 9 | project: QubesOS/qubes-continuous-integration 10 | ref: $CI_BRANCH_REF 11 | - file: /r4.3/gitlab-base.yml 12 | project: QubesOS/qubes-continuous-integration 13 | ref: $CI_BRANCH_REF 14 | - file: /r4.3/gitlab-host.yml 15 | project: QubesOS/qubes-continuous-integration 16 | ref: $CI_BRANCH_REF 17 | - file: /r4.3/gitlab-host-qwt.yml 18 | project: QubesOS/qubes-continuous-integration 19 | ref: $CI_BRANCH_REF 20 | - file: /r4.3/gitlab-vm.yml 21 | project: QubesOS/qubes-continuous-integration 22 | ref: $CI_BRANCH_REF 23 | -------------------------------------------------------------------------------- /.qubesbuilder: -------------------------------------------------------------------------------- 1 | host: 2 | rpm: 3 | build: 4 | - rpm_spec/libvchan.spec 5 | vm: 6 | rpm: 7 | build: 8 | - rpm_spec/libvchan.spec 9 | deb: 10 | build: 11 | - debian 12 | archlinux: 13 | build: 14 | - archlinux 15 | windows: 16 | build: 17 | - windows/vs2022/core-vchan-xen.sln 18 | bin: 19 | - windows/vs2022/x64/@CONFIGURATION@/libvchan/libvchan.dll 20 | inc: 21 | - windows/include/libvchan.h 22 | lib: 23 | - windows/vs2022/x64/@CONFIGURATION@/libvchan/libvchan.lib 24 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PREFIX ?= /usr 2 | LIBDIR ?= $(PREFIX)/lib 3 | INCLUDEDIR ?= $(PREFIX)/include 4 | 5 | help: 6 | @echo "make all -- build binaries" 7 | @echo "make clean -- cleanup" 8 | 9 | all: 10 | $(MAKE) -C vchan -f Makefile.linux 11 | 12 | install: 13 | $(MAKE) -C vchan -f Makefile.linux install 14 | 15 | clean: 16 | make -C vchan -f Makefile.linux clean 17 | -------------------------------------------------------------------------------- /Makefile.builder: -------------------------------------------------------------------------------- 1 | ifeq ($(BACKEND_VMM),xen) 2 | RPM_SPEC_FILES := rpm_spec/libvchan.spec 3 | ARCH_BUILD_DIRS := archlinux 4 | 5 | ifeq ($(PACKAGE_SET),vm) 6 | ifneq ($(filter $(DISTRIBUTION), debian qubuntu),) 7 | DEBIAN_BUILD_DIRS := debian 8 | endif 9 | 10 | WIN_COMPILER = msbuild 11 | WIN_SOURCE_SUBDIRS = windows 12 | WIN_BUILD_DEPS = vmm-xen-windows-pvdrivers 13 | WIN_OUTPUT_LIBS = bin 14 | WIN_OUTPUT_HEADERS = include 15 | WIN_OUTPUT_BIN = bin 16 | WIN_PREBUILD_CMD = set_version.bat && powershell -executionpolicy bypass -File set_version.ps1 < nul 17 | WIN_SLN_DIR = vs2017 18 | endif 19 | 20 | endif 21 | 22 | # Support for new packaging 23 | ifneq ($(filter $(DISTRIBUTION), archlinux),) 24 | VERSION := $(file <$(ORIG_SRC)/$(DIST_SRC)/version) 25 | GIT_TARBALL_NAME ?= qubes-libvchan-xen-$(VERSION)-1.tar.gz 26 | SOURCE_COPY_IN := source-archlinux-copy-in 27 | 28 | source-archlinux-copy-in: PKGBUILD = $(CHROOT_DIR)/$(DIST_SRC)/$(ARCH_BUILD_DIRS)/PKGBUILD 29 | source-archlinux-copy-in: 30 | cp $(PKGBUILD).in $(CHROOT_DIR)/$(DIST_SRC)/PKGBUILD 31 | sed -i "s/@VERSION@/$(VERSION)/g" $(CHROOT_DIR)/$(DIST_SRC)/PKGBUILD 32 | sed -i "s/@REL@/1/g" $(CHROOT_DIR)/$(DIST_SRC)/PKGBUILD 33 | endif 34 | 35 | # vim: filetype=make 36 | -------------------------------------------------------------------------------- /archlinux/PKGBUILD.in: -------------------------------------------------------------------------------- 1 | # Maintainer: Frédéric Pierret (fepitre) 2 | 3 | pkgname=qubes-libvchan-xen 4 | pkgver=@VERSION@ 5 | pkgrel=@REL@ 6 | pkgdesc="The Qubes core libraries for installation inside a Qubes Dom0 and VM." 7 | _pkgnvr="${pkgname}-${pkgver}-${pkgrel}" 8 | arch=("x86_64") 9 | url="http://qubes-os.org/" 10 | license=('GPL') 11 | depends=(qubes-vm-xen) 12 | provides=('qubes-core-libs' 'qubes-libvchan') 13 | source=("${_pkgnvr}.tar.gz") 14 | sha256sums=(SKIP) 15 | 16 | build() { 17 | cd "${_pkgnvr}/vchan" 18 | make -f Makefile.linux 19 | } 20 | 21 | package() { 22 | cd "${_pkgnvr}" 23 | make install DESTDIR="$pkgdir" LIBDIR=/usr/lib INCLUDEDIR=/usr/include 24 | } 25 | -------------------------------------------------------------------------------- /build-deps.list: -------------------------------------------------------------------------------- 1 | xen-devel 2 | -------------------------------------------------------------------------------- /debian-quilt: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # vim: set ts=4 sw=4 sts=4 et : 3 | # 4 | # Given a series.conf file and debian patches directory, patches 5 | # are copied to debian patch directory 6 | 7 | USAGE="${0} " 8 | 9 | set -e 10 | set -o pipefail 11 | 12 | DIR="${0%/*}" 13 | SERIES_CONF="${1}" 14 | PATCH_DIR="${2}" 15 | 16 | if test $# -lt 2 || [ ! -e "${SERIES_CONF}" ] || [ ! -d "${PATCH_DIR}" ] ; then 17 | echo "${USAGE}" >&2 18 | exit 1 19 | fi 20 | 21 | # Clear patch series.conf file 22 | rm -f "${PATCH_DIR}/series" 23 | touch "${PATCH_DIR}/series" 24 | 25 | while read patch_file 26 | do 27 | if [ -e "${DIR}/${patch_file}" ]; then 28 | echo -e "${patch_file##*/}" >> "${PATCH_DIR}/series" 29 | cp "${DIR}/${patch_file}" "${PATCH_DIR}" 30 | fi 31 | done < "${SERIES_CONF}" 32 | -------------------------------------------------------------------------------- /debian/README: -------------------------------------------------------------------------------- 1 | qubes-core-vchan-xen 2 | -------------------- 3 | 4 | See http://www.qubes-os.org/ 5 | 6 | -- Davíð Steinn Geirsson Mon, 10 Mar 2014 21:53:17 +0000 7 | -------------------------------------------------------------------------------- /debian/README.configuration: -------------------------------------------------------------------------------- 1 | Debian Packaging Guide 2 | ---------------------- 3 | https://www.debian.org/doc/manuals/maint-guide/first.en.html 4 | 5 | 6 | =============================================================================== 7 | Bash.rc 8 | =============================================================================== 9 | cat >>~/.bashrc <<'EOF' 10 | DEBMAIL="user@chroot.local" 11 | DEBFULLNAME="Qubes Builder" 12 | export DEBMAIL DEBFULLNAME 13 | 14 | alias dquilt="quilt --quiltrc=${HOME}/.quiltrc-dpkg" 15 | complete -F _quilt_completion $_quilt_complete_opt dquilt 16 | EOF 17 | 18 | 19 | =============================================================================== 20 | Quilt RC 21 | =============================================================================== 22 | cat >>~/.quiltrc-dpkg <<'EOF' 23 | d=. ; while [ ! -d $d/debian -a `readlink -e $d` != / ]; do d=$d/..; done 24 | if [ -d $d/debian ] && [ -z $QUILT_PATCHES ]; then 25 | # if in Debian packaging tree with unset $QUILT_PATCHES 26 | QUILT_PATCHES="debian/patches" 27 | QUILT_PATCH_OPTS="--reject-format=unified" 28 | QUILT_DIFF_ARGS="-p ab --no-timestamps --no-index --color=auto" 29 | QUILT_REFRESH_ARGS="-p ab --no-timestamps --no-index" 30 | QUILT_COLORS="diff_hdr=1;32:diff_add=1;34:diff_rem=1;31:diff_hunk=1;33:diff_ctx=35:diff_cctx=33" 31 | if ! [ -d $d/debian/patches ]; then mkdir $d/debian/patches; fi 32 | fi 33 | EOF 34 | 35 | =============================================================================== 36 | Create a fresh Debian configuration 37 | =============================================================================== 38 | apt-get dh-make 39 | 40 | # Example 41 | $ cd ~/gentoo 42 | $ wget http://example.org/gentoo-0.9.12.tar.gz 43 | $ tar -xvzf gentoo-0.9.12.tar.gz 44 | $ cd gentoo-0.9.12 45 | $ dh_make -f ../gentoo-0.9.12.tar.gz 46 | 47 | 48 | =============================================================================== 49 | Adding Patches 50 | =============================================================================== 51 | https://www.debian.org/doc/manuals/maint-guide/modify.en.html 52 | 53 | # When anyone (including yourself) provides a patch foo.patch to the source 54 | # later, modifying a 3.0 (quilt) source package is quite simple: 55 | $ dpkg-source -x gentoo_0.9.12.dsc 56 | $ cd gentoo-0.9.12 57 | $ dquilt import ../foo.patch 58 | $ dquilt push 59 | $ dquilt refresh 60 | $ dquilt header -e 61 | ... describe patch 62 | 63 | 64 | 65 | =============================================================================== 66 | Other 67 | =============================================================================== 68 | # To list all dh_ modules... 69 | man -k dh_ 70 | 71 | # To indicate what build-depends are required! 72 | dpkg-depcheck -d ./configure 73 | 74 | # Test build (unsigned) 75 | dpkg-buildpackage -us -uc 76 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | libvchan-xen (4.2.7-1) unstable; urgency=medium 2 | 3 | [ Rafał Wojdyła ] 4 | * Update for Windows 10 5 | * readme: describe required env variables 6 | * Fix build script to run from different directories 7 | * Update gitignore 8 | * windows: remove 32bit build configurations 9 | * windows: remove unused Makefile 10 | * Support building from the installer 11 | * Make project outputs separate to eliminate postbuild copy overlap 12 | * vchan: properly set xencontrol log level 13 | * windows: remove unnecessary xenstore wait 14 | * windows: add libvchan_cleanup() for xenstore path removal 15 | * windows: fix vchan-test 16 | * windows: support builder v2 17 | * windows: update readme 18 | * windows: Fix local build 19 | * windows: update gitignore 20 | 21 | [ Marek Marczykowski-Górecki ] 22 | * ci: remove R4.1, add R4.3 23 | 24 | [ Rafał Wojdyła ] 25 | * windows: make libvchan_client_init() xenstore logic more clear 26 | 27 | -- Marek Marczykowski-Górecki Tue, 18 Mar 2025 20:37:21 +0100 28 | 29 | libvchan-xen (4.2.6-1) unstable; urgency=medium 30 | 31 | * debian: require pkg-config 32 | 33 | -- Marek Marczykowski-Górecki Thu, 30 Jan 2025 05:57:26 +0100 34 | 35 | libvchan-xen (4.2.5-1) unstable; urgency=medium 36 | 37 | * Rebuild with Xen 4.19 in Trixie 38 | 39 | -- Marek Marczykowski-Górecki Thu, 30 Jan 2025 04:44:45 +0100 40 | 41 | libvchan-xen (4.2.4-1) unstable; urgency=medium 42 | 43 | * 44 | 45 | -- Marek Marczykowski-Górecki Sun, 18 Aug 2024 02:51:07 +0200 46 | 47 | libvchan-xen (4.2.3-1) unstable; urgency=medium 48 | 49 | * Support changed libxenctrl API in Xen 4.18.0 50 | * Fix parameters order in calloc call 51 | 52 | -- Marek Marczykowski-Górecki Mon, 05 Feb 2024 05:17:55 +0100 53 | 54 | libvchan-xen (4.2.2-1) unstable; urgency=medium 55 | 56 | [ Frédéric Pierret (fepitre) ] 57 | * gitlab-ci: use CI_BRANCH_REF 58 | 59 | [ Demi Marie Obenour ] 60 | * Avoid mention of username "user" 61 | * Clobber already-existing symlinks 62 | * Remove pkg-config file in 'make clean' 63 | * Add missing -L${libdir} to pkg-config 64 | 65 | [ Marek Marczykowski-Górecki ] 66 | * rpm: fix missing ? in dist tag 67 | * rpm: move libvchan-xen.so to -devel package 68 | * rpm: add directory ownership 69 | * Drop forced -D_FORTIFY_SOURCE=2 70 | 71 | -- Marek Marczykowski-Górecki Thu, 02 Nov 2023 02:10:31 +0100 72 | 73 | libvchan-xen (4.2.1-1) unstable; urgency=medium 74 | 75 | [ Marek Marczykowski-Górecki ] 76 | * Fix use after free detected by GCC 13 77 | 78 | [ Frédéric Pierret (fepitre) ] 79 | * Rework Archlinux packaging 80 | * archlinux: support for new packaging in legacy builder 81 | 82 | -- Marek Marczykowski-Górecki Tue, 25 Apr 2023 22:59:39 +0200 83 | 84 | libvchan-xen (4.2.0-1) unstable; urgency=medium 85 | 86 | * Interface for async client connection 87 | * Make all the public function deal with half-open client vchan 88 | * Properly define soname 89 | * Link with libxenstore 90 | * debian: rename package for proper soname handling 91 | * debian: fail the build if files are missing 92 | * debian: bump compat level to 10 93 | 94 | -- Marek Marczykowski-Górecki Mon, 09 Jan 2023 05:02:12 +0100 95 | 96 | libvchan-xen (4.1.12-1) unstable; urgency=medium 97 | 98 | * debian: do not hardcode libxenstore version 99 | 100 | -- Marek Marczykowski-Górecki Fri, 02 Dec 2022 18:45:10 +0100 101 | 102 | libvchan-xen (4.1.11-1) unstable; urgency=medium 103 | 104 | [ Demi Marie Obenour ] 105 | * Stricter domid validation 106 | 107 | -- Marek Marczykowski-Górecki Fri, 02 Dec 2022 02:29:24 +0100 108 | 109 | libvchan-xen (4.1.10-1) wheezy; urgency=medium 110 | 111 | [ Demi Marie Obenour ] 112 | * Add missing include 113 | * Avoid using reserved identifiers in macros 114 | * Better build system 115 | * Validate peer domain IDs 116 | * Validate port numbers 117 | 118 | -- Marek Marczykowski-Górecki Sun, 13 Nov 2022 00:00:45 +0100 119 | 120 | libvchan-xen (4.1.9-1) unstable; urgency=medium 121 | 122 | [ Demi Marie Obenour ] 123 | * Allow controlling the blocking flag of a vchan 124 | 125 | -- Marek Marczykowski-Górecki Fri, 11 Nov 2022 11:41:48 +0100 126 | 127 | libvchan-xen (4.1.8-1) unstable; urgency=medium 128 | 129 | [ Marek Marczykowski-Górecki ] 130 | * Make the code compile with MinGW 131 | * Add Makefile for MinGW build 132 | 133 | [ Mikhail Lukashov ] 134 | * windows: improve logging 135 | 136 | [ Frédéric Pierret (fepitre) ] 137 | * Drop Travis CI 138 | * Add Qubes Builder v2 integration 139 | * .qubesbuilder: replace 'spec' by 'build' 140 | 141 | [ Marek Marczykowski-Górecki ] 142 | * ci: include windows build too 143 | 144 | [ Frédéric Pierret (fepitre) ] 145 | * Makefile.builder: restrict build for BACKEND_VMM=xen 146 | 147 | [ Demi Marie Obenour ] 148 | * Do not leak Xen control interface 149 | * Avoid leaks in libvchan_server_init() 150 | * libvchan_client_init(): avoid leaking resources 151 | * Include before using size_t 152 | * Switch from select() to poll() 153 | * Add -D_FORTIFY_SOURCE=2 unconditionally 154 | 155 | -- Marek Marczykowski-Górecki Wed, 31 Aug 2022 09:33:23 +0200 156 | 157 | libvchan-xen (4.1.7-1) unstable; urgency=medium 158 | 159 | [ Frédéric Pierret (fepitre) ] 160 | * archlinux: fix missing symlink in refactor 161 | 162 | -- Marek Marczykowski-Górecki Thu, 31 Dec 2020 13:30:26 +0100 163 | 164 | libvchan-xen (4.1.6-1) unstable; urgency=medium 165 | 166 | * Include extra 'backend_vmm' variable in pkgconfig file 167 | 168 | -- Marek Marczykowski-Górecki Tue, 01 Dec 2020 06:17:13 +0100 169 | 170 | libvchan-xen (4.1.5-1) unstable; urgency=medium 171 | 172 | [ Frédéric Pierret (fepitre) ] 173 | * Create symlink to vchan-xen.pc 174 | * archlinux: polish PKGBUILD 175 | * debian: provide generic libvchan{,-dev} packages 176 | * Add .gitlab-ci.yml 177 | 178 | [ Marek Marczykowski-Górecki ] 179 | * Remove u2mfn lib 180 | 181 | -- Marek Marczykowski-Górecki Thu, 19 Nov 2020 00:45:24 +0100 182 | 183 | libvchan-xen (4.1.4-1) unstable; urgency=medium 184 | 185 | [ Frédéric Pierret (fepitre) ] 186 | * travis: switch to bionic 187 | * travis: switch to dom0 Fedora 31 188 | * Update travis 189 | 190 | -- Marek Marczykowski-Górecki Mon, 31 Aug 2020 04:06:31 +0200 191 | 192 | libvchan-xen (4.1.3-1) unstable; urgency=medium 193 | 194 | * Rebuild for CentOS 195 | 196 | -- Marek Marczykowski-Górecki Tue, 15 Oct 2019 03:05:34 +0200 197 | 198 | libvchan-xen (4.1.2-1) unstable; urgency=medium 199 | 200 | * travis: switch to xenial 201 | * Check if domain is alive using domctl 202 | 203 | -- Marek Marczykowski-Górecki Sat, 21 Sep 2019 03:53:38 +0200 204 | 205 | libvchan-xen (4.1.1-1) unstable; urgency=medium 206 | 207 | * Drop obsolete make targets 208 | * Make the makefile more flexible, introduce PREFIX, LIBDIR, 209 | INCLUDEDIR 210 | * rpm: make use of improved make file 211 | * debian: make use of more flexible makefile 212 | * travis: update distributions 213 | 214 | -- Marek Marczykowski-Górecki Mon, 09 Sep 2019 04:25:31 +0200 215 | 216 | libvchan-xen (4.1.0-1) unstable; urgency=medium 217 | 218 | * debian: don't create orig.tar.gz manually 219 | * debian: add autotools-dev to build-depends 220 | * travis: update to R4.1 221 | 222 | -- Marek Marczykowski-Górecki Wed, 27 Feb 2019 02:48:47 +0100 223 | 224 | libvchan-xen (4.0.5-1) unstable; urgency=medium 225 | 226 | * 227 | 228 | -- Marek Marczykowski-Górecki Tue, 09 Oct 2018 20:28:20 +0200 229 | 230 | libvchan-xen (4.0.4-1) unstable; urgency=medium 231 | 232 | * rpm: add BR: gcc 233 | * travis: update Fedora and Debian versions 234 | 235 | -- Marek Marczykowski-Górecki Mon, 08 Oct 2018 22:50:37 +0200 236 | 237 | libvchan-xen (4.0.3-1) unstable; urgency=medium 238 | 239 | * windows: update for vs2017 240 | 241 | -- Marek Marczykowski-Górecki Wed, 11 Jul 2018 16:27:02 +0200 242 | 243 | libvchan-xen (4.0.2-1) unstable; urgency=medium 244 | 245 | [ Marek Marczykowski-Górecki ] 246 | * Adjust snprintf string limit 247 | 248 | [ Frédéric Pierret ] 249 | * Create spec.in and Source0 250 | * Remove _builddir 251 | * spec.in: add changelog placeholder 252 | 253 | [ Marek Marczykowski-Górecki ] 254 | * travis: update for R4.0, bump Fedora versions 255 | * travis: add centos7 256 | 257 | -- Marek Marczykowski-Górecki Thu, 03 May 2018 01:12:58 +0200 258 | 259 | libvchan-xen (4.0.1-1) unstable; urgency=medium 260 | 261 | [ Ilpo Järvinen ] 262 | * Typo fix to description 263 | 264 | -- Marek Marczykowski-Górecki Tue, 27 Feb 2018 15:16:33 +0100 265 | 266 | libvchan-xen (4.0.0-1) unstable; urgency=medium 267 | 268 | * 269 | 270 | -- Marek Marczykowski-Górecki Sat, 05 Aug 2017 11:26:14 +0200 271 | 272 | libvchan-xen (3.2.1-1) unstable; urgency=medium 273 | 274 | * Don't require xen-devel when building other packages linked with 275 | vchan 276 | * travis: drop debootstrap workaround 277 | * Cleanup empty xenstore directory after removing connection data 278 | 279 | -- Marek Marczykowski-Górecki Sat, 08 Apr 2017 13:52:30 +0200 280 | 281 | libvchan-xen (3.2.0-1) wheezy; urgency=medium 282 | 283 | [ Marek Marczykowski-Górecki ] 284 | * travis: initial version 285 | 286 | [ WetwareLabs ] 287 | * Fix building for Xen 4.7.0 288 | * Add libxenctlr dependency 289 | * Move libxenctrl dependency to Makefile 290 | 291 | [ Marek Marczykowski-Górecki ] 292 | * Allow building with Xen 4.6 and 4.7 293 | 294 | -- Marek Marczykowski-Górecki Mon, 05 Sep 2016 01:29:39 +0200 295 | 296 | libvchan-xen (3.1.0-1) wheezy; urgency=medium 297 | 298 | [ Marek Marczykowski-Górecki ] 299 | * studom: fix building with Xen 4.6 300 | * Remove redundant link option 301 | * debian: do not depend on specific Xen version 302 | 303 | [ Rafał Wojdyła ] 304 | * windows: update for pvdriver changes 305 | * windows: update logger type 306 | * windows: automatic VS project formatting 307 | * windows: define meaningful perror() in vchan-test 308 | * windows: return ERROR_NOT_SUPPORTED if xeniface is unavailable 309 | 310 | -- Marek Marczykowski-Górecki Sat, 28 Nov 2015 14:44:50 +0100 311 | 312 | libvchan-xen (3.0.8-1) wheezy; urgency=medium 313 | 314 | [ Rafał Wojdyła ] 315 | * windows: don't close invalid handles 316 | * windows: support logging using xeniface logger 317 | * windows: account for xenstore watches being triggered immediately 318 | after creation 319 | 320 | -- Marek Marczykowski-Górecki Sun, 09 Aug 2015 05:11:24 +0200 321 | 322 | libvchan-xen (3.0.7-1) wheezy; urgency=medium 323 | 324 | * 325 | 326 | -- Marek Marczykowski-Górecki Sat, 08 Aug 2015 05:05:12 +0200 327 | 328 | libvchan-xen (3.0.6-1) wheezy; urgency=medium 329 | 330 | [ Wojtek Porczyk ] 331 | * spec: -devel Requires: xen-devel 332 | 333 | [ Olivier MEDOC ] 334 | * archlinux: Change library name to match QubesR3 name 335 | 336 | [ Wojtek Porczyk ] 337 | * debian/control: libvchan-xen-dev Depends: libxen-dev 338 | 339 | [ Marek Marczykowski-Górecki ] 340 | * Add test program 341 | * Ignore EINTR in libvchan_wait 342 | 343 | [ Rafał Wojdyła ] 344 | * windows: update for new pvdrivers 345 | * windows: fixed signing 346 | * windows: added test program 347 | * windows: updated gitignore 348 | * windows: moved common property sheet 349 | * windos: removed default sign/wix scripts 350 | * enabled code analysis on debug build 351 | * windows: close xeninterface on client close 352 | * windows: allow libvchan_close on null control struct 353 | * windows: share more common properties in projects 354 | * windows: installer cleanup 355 | * windows: prevent installer name collision 356 | 357 | [ Marek Marczykowski-Górecki ] 358 | * windows: fix libvchan_close(NULL) handling 359 | 360 | -- Marek Marczykowski-Górecki Wed, 01 Jul 2015 07:07:18 +0200 361 | 362 | libvchan-xen (3.0.5-1) wheezy; urgency=medium 363 | 364 | * Rearrange error handling in libvchan_client_init, no functional 365 | change 366 | * Do not use global xc_interface, open separate one for each vchan 367 | connection 368 | * Simplify watch loop in libvchan_client_init 369 | 370 | -- Marek Marczykowski-Górecki Sun, 03 May 2015 13:10:28 +0200 371 | 372 | libvchan-xen (3.0.4-1) wheezy; urgency=medium 373 | 374 | * Check if remote domain is still alive 375 | 376 | -- Marek Marczykowski-Górecki Tue, 28 Apr 2015 13:22:00 +0200 377 | 378 | libvchan-xen (3.0.3-1) wheezy; urgency=medium 379 | 380 | * rpm: remove duplicated Group: header 381 | 382 | -- Marek Marczykowski-Górecki Sat, 11 Apr 2015 03:08:10 +0200 383 | 384 | libvchan-xen (3.0.2-1) wheezy; urgency=medium 385 | 386 | * Provide description of libxenvchan_is_open return values 387 | * client: watch for remote domain shutdown during client 388 | initialization 389 | 390 | -- Marek Marczykowski-Górecki Wed, 01 Apr 2015 00:10:14 +0200 391 | 392 | libvchan-xen (3.0.1-1) wheezy; urgency=medium 393 | 394 | [ Jason Mehring ] 395 | * debian: Converted Debian packaging to quilt to allow patches 396 | * debian: Refactor Debian quilt packaging 397 | * debian: Modified copy-in for patches not to fail if no patch script 398 | exists to allow removing patches in future 399 | * debian: Revert back to using libxen-dev and libxen as depends 400 | * debian: Add extend-diff-ignore options to debian packager 401 | 402 | [ Marek Marczykowski-Górecki ] 403 | * Prevent loopback connections, which currently crashes the kernel 404 | 405 | -- Marek Marczykowski-Górecki Fri, 27 Mar 2015 00:28:10 +0100 406 | 407 | libvchan-xen (3.0.0-1) jessie; urgency=medium 408 | 409 | [ Marek Marczykowski-Górecki ] 410 | * debian: fix deps for jessie build 411 | 412 | [ Marek Marczykowski ] 413 | * New vchan API - make it based on libxenvchan (upstreamed version of 414 | vchan) 415 | * Rename library to libvchan-xen, update rpm headers 416 | * Remove libvchan_get_domain_name 417 | * restore slow check in libvchan_is_open 418 | * gitignore update 419 | * client: notify the server when connected 420 | * init/client: properly get own domain ID 421 | * Fix minor memleak. 422 | * Remove vchan connection data from xenstore on vchan close 423 | * client: Rebuild xs_path when own domid changed 424 | 425 | [ Marek Marczykowski-Górecki ] 426 | * remove xenstore entries just after establishing connection 427 | * Add missing 'const' 428 | 429 | -- Marek Marczykowski-Górecki Sat, 22 Nov 2014 16:24:06 +0100 430 | 431 | libvchan-xen (2.2.8) jessie; urgency=medium 432 | 433 | [ Davíð Steinn Geirsson ] 434 | * Add initial debian packaging 435 | 436 | [ Marek Marczykowski-Górecki ] 437 | * debian: change package name to libvchan-xen, split headers to -dev 438 | pkg 439 | * gitignore 440 | 441 | -- Marek Marczykowski-Górecki Mon, 28 Jul 2014 02:42:33 +0200 442 | 443 | libvchan-xen (2.2.7) jessie; urgency=low 444 | 445 | * Initial Release. 446 | 447 | -- Davíð Steinn Geirsson Sun, 20 Apr 2014 19:18:18 +0000 448 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: libvchan-xen 2 | Section: libs 3 | Priority: extra 4 | Maintainer: Jason Mehring 5 | Build-Depends: 6 | debhelper, 7 | quilt, 8 | autotools-dev, 9 | pkg-config, 10 | libxen-dev 11 | Standards-Version: 3.9.5 12 | Homepage: http://www.qubes-os.org 13 | 14 | Package: libvchan-xen1 15 | Section: libs 16 | Architecture: amd64 17 | Depends: ${shlibs:Depends}, ${misc:Depends} 18 | Conflicts: qubes-core-vchan-xen 19 | Provides: libvchan 20 | Description: Qubes Xen core libraries 21 | This package includes the libraries required for the higher-level Qubes 22 | daemons and tools. 23 | 24 | Package: libvchan-xen-dev 25 | Section: libdevel 26 | Architecture: amd64 27 | Conflicts: qubes-core-vchan-xen 28 | Breaks: libvchan-xen (<< 4.2.0) 29 | Replaces: libvchan-xen (<< 4.2.0) 30 | Depends: libvchan-xen1 (= ${binary:Version}), ${misc:Depends} 31 | Provides: libvchan-dev 32 | Description: Development files for Qubes libvchan communication library. 33 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: qubes-core-vchan-xen 3 | Source: 4 | 5 | Files: * 6 | Copyright: ?-2014 Qubes Developers 7 | License: GPL-2+ 8 | This package is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2 of the License, or 11 | (at your option) any later version. 12 | . 13 | This package is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | . 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see 20 | . 21 | On Debian systems, the complete text of the GNU General 22 | Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". 23 | 24 | Files: debian/* 25 | Copyright: 2014 Davíð Steinn Geirsson 26 | License: GPL-2+ 27 | This package is free software; you can redistribute it and/or modify 28 | it under the terms of the GNU General Public License as published by 29 | the Free Software Foundation; either version 2 of the License, or 30 | (at your option) any later version. 31 | . 32 | This package is distributed in the hope that it will be useful, 33 | but WITHOUT ANY WARRANTY; without even the implied warranty of 34 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 35 | GNU General Public License for more details. 36 | . 37 | You should have received a copy of the GNU General Public License 38 | along with this program. If not, see 39 | . 40 | On Debian systems, the complete text of the GNU General 41 | Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". 42 | 43 | -------------------------------------------------------------------------------- /debian/libvchan-xen-dev.install: -------------------------------------------------------------------------------- 1 | usr/lib/libvchan-xen.so 2 | usr/include/vchan-xen/libvchan.h 3 | usr/lib/pkgconfig/vchan-xen.pc 4 | usr/lib/pkgconfig/vchan.pc 5 | -------------------------------------------------------------------------------- /debian/libvchan-xen1.install: -------------------------------------------------------------------------------- 1 | usr/lib/libvchan-xen.so.* 2 | -------------------------------------------------------------------------------- /debian/libvchan-xen1.shlibs: -------------------------------------------------------------------------------- 1 | libvchan-xen 1 libvchan-xen1 (>= 4.2.0) 2 | -------------------------------------------------------------------------------- /debian/patches/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QubesOS/qubes-core-vchan-xen/b39c9a853f05a7789f8989cd83e824cde981d56b/debian/patches/.gitignore -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | 4 | # Uncomment this to turn on verbose mode. 5 | #export DH_VERBOSE=1 6 | 7 | DPKG_EXPORT_BUILDFLAGS = 1 8 | include /usr/share/dpkg/default.mk 9 | 10 | export DESTDIR=$(shell pwd)/debian/tmp 11 | 12 | %: 13 | dh $@ 14 | 15 | override_dh_auto_build: 16 | make all LIBDIR=/usr/lib 17 | 18 | override_dh_auto_install: 19 | make install LIBDIR=/usr/lib 20 | 21 | override_dh_missing: 22 | dh_missing --fail-missing 23 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /debian/source/options: -------------------------------------------------------------------------------- 1 | extend-diff-ignore = "(^|/)(.git/.*)$" 2 | extend-diff-ignore = "(^|/)(deb/.*)$" 3 | extend-diff-ignore = "(^|/)(pkgs/.*)$" 4 | extend-diff-ignore = "(^|/)(rpm/.*)$" 5 | -------------------------------------------------------------------------------- /pkgs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /rpm_spec/libvchan.spec.in: -------------------------------------------------------------------------------- 1 | # 2 | # The Qubes OS Project, http://www.qubes-os.org 3 | # 4 | # Copyright (C) 2010 Joanna Rutkowska 5 | # Copyright (C) 2010 Rafal Wojtczuk 6 | # Copyright (C) 2012 Marek Marczykowski 7 | # 8 | # This program is free software; you can redistribute it and/or 9 | # modify it under the terms of the GNU General Public License 10 | # as published by the Free Software Foundation; either version 2 11 | # of the License, or (at your option) any later version. 12 | # 13 | # This program is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 21 | # 22 | # 23 | 24 | Name: qubes-libvchan-xen 25 | Version: @VERSION@ 26 | Release: 1%{?dist} 27 | 28 | Summary: Qubes vchan libraries 29 | License: GPL v2 only 30 | Group: Qubes 31 | Vendor: Invisible Things Lab 32 | URL: http://www.qubes-os.org 33 | Obsoletes: qubes-core-libs < 2.1.2 34 | Provides: qubes-core-libs 35 | Provides: qubes-libvchan 36 | BuildRequires: gcc 37 | BuildRequires: xen-devel >= 4.2 38 | Source0: %{name}-%{version}.tar.gz 39 | 40 | %description 41 | The Qubes core libraries for installation inside a Qubes Dom0 and VM. 42 | 43 | %prep 44 | %setup -q 45 | 46 | %build 47 | %set_build_flags 48 | export LIBDIR=%{_libdir} 49 | export INCLUDEDIR=%{_includedir} 50 | make all 51 | 52 | %install 53 | export LIBDIR=%{_libdir} 54 | export INCLUDEDIR=%{_includedir} 55 | make DESTDIR=$RPM_BUILD_ROOT install 56 | 57 | %clean 58 | rm -rf $RPM_BUILD_ROOT 59 | rm -f %{name}-%{version} 60 | 61 | %files 62 | %{_libdir}/libvchan-xen.so.* 63 | 64 | %package devel 65 | Summary: Include files for qubes core libraries 66 | License: GPL v2 only 67 | Group: Development/Sources 68 | Obsoletes: qubes-core-appvm-devel 69 | Obsoletes: qubes-core-vm-devel < 2.1.2 70 | Obsoletes: qubes-core-libs-devel < 2.1.2 71 | Provides: qubes-core-vm-devel 72 | Provides: qubes-core-libs-devel 73 | Provides: qubes-libvchan-devel 74 | Requires: %{name} = %{version}-%{release} 75 | Requires: pkgconfig 76 | 77 | %description devel 78 | 79 | %files devel 80 | %dir %{_includedir}/vchan-xen 81 | %{_includedir}/vchan-xen/libvchan.h 82 | %{_libdir}/libvchan-xen.so 83 | %{_libdir}/pkgconfig/vchan-xen.pc 84 | %{_libdir}/pkgconfig/vchan.pc 85 | 86 | %changelog 87 | @CHANGELOG@ 88 | -------------------------------------------------------------------------------- /series-debian-vm.conf: -------------------------------------------------------------------------------- 1 | patches.debian/use_debian_lib_directory_for_pkgconfig.patch 2 | -------------------------------------------------------------------------------- /test/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | node 3 | node-select 4 | -------------------------------------------------------------------------------- /test/Makefile: -------------------------------------------------------------------------------- 1 | 2 | CC=gcc 3 | CFLAGS=-g -Wall -Wextra -Werror -fPIC -O2 -I../vchan 4 | all: node node-select 5 | 6 | node: node.o 7 | gcc -g -o node node.o -L../vchan -lvchan-xen 8 | node-select: node-select.o 9 | gcc -g -o node-select node-select.o -L../vchan -lvchan-xen 10 | clean: 11 | rm -f *.o node node-select 12 | 13 | -------------------------------------------------------------------------------- /test/node-select.c: -------------------------------------------------------------------------------- 1 | /* 2 | * The Qubes OS Project, http://www.qubes-os.org 3 | * 4 | * Copyright (C) 2010 Rafal Wojtczuk 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | * 20 | */ 21 | 22 | #include "libvchan.h" 23 | #include 24 | #include 25 | #include 26 | #include 27 | int libvchan_write_all(struct libvchan *ctrl, char *buf, int size) 28 | { 29 | int written = 0; 30 | int ret; 31 | while (written < size) { 32 | ret = libvchan_write(ctrl, buf + written, size - written); 33 | if (ret <= 0) { 34 | perror("write"); 35 | exit(1); 36 | } 37 | written += ret; 38 | } 39 | return size; 40 | } 41 | 42 | int write_all(int fd, char *buf, int size) 43 | { 44 | int written = 0; 45 | int ret; 46 | while (written < size) { 47 | ret = write(fd, buf + written, size - written); 48 | if (ret <= 0) { 49 | perror("write"); 50 | exit(1); 51 | } 52 | written += ret; 53 | } 54 | return size; 55 | } 56 | 57 | 58 | void usage() 59 | { 60 | fprintf(stderr, "usage:\n\tnode-select server domainid nodeid\n" 61 | "or\n" "\tnode-select client domainid nodeid\n"); 62 | exit(1); 63 | } 64 | 65 | #define BUFSIZE 5000 66 | char buf[BUFSIZE]; 67 | 68 | /** 69 | Simple libvchan application, both client and server. 70 | Both sides may write and read, both from the libvchan and from 71 | stdin/stdout (just like netcat). More code is required to avoid 72 | deadlock when both sides write, and noone reads. 73 | */ 74 | 75 | int main(int argc, char **argv) 76 | { 77 | int ret; 78 | int libvchan_fd; 79 | struct libvchan *ctrl = 0; 80 | if (argc < 3) 81 | usage(); 82 | if (!strcmp(argv[1], "server")) 83 | ctrl = libvchan_server_init(atoi(argv[2]), atoi(argv[3]), 1024, 1024); 84 | else if (!strcmp(argv[1], "client")) 85 | ctrl = libvchan_client_init(atoi(argv[2]), atoi(argv[3])); 86 | else 87 | usage(); 88 | if (!ctrl) { 89 | perror("libvchan_*_init"); 90 | exit(1); 91 | } 92 | 93 | for (;;) { 94 | fd_set rfds; 95 | FD_ZERO(&rfds); 96 | FD_SET(0, &rfds); 97 | libvchan_fd = libvchan_fd_for_select(ctrl); 98 | FD_SET(libvchan_fd, &rfds); 99 | // libvchan_prepare_to_select(ctrl); 100 | ret = select(libvchan_fd + 1, &rfds, NULL, NULL, NULL); 101 | if (ret < 0) { 102 | perror("select"); 103 | exit(1); 104 | } 105 | if (!libvchan_is_open(ctrl)) 106 | exit(0); 107 | if (FD_ISSET(libvchan_fd, &rfds)) 108 | // we don't care about the result, but we need to do the read to 109 | // clear libvchan_fd pendind state 110 | libvchan_wait(ctrl); 111 | while (libvchan_data_ready(ctrl) > 0) { 112 | ret = libvchan_read(ctrl, buf, BUFSIZE); 113 | if (ret < 0) 114 | exit(0); 115 | write_all(1, buf, ret); 116 | } 117 | if (FD_ISSET(0, &rfds)) { 118 | ret = read(0, buf, BUFSIZE); 119 | if (ret == 0) { 120 | libvchan_close(ctrl); 121 | exit(0); 122 | } 123 | if (ret < 0) { 124 | perror("read 0"); 125 | exit(1); 126 | } 127 | // libvchan_write_all can block; so if both sides write a lot, 128 | // we can deadlock. Need higher level solution; would libvchan_write be ok ? 129 | libvchan_write_all(ctrl, buf, ret); 130 | } 131 | 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /test/node.c: -------------------------------------------------------------------------------- 1 | /* 2 | * The Qubes OS Project, http://www.qubes-os.org 3 | * 4 | * Copyright (C) 2010 Rafal Wojtczuk 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | * 20 | */ 21 | 22 | #include "libvchan.h" 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | int libvchan_write_all(libvchan_t *ctrl, char *buf, int size) 29 | { 30 | int written = 0; 31 | int ret; 32 | while (written < size) { 33 | ret = libvchan_write(ctrl, buf + written, size - written); 34 | if (ret <= 0) { 35 | perror("write"); 36 | exit(1); 37 | } 38 | written += ret; 39 | } 40 | return size; 41 | } 42 | 43 | int write_all(int fd, char *buf, int size) 44 | { 45 | int written = 0; 46 | int ret; 47 | while (written < size) { 48 | ret = write(fd, buf + written, size - written); 49 | if (ret <= 0) { 50 | perror("write"); 51 | exit(1); 52 | } 53 | written += ret; 54 | } 55 | return size; 56 | } 57 | 58 | void usage() 59 | { 60 | fprintf(stderr, "usage:\n\tnode server [read|write] domainid nodeid\n" 61 | "or\n" "\tnode client [read|write] domainid nodeid\n"); 62 | exit(1); 63 | } 64 | 65 | #define BUFSIZE 5000 66 | char buf[BUFSIZE]; 67 | void reader(libvchan_t *ctrl) 68 | { 69 | int size; 70 | for (;;) { 71 | size = rand() % (BUFSIZE - 1) + 1; 72 | size = libvchan_read(ctrl, buf, size); 73 | fprintf(stderr, "#"); 74 | if (size < 0) { 75 | perror("read vchan"); 76 | libvchan_close(ctrl); 77 | exit(1); 78 | } 79 | if (size == 0) 80 | break; 81 | size = write_all(1, buf, size); 82 | if (size < 0) { 83 | perror("stdout write"); 84 | exit(1); 85 | } 86 | if (size == 0) { 87 | perror("write size=0?\n"); 88 | exit(1); 89 | } 90 | } 91 | } 92 | 93 | void writer(libvchan_t *ctrl) 94 | { 95 | int size; 96 | for (;;) { 97 | size = rand() % (BUFSIZE - 1) + 1; 98 | size = read(0, buf, size); 99 | if (size < 0) { 100 | perror("read stdin"); 101 | libvchan_close(ctrl); 102 | exit(1); 103 | } 104 | if (size == 0) 105 | break; 106 | size = libvchan_write_all(ctrl, buf, size); 107 | fprintf(stderr, "#"); 108 | if (size < 0) { 109 | perror("vchan write"); 110 | exit(1); 111 | } 112 | if (size == 0) { 113 | perror("write size=0?\n"); 114 | exit(1); 115 | } 116 | } 117 | } 118 | 119 | 120 | /** 121 | Simple libvchan application, both client and server. 122 | One side does writing, the other side does reading; both from 123 | standard input/output fds. 124 | */ 125 | int main(int argc, char **argv) 126 | { 127 | int seed = time(0); 128 | libvchan_t *ctrl = 0; 129 | int wr = 0; 130 | if (argc < 4) 131 | usage(); 132 | if (!strcmp(argv[2], "read")) 133 | wr = 0; 134 | else if (!strcmp(argv[2], "write")) 135 | wr = 1; 136 | else 137 | usage(); 138 | if (!strcmp(argv[1], "server")) 139 | ctrl = libvchan_server_init(atoi(argv[3]), atoi(argv[4]), 1024, 1024); 140 | else if (!strcmp(argv[1], "client")) 141 | ctrl = libvchan_client_init(atoi(argv[3]), atoi(argv[4])); 142 | else 143 | usage(); 144 | if (!ctrl) { 145 | perror("libvchan_*_init"); 146 | exit(1); 147 | } 148 | 149 | srand(seed); 150 | fprintf(stderr, "seed=%d\n", seed); 151 | if (wr) 152 | writer(ctrl); 153 | else 154 | reader(ctrl); 155 | libvchan_close(ctrl); 156 | return 0; 157 | } 158 | -------------------------------------------------------------------------------- /vchan/.gitignore: -------------------------------------------------------------------------------- 1 | libvchan.so 2 | -------------------------------------------------------------------------------- /vchan/Makefile.linux: -------------------------------------------------------------------------------- 1 | # 2 | # The Qubes OS Project, http://www.qubes-os.org 3 | # 4 | # Copyright (C) 2010 Rafal Wojtczuk 5 | # 6 | # This program is free software; you can redistribute it and/or 7 | # modify it under the terms of the GNU General Public License 8 | # as published by the Free Software Foundation; either version 2 9 | # of the License, or (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program; if not, write to the Free Software 18 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | # 20 | # 21 | 22 | PREFIX ?= /usr 23 | LIBDIR ?= $(PREFIX)/lib 24 | INCLUDEDIR ?= $(PREFIX)/include 25 | CC ?= gcc 26 | CFLAGS += -g -Wall -Wextra -Werror -fPIC -O2 -D_GNU_SOURCE -MD -MP -MF $@.dep 27 | all: libvchan-xen.so vchan-xen.pc 28 | -include *.dep 29 | 30 | # xenctrl.h does not provide any #define to distinguish API versions 31 | XENCTRL_VERSION := $(shell pkg-config --modversion xencontrol) 32 | CFLAGS += $(shell if printf '%s\n' '4.18.0' '$(XENCTRL_VERSION)' | \ 33 | sort -CV; then echo -DHAVE_XC_DOMAIN_GETINFO_SINGLE; fi) 34 | SO_VER = 1 35 | 36 | libvchan-xen.so.$(SO_VER): init.o io.o 37 | $(CC) $(LDFLAGS) -Wl,-soname,$@ -shared -o $@ $^ -lxenvchan -lxenctrl -lxenstore 38 | 39 | libvchan-xen.so: libvchan-xen.so.$(SO_VER) 40 | ln -sf $< $@ 41 | 42 | clean: 43 | rm -f *.o *so *~ client server node node-select vchan-xen.pc 44 | 45 | install: vchan-xen.pc libvchan.h libvchan-xen.so.$(SO_VER) 46 | install -D -m 0644 libvchan.h $(DESTDIR)$(INCLUDEDIR)/vchan-xen/libvchan.h 47 | install -D -m 0644 vchan-xen.pc $(DESTDIR)$(LIBDIR)/pkgconfig/vchan-xen.pc 48 | install -D -t $(DESTDIR)$(LIBDIR)/ libvchan-xen.so.$(SO_VER) 49 | ln -sf libvchan-xen.so.$(SO_VER) $(DESTDIR)$(LIBDIR)/libvchan-xen.so 50 | ln -sf vchan-xen.pc $(DESTDIR)$(LIBDIR)/pkgconfig/vchan.pc 51 | 52 | vchan-xen.pc: vchan-xen.pc.in 53 | sed -e "s/@VERSION@/`cat ../version`/" \ 54 | -e "s:@PREFIX@:$(PREFIX):" \ 55 | -e "s:@LIBDIR@:$(LIBDIR):" \ 56 | -e "s:@INCLUDEDIR@:$(INCLUDEDIR):" \ 57 | $< > $@ 58 | -------------------------------------------------------------------------------- /vchan/Makefile.stubdom: -------------------------------------------------------------------------------- 1 | # 2 | # The Qubes OS Project, http://www.qubes-os.org 3 | # 4 | # Copyright (C) 2012 Marek Marczykowski 5 | # 6 | # This program is free software; you can redistribute it and/or 7 | # modify it under the terms of the GNU General Public License 8 | # as published by the Free Software Foundation; either version 2 9 | # of the License, or (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program; if not, write to the Free Software 18 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | # 20 | # 21 | 22 | # Assume it is placed as xen-root/tools/vchan 23 | 24 | XEN_ROOT = $(CURDIR)/../.. 25 | include $(XEN_ROOT)/tools/Rules.mk 26 | 27 | LIBXC_INCLUDES := $(if $(wildcard $(XEN_ROOT)/tools/libxc/include),\ 28 | $(XEN_ROOT)/tools/libxc/include,\ 29 | $(XEN_ROOT)/tools/libxc) 30 | 31 | CFLAGS+=-Wall -Wextra -Werror -I$(LIBXC_INCLUDES) -I$(XEN_ROOT)/tools/libvchan \ 32 | -DCONFIG_STUBDOM -fPIC -O2 -D_GNU_SOURCE -D_FORTIFY_SOURCE=2 -MD -MP -MF $@.dep 33 | all: libvchan.a 34 | -include *.dep 35 | 36 | libvchan.a: init.o io.o 37 | $(AR) rc $@ $^ 38 | 39 | clean: 40 | rm -f *.o *so *~ client server node node-select 41 | 42 | 43 | -------------------------------------------------------------------------------- /vchan/init.c: -------------------------------------------------------------------------------- 1 | /* 2 | * The Qubes OS Project, http://www.qubes-os.org 3 | * 4 | * Copyright (C) 2010 Rafal Wojtczuk 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | * 20 | */ 21 | #define XC_WANT_COMPAT_EVTCHN_API 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include "libvchan.h" 31 | #include "libvchan_private.h" 32 | 33 | static domid_t parse_domid(const char *ptr) { 34 | char *endptr; 35 | unsigned long ret; 36 | 37 | if (!ptr) 38 | return DOMID_INVALID; 39 | if (ptr[0] == '0') 40 | return ptr[1] ? DOMID_INVALID : 0; 41 | if (ptr[0] < '1' || ptr[0] > '9') 42 | return DOMID_INVALID; 43 | ret = strtoul(ptr, &endptr, 10); 44 | return (*endptr || ret >= DOMID_FIRST_RESERVED) ? DOMID_INVALID : (domid_t)ret; 45 | } 46 | 47 | libvchan_t *libvchan_server_init(int domain, int port, size_t read_min, size_t write_min) { 48 | libvchan_t *ctrl; 49 | 50 | ctrl = calloc(1, sizeof(*ctrl)); 51 | if (!ctrl) 52 | return NULL; 53 | 54 | if (asprintf(&ctrl->xs_path, "data/vchan/%d/%d", domain, port) < 0) 55 | goto err_asprintf; 56 | ctrl->xenvchan = libxenvchan_server_init(NULL, domain, ctrl->xs_path, read_min, write_min); 57 | if (!ctrl->xenvchan) 58 | goto err_server_init; 59 | ctrl->xenvchan->blocking = 1; 60 | ctrl->remote_domain = domain; 61 | if (!(ctrl->xc_handle = xc_interface_open(NULL, NULL, 0))) 62 | goto err_xc_open; 63 | return ctrl; 64 | err_xc_open: 65 | libxenvchan_close(ctrl->xenvchan); 66 | err_server_init: 67 | free(ctrl->xs_path); 68 | err_asprintf: 69 | free(ctrl); 70 | return NULL; 71 | } 72 | 73 | libvchan_t *libvchan_client_init_async(int domain, int port, int *watch_fd) { 74 | libvchan_t *ctrl; 75 | xc_interface *xc_handle; 76 | struct xs_handle *xs; 77 | 78 | if (domain < 0 || (unsigned)domain >= DOMID_FIRST_RESERVED) { 79 | fprintf(stderr, "Invalid peer domain ID %d\n", domain); 80 | return NULL; 81 | } 82 | 83 | if (port < 0) { 84 | fprintf(stderr, "Invalid port %d\n", port); 85 | return NULL; 86 | } 87 | 88 | xc_handle = xc_interface_open(NULL, NULL, 0); 89 | if (!xc_handle) { 90 | /* error already logged by xc_interface_open */ 91 | goto err; 92 | } 93 | 94 | /* wait for server to appear */ 95 | xs = xs_open(0); 96 | if (!xs) { 97 | perror("xs_open"); 98 | goto err_xc; 99 | } 100 | 101 | if (!xs_watch(xs, "domid", "domid")) { 102 | fprintf(stderr, "Cannot setup xenstore watch\n"); 103 | goto err_xs; 104 | } 105 | if (!xs_watch(xs, "@releaseDomain", "release")) { 106 | fprintf(stderr, "Cannot setup xenstore watch\n"); 107 | goto err_xs; 108 | } 109 | 110 | ctrl = calloc(1, sizeof(*ctrl)); 111 | if (!ctrl) 112 | goto err_xs; 113 | ctrl->xs = xs; 114 | ctrl->xc_handle = xc_handle; 115 | ctrl->remote_domain = domain; 116 | ctrl->local_domain = DOMID_INVALID; 117 | ctrl->port = port; 118 | 119 | /* 120 | * Watch for the path is established only when domid watch gets fired for 121 | * the first time 122 | */ 123 | *watch_fd = xs_fileno(xs); 124 | 125 | return ctrl; 126 | 127 | err_xs: 128 | xs_close(xs); 129 | err_xc: 130 | xc_interface_close(xc_handle); 131 | err: 132 | return NULL; 133 | } 134 | 135 | int libvchan_client_init_async_finish(libvchan_t *ctrl, bool blocking) { 136 | char xs_path_base[255]; 137 | char *own_domid; 138 | char **vec; 139 | unsigned int len; 140 | char *tmp_str = NULL; 141 | 142 | for (;;) { 143 | vec = xs_check_watch(ctrl->xs); 144 | if (vec) { 145 | if (strcmp(vec[XS_WATCH_TOKEN], "domid") == 0) { 146 | /* domid have changed */ 147 | if (ctrl->xs_path) { 148 | xs_unwatch(ctrl->xs, ctrl->xs_path, ctrl->xs_path); 149 | free(ctrl->xs_path); 150 | ctrl->xs_path = NULL; 151 | } 152 | ctrl->local_domain = DOMID_INVALID; 153 | } 154 | free(vec); 155 | } else if (errno == EAGAIN) { 156 | break; 157 | } else if (errno == EINTR) { 158 | continue; 159 | } else { 160 | return -1; 161 | } 162 | } 163 | 164 | /* get local domid after watch gets registered, and after each change */ 165 | if (ctrl->local_domain == DOMID_INVALID) { 166 | own_domid = xs_read(ctrl->xs, 0, "domid", &len); 167 | if (!own_domid) { 168 | fprintf(stderr, "Cannot get own domid\n"); 169 | goto err; 170 | } 171 | int own_domid_num = parse_domid(own_domid); 172 | if (own_domid_num == DOMID_INVALID) { 173 | fprintf(stderr, "Invalid own domid %s\n", own_domid); 174 | free(own_domid); 175 | goto err; 176 | } 177 | free(own_domid); 178 | if (own_domid_num == ctrl->remote_domain) { 179 | fprintf(stderr, "Loopback vchan connection not supported\n"); 180 | goto err; 181 | } 182 | ctrl->local_domain = own_domid_num; 183 | } 184 | 185 | /* construct xenstore path on first iteration and on every domid 186 | * change detected (save+restore case) */ 187 | if (!ctrl->xs_path) { 188 | int v; 189 | 190 | v = snprintf(xs_path_base, sizeof(xs_path_base), "/local/domain/%d/data/vchan/%d/%d", 191 | ctrl->remote_domain, ctrl->local_domain, ctrl->port); 192 | if ((unsigned)v >= sizeof(xs_path_base)) { 193 | goto err; 194 | } 195 | 196 | /* watch on this key as we might not have access to the whole directory */ 197 | v = asprintf(&ctrl->xs_path, "%.128s/event-channel", xs_path_base); 198 | if (v < 0) { 199 | goto err; 200 | } 201 | 202 | if (!xs_watch(ctrl->xs, ctrl->xs_path, ctrl->xs_path)) { 203 | fprintf(stderr, "Cannot setup watch on %s\n", ctrl->xs_path); 204 | goto err; 205 | } 206 | } 207 | 208 | tmp_str = xs_read(ctrl->xs, 0, ctrl->xs_path, &len); 209 | if (tmp_str) 210 | free(tmp_str); 211 | else { 212 | if (!libvchan__check_domain_alive(ctrl->xc_handle, ctrl->remote_domain)) { 213 | fprintf(stderr, "domain dead\n"); 214 | goto err; 215 | } 216 | /* no xenstore entry (yet), wait more */ 217 | return 1; 218 | } 219 | 220 | if (!len) { 221 | /* empty entry, wait more */ 222 | return 1; 223 | } 224 | 225 | /* when got here, wait is over, attempt to connect */ 226 | xs_close(ctrl->xs); 227 | ctrl->xs = NULL; 228 | 229 | /* cut trailing /event-channel */ 230 | tmp_str = strrchr(ctrl->xs_path, '/'); 231 | assert(tmp_str); 232 | *tmp_str = '\0'; 233 | 234 | ctrl->xenvchan = libxenvchan_client_init(NULL, ctrl->remote_domain, ctrl->xs_path); 235 | free(ctrl->xs_path); 236 | ctrl->xs_path = NULL; 237 | if (!ctrl->xenvchan) 238 | goto err; 239 | ctrl->xenvchan->blocking = blocking; 240 | /* notify server */ 241 | xc_evtchn_notify(ctrl->xenvchan->event, ctrl->xenvchan->event_port); 242 | return 0; 243 | 244 | err: 245 | return -1; 246 | } 247 | 248 | libvchan_t *libvchan_client_init(int domain, int port) { 249 | libvchan_t *ctrl; 250 | int watch_fd, connect_ret = 1; 251 | struct pollfd vchan_wait = { 252 | .events = POLLIN, 253 | }; 254 | 255 | ctrl = libvchan_client_init_async(domain, port, &watch_fd); 256 | if (!ctrl) 257 | return NULL; 258 | 259 | vchan_wait.fd = watch_fd; 260 | do { 261 | if (poll(&vchan_wait, 1, -1) == -1 && errno != EINTR) { 262 | perror("poll"); 263 | libvchan_close(ctrl); 264 | return NULL; 265 | } 266 | if (vchan_wait.revents & (POLLERR | POLLHUP | POLLNVAL)) { 267 | fprintf(stderr, "unexpected watch_fd event: 0x%x\n", vchan_wait.revents); 268 | libvchan_close(ctrl); 269 | return NULL; 270 | } 271 | if (vchan_wait.revents & POLLIN) { 272 | connect_ret = libvchan_client_init_async_finish(ctrl, true); 273 | } 274 | } while (connect_ret > 0); 275 | 276 | if (connect_ret < 0) { 277 | /* error, ctrl already cleaned up */ 278 | return NULL; 279 | } 280 | 281 | assert(connect_ret == 0); 282 | /* connected */ 283 | return ctrl; 284 | } 285 | -------------------------------------------------------------------------------- /vchan/io.c: -------------------------------------------------------------------------------- 1 | /* 2 | * The Qubes OS Project, http://www.qubes-os.org 3 | * 4 | * Copyright (C) 2010 Rafal Wojtczuk 5 | * Copyright (C) 2013 Marek Marczykowski 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License 9 | * as published by the Free Software Foundation; either version 2 10 | * of the License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 | * 21 | */ 22 | #define XC_WANT_COMPAT_EVTCHN_API 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include "libvchan.h" 31 | #include "libvchan_private.h" 32 | 33 | /* check if domain is still alive */ 34 | int libvchan__check_domain_alive(xc_interface *xc_handle, int dom) { 35 | struct evtchn_status evst; 36 | #ifdef HAVE_XC_DOMAIN_GETINFO_SINGLE 37 | xc_domaininfo_t dominfo; 38 | #else 39 | xc_dominfo_t dominfo; 40 | #endif 41 | int ret; 42 | 43 | /* first try using domctl, more reliable but available in a privileged 44 | * domain only */ 45 | #ifdef HAVE_XC_DOMAIN_GETINFO_SINGLE 46 | ret = xc_domain_getinfo_single(xc_handle, dom, &dominfo); 47 | if (ret == 0) 48 | return !(dominfo.flags & XEN_DOMINF_dying); 49 | #else 50 | ret = xc_domain_getinfo(xc_handle, dom, 1, &dominfo); 51 | if (ret == 1) 52 | return dominfo.domid == (uint32_t)dom && !dominfo.dying; 53 | #endif 54 | else if (ret == -1 && errno == ESRCH) 55 | return 0; 56 | /* otherwise fallback to xc_evtchn_status method */ 57 | 58 | evst.dom = dom; 59 | /* xc_evtchn_status will return different error depending on 60 | * existence of "source" domain: 61 | * ESRCH - domain don't exists 62 | * EINVAL/EPERM - domain exsts but port is invalid / cannot check 63 | * its status 64 | */ 65 | evst.port = -1; 66 | 67 | ret = xc_evtchn_status(xc_handle, &evst); 68 | if (ret == -1 && errno == ESRCH) { 69 | return 0; 70 | } 71 | return 1; 72 | } 73 | 74 | int libvchan_write(libvchan_t *ctrl, const void *data, size_t size) { 75 | if (!ctrl->xenvchan) { 76 | errno = EAGAIN; 77 | return -1; 78 | } 79 | return libxenvchan_write(ctrl->xenvchan, (char*)data, size); 80 | } 81 | 82 | int libvchan_send(libvchan_t *ctrl, const void *data, size_t size) { 83 | if (!ctrl->xenvchan) { 84 | errno = EAGAIN; 85 | return -1; 86 | } 87 | return libxenvchan_send(ctrl->xenvchan, (char*)data, size); 88 | } 89 | 90 | int libvchan_read(libvchan_t *ctrl, void *data, size_t size) { 91 | if (!ctrl->xenvchan) { 92 | errno = EAGAIN; 93 | return -1; 94 | } 95 | return libxenvchan_read(ctrl->xenvchan, (char*)data, size); 96 | } 97 | 98 | void libvchan_set_blocking(libvchan_t *ctrl, bool blocking) { 99 | if (!ctrl->xenvchan) 100 | /* this API call doesn't have way to report errors */ 101 | abort(); 102 | ctrl->xenvchan->blocking = blocking; 103 | } 104 | 105 | int libvchan_recv(libvchan_t *ctrl, void *data, size_t size) { 106 | if (!ctrl->xenvchan) { 107 | errno = EAGAIN; 108 | return -1; 109 | } 110 | return libxenvchan_recv(ctrl->xenvchan, (char*)data, size); 111 | } 112 | 113 | int libvchan_wait(libvchan_t *ctrl) { 114 | int ret = -2; /* invalid, so can be distinguished from real 115 | libxenvchan_wait return code */ 116 | struct xs_handle *xs; 117 | 118 | if (!ctrl->xenvchan) 119 | return 0; 120 | 121 | if (ctrl->xenvchan->is_server && libxenvchan_is_open(ctrl->xenvchan) == 2) { 122 | /* In case of vchan server waiting for a client, we'll not receive any 123 | * notification if the remote domain dies before connecting. Because of 124 | * that, check periodically if remote domain is still alive while 125 | * waiting for a connection. Actually this doesn't cover all the cases 126 | * - if remote domain is still alive, but remote process dies before 127 | * connecting, we'll also not receive any notification. But this, in 128 | * most cases, can be solved by application using libvchan. 129 | * 130 | * During normal operation this shouldn't be long - in most cases vchan 131 | * client will connect almost instantly. So this sleep(10) loop will 132 | * not hurt. Alternativelly it could be implemented with 133 | * xs_watch("@releaseDomain"), but such approach will slow down most 134 | * common execution path (xs_open+xs_watch even if client connects 135 | * right away). 136 | */ 137 | while (ret == -2 && libxenvchan_is_open(ctrl->xenvchan) == 2) { 138 | int vchan_fd = libxenvchan_fd_for_select(ctrl->xenvchan); 139 | struct pollfd fds[] = { 140 | { .fd = vchan_fd, .events = POLLIN, .revents = 0 }, 141 | }; 142 | switch (poll(fds, 1, 10000)) { 143 | case 0: 144 | if (!libvchan__check_domain_alive(ctrl->xc_handle, ctrl->remote_domain)) 145 | return -1; 146 | break; 147 | case 1: 148 | /* break the loop */ 149 | ret = -1; 150 | break; 151 | default: 152 | if (errno == EINTR) 153 | break; 154 | perror("poll"); 155 | return -1; 156 | } 157 | } 158 | } 159 | ret = libxenvchan_wait(ctrl->xenvchan); 160 | if (ctrl->xs_path) { 161 | xs_transaction_t trans; 162 | char *xs_dir_path, *last_slash; 163 | char **dir_list; 164 | unsigned int dir_size; 165 | /* remove xenstore entry at first client connection */ 166 | xs = xs_open(0); 167 | if (xs) { 168 | /* If xenstore connection failed just do not remove entries, but do 169 | * not abort whole function, especially still free the memory. 170 | * 171 | * If that was the last connection waiting to that domain, 172 | * remove the whole directory. Use transaction to avoid race 173 | * condition. 174 | */ 175 | xs_dir_path = strdup(ctrl->xs_path); 176 | /* cut last directory component */ 177 | last_slash = strrchr(xs_dir_path, '/'); 178 | if (last_slash) 179 | *last_slash = '\0'; 180 | do { 181 | trans = xs_transaction_start(xs); 182 | if (trans == XBT_NULL) { 183 | perror("xs_transaction_start"); 184 | break; 185 | } 186 | xs_rm(xs, trans, ctrl->xs_path); 187 | dir_list = xs_directory(xs, trans, xs_dir_path, &dir_size); 188 | if (dir_list && dir_size == 0) { 189 | /* that was the last entry, remove the whole directory */ 190 | xs_rm(xs, trans, xs_dir_path); 191 | } 192 | if (dir_list) 193 | free(dir_list); 194 | } while (!xs_transaction_end(xs, trans, 0) && errno == EAGAIN); 195 | free(xs_dir_path); 196 | xs_close(xs); 197 | } 198 | free(ctrl->xs_path); 199 | ctrl->xs_path = NULL; 200 | } 201 | return ret; 202 | } 203 | 204 | void libvchan_close(libvchan_t *ctrl) { 205 | struct xs_handle *xs; 206 | 207 | if (ctrl->xenvchan) 208 | libxenvchan_close(ctrl->xenvchan); 209 | if (ctrl->xenvchan && ctrl->xs_path) { 210 | /* remove server xenstore entry in case of no client connected */ 211 | xs = xs_open(0); 212 | if (xs) { 213 | /* if xenstore connection failed just do not remove entries, but do 214 | * not abort whole function, especially still free the memory 215 | */ 216 | xs_rm(xs, 0, ctrl->xs_path); 217 | xs_close(xs); 218 | } 219 | free(ctrl->xs_path); 220 | } 221 | /* this releases watches too */ 222 | if (ctrl->xs) 223 | xs_close(ctrl->xs); 224 | if (ctrl->xc_handle) 225 | xc_interface_close(ctrl->xc_handle); 226 | free(ctrl); 227 | } 228 | 229 | EVTCHN libvchan_fd_for_select(libvchan_t *ctrl) { 230 | if (!ctrl->xenvchan) { 231 | errno = EAGAIN; 232 | return -1; 233 | } 234 | return libxenvchan_fd_for_select(ctrl->xenvchan); 235 | } 236 | 237 | int libvchan_data_ready(libvchan_t *ctrl) { 238 | if (!ctrl->xenvchan) 239 | return 0; 240 | return libxenvchan_data_ready(ctrl->xenvchan); 241 | } 242 | 243 | int libvchan_buffer_space(libvchan_t *ctrl) { 244 | if (!ctrl->xenvchan) 245 | return 0; 246 | return libxenvchan_buffer_space(ctrl->xenvchan); 247 | } 248 | 249 | int libvchan_is_open(libvchan_t *ctrl) { 250 | int ret; 251 | struct evtchn_status evst; 252 | 253 | if (!ctrl->xenvchan) 254 | return VCHAN_WAITING; 255 | 256 | ret = libxenvchan_is_open(ctrl->xenvchan); 257 | if (ret == 2) { 258 | if (!libvchan__check_domain_alive(ctrl->xc_handle, ctrl->remote_domain)) 259 | return VCHAN_DISCONNECTED; 260 | return VCHAN_WAITING; 261 | } 262 | if (!ret) 263 | return VCHAN_DISCONNECTED; 264 | /* slow check in case of domain destroy */ 265 | evst.port = ctrl->xenvchan->event_port; 266 | evst.dom = DOMID_SELF; 267 | if (xc_evtchn_status(ctrl->xc_handle, &evst)) { 268 | perror("xc_evtchn_status"); 269 | return VCHAN_DISCONNECTED; 270 | } 271 | if (evst.status != EVTCHNSTAT_interdomain) { 272 | if (!ctrl->xenvchan->is_server) 273 | ctrl->xenvchan->ring->srv_live = 0; 274 | return VCHAN_DISCONNECTED; 275 | } 276 | return VCHAN_CONNECTED; 277 | } 278 | -------------------------------------------------------------------------------- /vchan/libvchan.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The Qubes OS Project, http://www.qubes-os.org 3 | * 4 | * Copyright (C) 2010 Rafal Wojtczuk 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | * 20 | */ 21 | 22 | #ifndef LIBVCHAN_H 23 | #define LIBVCHAN_H 24 | 25 | #include 26 | #include 27 | #include 28 | typedef int EVTCHN; 29 | 30 | /* config vchan features */ 31 | #ifdef CONFIG_STUBDOM 32 | #define ASYNC_INIT 33 | #endif /* CONFIG_STUBDOM */ 34 | 35 | /* return values from libvchan_is_open */ 36 | /* remote disconnected or remote domain dead */ 37 | #define VCHAN_DISCONNECTED 0 38 | /* connected */ 39 | #define VCHAN_CONNECTED 1 40 | /* vchan initialized, waiting for client to connect, or server to appear */ 41 | #define VCHAN_WAITING 2 42 | 43 | struct libvchan; 44 | typedef struct libvchan libvchan_t; 45 | 46 | libvchan_t *libvchan_server_init(int domain, int port, size_t read_min, size_t write_min); 47 | 48 | libvchan_t *libvchan_client_init(int domain, int port); 49 | 50 | /* An alternative path for client connection: 51 | * 1. Call libvchan_client_init_async(). 52 | * 2. Wait for watch_fd to become readable. 53 | * 3. When readable, call libvchan_client_init_async_finish(). 54 | * 55 | * Repeat steps 2-3 until libvchan_client_init_async_finish returns 0. Abort on 56 | * negative values (error). 57 | * If connection attempt failed or should be aborted, call libvchan_close() to 58 | * clean up. 59 | */ 60 | libvchan_t *libvchan_client_init_async(int domain, int port, EVTCHN *watch_fd); 61 | int libvchan_client_init_async_finish(libvchan_t *ctrl, bool blocking); 62 | 63 | int libvchan_write(libvchan_t *ctrl, const void *data, size_t size); 64 | int libvchan_send(libvchan_t *ctrl, const void *data, size_t size); 65 | int libvchan_read(libvchan_t *ctrl, void *data, size_t size); 66 | int libvchan_recv(libvchan_t *ctrl, void *data, size_t size); 67 | int libvchan_wait(libvchan_t *ctrl); 68 | void libvchan_close(libvchan_t *ctrl); 69 | EVTCHN libvchan_fd_for_select(libvchan_t *ctrl); 70 | int libvchan_is_open(libvchan_t *ctrl); 71 | 72 | int libvchan_data_ready(libvchan_t *ctrl); 73 | int libvchan_buffer_space(libvchan_t *ctrl); 74 | /* Must be called only after successful libvchan_*_init(). When using 75 | * libvchan_client_init_async(), prefer using blocking parameter to 76 | * libvchan_client_init_async_finish() instead. 77 | */ 78 | void libvchan_set_blocking(libvchan_t *ctrl, bool blocking); 79 | 80 | #endif /* LIBVCHAN_H */ 81 | -------------------------------------------------------------------------------- /vchan/libvchan_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The Qubes OS Project, http://www.qubes-os.org 3 | * 4 | * Copyright (C) 2013 Marek Marczykowski 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | * 20 | */ 21 | 22 | #ifndef LIBVCHAN_PRIVATE_H 23 | #define LIBVCHAN_PRIVATE_H 24 | 25 | #include 26 | 27 | struct libvchan { 28 | struct libxenvchan *xenvchan; 29 | /* 30 | * server: path to be removed when client connects, 31 | * client: path currently watched, for async init 32 | */ 33 | char *xs_path; 34 | int remote_domain; 35 | int local_domain; 36 | int port; 37 | xc_interface *xc_handle; 38 | struct xs_handle *xs; 39 | }; 40 | 41 | int libvchan__check_domain_alive(xc_interface *xc_handle, int dom); 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /vchan/vchan-xen.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@PREFIX@ 2 | exec_prefix=${prefix} 3 | includedir=@INCLUDEDIR@ 4 | libdir=@LIBDIR@ 5 | backend_vmm=xen 6 | 7 | Name: vchan-xen 8 | Description: The vchan communication library 9 | Version: @VERSION@ 10 | Cflags: -I${includedir}/vchan-xen 11 | Libs: -L${libdir} -lvchan-xen 12 | -------------------------------------------------------------------------------- /version: -------------------------------------------------------------------------------- 1 | 4.2.7 2 | -------------------------------------------------------------------------------- /windows/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QubesOS/qubes-core-vchan-xen/b39c9a853f05a7789f8989cd83e824cde981d56b/windows/.gitignore -------------------------------------------------------------------------------- /windows/README.md: -------------------------------------------------------------------------------- 1 | # `libvchan` implementation for Windows/Xen. 2 | 3 | ## Local command-line build on Windows 4 | 5 | ### Prerequisites 6 | 7 | - Microsoft EWDK iso mounted as a drive 8 | - `qubes-builderv2` 9 | - `powershell-yaml` PowerShell package (run `powershell -command Install-Package powershell-yaml` as admin) 10 | (TODO: provide offline installer for this) 11 | - `vmm-xen-windows-pvdrivers` built with the same `output_dir` as below 12 | 13 | ### Build 14 | 15 | - run `powershell qubes-builderv2\qubesbuilder\plugins\build_windows\scripts\local\build.ps1 src_dir output_dir Release|Debug` 16 | -------------------------------------------------------------------------------- /windows/include/.gitignore: -------------------------------------------------------------------------------- 1 | /qwt_version.h 2 | -------------------------------------------------------------------------------- /windows/include/libvchan.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The Qubes OS Project, http://www.qubes-os.org 3 | * 4 | * Copyright (C) 2010 Rafal Wojtczuk 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | * 20 | */ 21 | 22 | #ifndef _LIBVCHAN_H 23 | #define _LIBVCHAN_H 24 | 25 | #include 26 | typedef HANDLE EVTCHN; 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #ifdef LIBVCHAN_EXPORTS 33 | # define LIBVCHAN_API __declspec(dllexport) 34 | #else 35 | # define LIBVCHAN_API __declspec(dllimport) 36 | #endif 37 | 38 | /* config vchan features */ 39 | #define QREXEC_RING_V2 40 | #define ASYNC_INIT 41 | 42 | #ifdef CONFIG_STUBDOM 43 | #define ASYNC_INIT 44 | #endif /* CONFIG_STUBDOM */ 45 | 46 | /* return values from libvchan_is_open */ 47 | /* remote disconnected or remote domain dead */ 48 | #define VCHAN_DISCONNECTED 0 49 | /* connected */ 50 | #define VCHAN_CONNECTED 1 51 | /* vchan server initialized, waiting for client to connect */ 52 | #define VCHAN_WAITING 2 53 | 54 | struct libvchan; 55 | typedef struct libvchan libvchan_t; 56 | 57 | typedef void libvchan_logger_t(IN int logLevel, IN const char *function, IN const WCHAR *format, IN va_list args); 58 | 59 | /* Log level ranges from 1 (most severe) to 5 (least), 0 = use default (3) */ 60 | LIBVCHAN_API 61 | void libvchan_register_logger(libvchan_logger_t *logger, int log_level); 62 | 63 | /* 64 | Note: libvchan_*_init sets last error to ERROR_NOT_SUPPORTED if 65 | the xeniface device is not available. The caller can potentially 66 | wait for xeniface to become active in that case (this can happen 67 | after the first reboot after pvdrivers installation, xeniface takes 68 | a while to load). 69 | */ 70 | 71 | LIBVCHAN_API 72 | libvchan_t *libvchan_server_init(int domain, int port, size_t read_min, size_t write_min); 73 | 74 | LIBVCHAN_API 75 | libvchan_t *libvchan_client_init(int domain, int port); 76 | 77 | LIBVCHAN_API 78 | int libvchan_write(libvchan_t *ctrl, const void *data, size_t size); 79 | 80 | LIBVCHAN_API 81 | int libvchan_send(libvchan_t *ctrl, const void *data, size_t size); 82 | 83 | LIBVCHAN_API 84 | int libvchan_read(libvchan_t *ctrl, void *data, size_t size); 85 | 86 | LIBVCHAN_API 87 | int libvchan_recv(libvchan_t *ctrl, void *data, size_t size); 88 | 89 | LIBVCHAN_API 90 | int libvchan_wait(libvchan_t *ctrl); 91 | 92 | // server: if waiting manually instead of using libvchan_wait() 93 | // this needs to be called after a client connected to remove the xenstore entry 94 | LIBVCHAN_API 95 | void libvchan_cleanup(libvchan_t* ctrl); 96 | 97 | LIBVCHAN_API 98 | void libvchan_close(libvchan_t *ctrl); 99 | 100 | LIBVCHAN_API 101 | EVTCHN libvchan_fd_for_select(libvchan_t *ctrl); 102 | 103 | LIBVCHAN_API 104 | int libvchan_is_open(libvchan_t *ctrl); 105 | 106 | LIBVCHAN_API 107 | int libvchan_data_ready(libvchan_t *ctrl); 108 | 109 | LIBVCHAN_API 110 | int libvchan_buffer_space(libvchan_t *ctrl); 111 | 112 | /* TODO: 113 | 114 | LIBVCHAN_API 115 | libvchan_t *libvchan_client_init_async(int domain, int port, EVTCHN *watch_fd); 116 | 117 | LIBVCHAN_API 118 | int libvchan_client_init_async_finish(libvchan_t *ctrl); 119 | 120 | LIBVCHAN_API 121 | void libvchan_client_init_async_cancel(libvchan_t *ctrl); 122 | */ 123 | 124 | #ifdef __cplusplus 125 | } 126 | #endif 127 | 128 | #endif /* _LIBVCHAN_H */ 129 | -------------------------------------------------------------------------------- /windows/set_version.ps1: -------------------------------------------------------------------------------- 1 | function GenerateVersionHeader { 2 | param( 3 | [Parameter(Mandatory)] [string]$in, 4 | [Parameter(Mandatory)] [string]$out 5 | ) 6 | $version = Get-Content $in 7 | # qubes version has 3 parts, windows needs 4 8 | $version += ".0" 9 | $version_str = "`"" + $version + "`"" 10 | $version = %{$version -replace "\.", ","} 11 | $hdr = "#define QWT_FILEVERSION " + $version + "`n" 12 | $hdr += "#define QWT_FILEVERSION_STR " + $version_str + "`n" 13 | $hdr += "#define QWT_PRODUCTVERSION QWT_FILEVERSION`n" 14 | $hdr += "#define QWT_PRODUCTVERSION_STR QWT_FILEVERSION_STR`n" 15 | Set-Content -Path $out $hdr 16 | } 17 | 18 | GenerateVersionHeader $args[0] $args[1] 19 | -------------------------------------------------------------------------------- /windows/src/dllmain.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | BOOL APIENTRY DllMain(HMODULE hModule, 4 | DWORD ul_reason_for_call, 5 | LPVOID lpReserved 6 | ) 7 | { 8 | switch (ul_reason_for_call) 9 | { 10 | case DLL_PROCESS_ATTACH: 11 | case DLL_THREAD_ATTACH: 12 | case DLL_THREAD_DETACH: 13 | case DLL_PROCESS_DETACH: 14 | break; 15 | } 16 | return TRUE; 17 | } 18 | -------------------------------------------------------------------------------- /windows/src/init.c: -------------------------------------------------------------------------------- 1 | /* 2 | * The Qubes OS Project, http://www.qubes-os.org 3 | * 4 | * Copyright (C) 2010 Rafal Wojtczuk 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | * 20 | */ 21 | #define _CRT_SECURE_NO_WARNINGS 22 | #define LIBVCHAN_EXPORTS 23 | 24 | #include 25 | #include 26 | #include 27 | #include "libvchan.h" 28 | #include "libvchan_private.h" 29 | 30 | // global state since we want it to work before the control structure is initialized 31 | static XENCONTROL_LOGGER *g_logger = NULL; 32 | static XENCONTROL_LOG_LEVEL g_log_level = XLL_INFO; 33 | 34 | void libvchan_register_logger(libvchan_logger_t *logger, int log_level) 35 | { 36 | if (!logger) 37 | return; 38 | 39 | g_logger = (XENCONTROL_LOGGER*)logger; 40 | 41 | if (log_level != 0) 42 | g_log_level = log_level; 43 | } 44 | 45 | void _Log(XENCONTROL_LOG_LEVEL logLevel, LPCSTR function, PWCHAR format, ...) { 46 | va_list args; 47 | 48 | if (!g_logger) 49 | return; 50 | 51 | if (logLevel > g_log_level) 52 | return; 53 | 54 | va_start(args, format); 55 | g_logger(logLevel, function, format, args); 56 | va_end(args); 57 | } 58 | 59 | libvchan_t *libvchan_server_init(int domain, int port, size_t read_min, size_t write_min) { 60 | char xs_path[255]; 61 | libvchan_t *ctrl; 62 | 63 | ctrl = malloc(sizeof(*ctrl)); 64 | if (!ctrl) 65 | return NULL; 66 | 67 | snprintf(xs_path, sizeof(xs_path), "data/vchan/%d/%d", domain, port); 68 | ctrl->xenvchan = libxenvchan_server_init(g_logger, domain, xs_path, read_min, write_min, g_log_level); 69 | if (!ctrl->xenvchan) { 70 | Log(XLL_ERROR, "libxenvchan_server_init failed"); 71 | free(ctrl); 72 | // The above sets last error to ERROR_NOT_SUPPORTED if xeniface 73 | // is not loaded, see below for more info. 74 | return NULL; 75 | } 76 | 77 | ctrl->xs_path = _strdup(xs_path); 78 | ctrl->xenvchan->blocking = 1; 79 | ctrl->remote_domain = domain; 80 | Log(XLL_DEBUG, "ctrl %p, xenvchan %p, path %S", ctrl, ctrl->xenvchan, ctrl->xs_path); 81 | return ctrl; 82 | } 83 | 84 | libvchan_t *libvchan_client_init(int domain, int port) { 85 | char xs_path[255]; 86 | char xs_path_watch[255]; 87 | libvchan_t *ctrl = NULL; 88 | PXENCONTROL_CONTEXT xc_handle = NULL; 89 | char own_domid[16]; 90 | DWORD status; 91 | HANDLE path_watch_event = NULL; 92 | PVOID path_watch_handle = NULL; 93 | 94 | if (ERROR_SUCCESS != XcOpen(g_logger, &xc_handle)) { 95 | Log(XLL_ERROR, "opening xen device failed"); 96 | /* 97 | This error signifies that xeniface is not available. 98 | We need to return a well-defined code so the caller can potentially 99 | wait for xeniface to become active (this can happen after the first 100 | reboot after pvdrivers installation, it takes a while to load). 101 | */ 102 | SetLastError(ERROR_NOT_SUPPORTED); 103 | goto fail; 104 | } 105 | 106 | XcSetLogLevel(xc_handle, g_log_level); 107 | 108 | /* wait for server to appear */ 109 | status = XcStoreRead(xc_handle, "domid", sizeof(own_domid), own_domid); 110 | if (status != ERROR_SUCCESS) { 111 | Log(XLL_ERROR, "reading domid from xenstore failed: 0x%x", status); 112 | goto fail; 113 | } 114 | 115 | if (atoi(own_domid) == domain) { 116 | Log(XLL_ERROR, "Loopback vchan connection not supported"); 117 | goto fail; 118 | } 119 | 120 | path_watch_event = CreateEvent(NULL, FALSE, FALSE, NULL); 121 | if (!path_watch_event) { 122 | Log(XLL_ERROR, "CreateEvent(xs watch) failed: 0x%x", GetLastError()); 123 | goto fail; 124 | } 125 | 126 | snprintf(xs_path, sizeof(xs_path), "/local/domain/%d/data/vchan/%s/%d", domain, own_domid, port); 127 | /* watch on this key as we might not have access to the whole directory */ 128 | snprintf(xs_path_watch, sizeof(xs_path_watch), "%s/event-channel", xs_path); 129 | 130 | Log(XLL_DEBUG, "path: %S", xs_path); 131 | status = XcStoreAddWatch(xc_handle, xs_path_watch, path_watch_event, &path_watch_handle); 132 | if (status != ERROR_SUCCESS) { 133 | Log(XLL_ERROR, "adding xenstore watch (%S) failed: 0x%x", xs_path_watch, status); 134 | goto fail; 135 | } 136 | 137 | // xenstore daemon always signals the watch immediately after creation 138 | status = WaitForSingleObject(path_watch_event, 500); 139 | if (status != WAIT_OBJECT_0) { 140 | Log(XLL_WARNING, "Wait for xenstore (1) failed: 0x%x", status); 141 | // don't fail completely yet, if we can read the store values we're ok 142 | } 143 | 144 | // test if the store entry exists; if not - wait a second time 145 | char buf[64]; 146 | if (XcStoreRead(xc_handle, xs_path_watch, sizeof(buf), buf) != ERROR_SUCCESS) { 147 | status = WaitForSingleObject(path_watch_event, 500); 148 | if (status != WAIT_OBJECT_0) { 149 | Log(XLL_WARNING, "Wait for xenstore (2) failed: 0x%x", status); 150 | } 151 | } 152 | 153 | XcStoreRemoveWatch(xc_handle, path_watch_handle); 154 | path_watch_handle = 0; 155 | CloseHandle(path_watch_event); 156 | path_watch_event = NULL; 157 | 158 | ctrl = malloc(sizeof(*ctrl)); 159 | if (!ctrl) 160 | goto fail; 161 | 162 | ctrl->xs_path = NULL; 163 | ctrl->xenvchan = libxenvchan_client_init(g_logger, domain, xs_path, g_log_level); 164 | if (!ctrl->xenvchan) { 165 | Log(XLL_ERROR, "libxenvchan_client_init(%u, %S) failed", domain, xs_path); 166 | goto fail; 167 | } 168 | 169 | ctrl->xenvchan->blocking = 1; 170 | // notify server - xc handle must be the one that xenvchan opened since we use event channel that was allocated using that handle 171 | XcEvtchnNotify(ctrl->xenvchan->xc, ctrl->xenvchan->event_port); 172 | ctrl->remote_domain = domain; 173 | XcClose(xc_handle); 174 | 175 | Log(XLL_DEBUG, "ctrl %p, xenvchan %p", ctrl, ctrl->xenvchan); 176 | return ctrl; 177 | 178 | fail: 179 | if (path_watch_handle) 180 | XcStoreRemoveWatch(xc_handle, path_watch_handle); 181 | if (path_watch_event) 182 | CloseHandle(path_watch_event); 183 | if (xc_handle) 184 | XcClose(xc_handle); 185 | if (ctrl) 186 | free(ctrl); 187 | return NULL; 188 | } 189 | -------------------------------------------------------------------------------- /windows/src/io.c: -------------------------------------------------------------------------------- 1 | /* 2 | * The Qubes OS Project, http://www.qubes-os.org 3 | * 4 | * Copyright (C) 2010 Rafal Wojtczuk 5 | * Copyright (C) 2013 Marek Marczykowski 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License 9 | * as published by the Free Software Foundation; either version 2 10 | * of the License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 | * 21 | */ 22 | #define LIBVCHAN_EXPORTS 23 | 24 | #include 25 | #include 26 | #include 27 | #include "libvchan.h" 28 | #include "libvchan_private.h" 29 | 30 | int libvchan__check_domain_alive(PXENCONTROL_CONTEXT xc_handle, int dom) { 31 | //DWORD ret, status; 32 | /* check if domain still alive */ 33 | /* xc_evtchn_status will return different error depending on 34 | * existence of "source" domain: 35 | * ESRCH - domain don't exists 36 | * EINVAL/EPERM - domain exsts but port is invalid / cannot check 37 | * its status 38 | */ 39 | 40 | //ret = EvtchnStatus(xc_handle, ~0, &status); 41 | return 1; 42 | } 43 | 44 | int libvchan_write(libvchan_t *ctrl, const void *data, size_t size) { 45 | return libxenvchan_write(ctrl->xenvchan, (char*)data, size); 46 | } 47 | 48 | int libvchan_send(libvchan_t *ctrl, const void *data, size_t size) { 49 | return libxenvchan_send(ctrl->xenvchan, (char*)data, size); 50 | } 51 | 52 | int libvchan_read(libvchan_t *ctrl, void *data, size_t size) { 53 | return libxenvchan_read(ctrl->xenvchan, (char*)data, size); 54 | } 55 | 56 | int libvchan_recv(libvchan_t *ctrl, void *data, size_t size) { 57 | return libxenvchan_recv(ctrl->xenvchan, (char*)data, size); 58 | } 59 | 60 | int libvchan_wait(libvchan_t *ctrl) { 61 | int ret = -2; /* invalid, so can be distinguished from real 62 | libxenvchan_wait return code */ 63 | #if 0 64 | if (ctrl->xenvchan->is_server && libxenvchan_is_open(ctrl->xenvchan) == 2) { 65 | /* In case of vchan server waiting for a client, we'll not receive any 66 | * notification if the remote domain dies before connecting. Because of 67 | * that, check periodically if remote domain is still alive while 68 | * waiting for a connection. Actually this doesn't cover all the cases 69 | * - if remote domain is still alive, but remote process dies before 70 | * connecting, we'll also not receive any notification. But this, in 71 | * most cases, can be solved by application using libvchan. 72 | * 73 | * During normal operation this shouldn't be long - in most cases vchan 74 | * client will connect almost instantly. So this sleep(10) loop will 75 | * not hurt. Alternativelly it could be implemented with 76 | * xs_watch("@releaseDomain"), but such approach will slow down most 77 | * common execution path (xs_open+xs_watch even if client connects 78 | * right away). 79 | */ 80 | while (ret == -2 && libxenvchan_is_open(ctrl->xenvchan) == 2) { 81 | fd_set rd_set; 82 | struct timeval tv = { 10, 0 }; 83 | int vchan_fd = libxenvchan_fd_for_select(ctrl->xenvchan); 84 | FD_ZERO(&rd_set); 85 | FD_SET(vchan_fd, &rd_set); 86 | switch (select(vchan_fd+1, &rd_set, NULL, NULL, &tv)) { 87 | case 0: 88 | if (!libvchan__check_domain_alive(ctrl->xc_handle, ctrl->remote_domain)) 89 | return -1; 90 | break; 91 | case 1: 92 | /* break the loop */ 93 | ret = -1; 94 | break; 95 | default: 96 | perror("select"); 97 | return -1; 98 | } 99 | } 100 | } 101 | #endif 102 | ret = libxenvchan_wait(ctrl->xenvchan); 103 | libvchan_cleanup(ctrl); 104 | return ret; 105 | } 106 | 107 | void libvchan_cleanup(libvchan_t* ctrl) { 108 | if (ctrl->xs_path) { 109 | Log(XLL_DEBUG, "removing xs path %S", ctrl->xs_path); 110 | /* remove xenstore entry at first client connection */ 111 | XcStoreRemove(ctrl->xenvchan->xc, ctrl->xs_path); 112 | free(ctrl->xs_path); 113 | ctrl->xs_path = NULL; 114 | } 115 | } 116 | 117 | void libvchan_close(libvchan_t *ctrl) { 118 | 119 | if (!ctrl) 120 | return; 121 | 122 | libvchan_cleanup(ctrl); 123 | libxenvchan_close(ctrl->xenvchan); 124 | free(ctrl); 125 | } 126 | 127 | EVTCHN libvchan_fd_for_select(libvchan_t *ctrl) { 128 | return libxenvchan_fd_for_select(ctrl->xenvchan); 129 | } 130 | 131 | int libvchan_data_ready(libvchan_t *ctrl) { 132 | return libxenvchan_data_ready(ctrl->xenvchan); 133 | } 134 | 135 | int libvchan_buffer_space(libvchan_t *ctrl) { 136 | return libxenvchan_buffer_space(ctrl->xenvchan); 137 | } 138 | 139 | int libvchan_is_open(libvchan_t *ctrl) { 140 | int ret; 141 | //struct evtchn_status evst; 142 | 143 | ret = libxenvchan_is_open(ctrl->xenvchan); 144 | if (ret == 2) { 145 | if (!libvchan__check_domain_alive(ctrl->xenvchan->xc, ctrl->remote_domain)) 146 | return VCHAN_DISCONNECTED; 147 | return VCHAN_WAITING; 148 | } 149 | 150 | if (!ret) 151 | return VCHAN_DISCONNECTED; 152 | #if 0 153 | /* slow check in case of domain destroy */ 154 | evst.port = ctrl->xenvchan->event_port; 155 | evst.dom = DOMID_SELF; 156 | if (xc_evtchn_status(ctrl->xc_handle, &evst)) { 157 | perror("xc_evtchn_status"); 158 | return VCHAN_DISCONNECTED; 159 | } 160 | if (evst.status != EVTCHNSTAT_interdomain) { 161 | if (!ctrl->xenvchan->is_server) 162 | ctrl->xenvchan->ring->srv_live = 0; 163 | return VCHAN_DISCONNECTED; 164 | } 165 | #endif 166 | return VCHAN_CONNECTED; 167 | } 168 | -------------------------------------------------------------------------------- /windows/src/libvchan_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The Qubes OS Project, http://www.qubes-os.org 3 | * 4 | * Copyright (C) 2013 Marek Marczykowski 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | * 20 | */ 21 | 22 | #ifndef _LIBVCHAN_PRIVATE_H 23 | #define _LIBVCHAN_PRIVATE_H 24 | 25 | #include 26 | 27 | #if _MSC_VER < 1900 28 | #define snprintf _snprintf 29 | #endif 30 | 31 | struct libvchan { 32 | struct libxenvchan *xenvchan; 33 | /* store path, which should be removed after client connect (server only) */ 34 | char *xs_path; 35 | int remote_domain; 36 | }; 37 | 38 | int libvchan__check_domain_alive(PXENCONTROL_CONTEXT xc_handle, int dom); 39 | void _Log(XENCONTROL_LOG_LEVEL logLevel, LPCSTR function, PWCHAR format, ...); 40 | 41 | #define Log(level, msg, ...) _Log(level, __FUNCTION__, L"(%p) " L##msg L"\n", ctrl, __VA_ARGS__) 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /windows/src/vchan-test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * The Qubes OS Project, http://www.qubes-os.org 3 | * 4 | * Copyright (C) 2010 Rafal Wojtczuk 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | * 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include "libvchan.h" 29 | 30 | #if defined(DEBUG) || defined(_DEBUG) || defined(DBG) 31 | #define Log(msg, ...) fprintf(stderr, __FUNCTION__ ": " msg "\n", __VA_ARGS__) 32 | #else 33 | #define Log(msg, ...) 34 | #endif 35 | 36 | #define perror(msg) fprintf(stderr, __FUNCTION__ ": " msg " failed: error 0x%x\n", GetLastError()) 37 | 38 | int libvchan_write_all(libvchan_t *ctrl, char *buf, int size) 39 | { 40 | int written = 0; 41 | int ret; 42 | 43 | while (written < size) 44 | { 45 | ret = libvchan_write(ctrl, buf + written, size - written); 46 | if (ret <= 0) 47 | { 48 | perror("write"); 49 | exit(1); 50 | } 51 | written += ret; 52 | } 53 | return size; 54 | } 55 | 56 | void write_all(HANDLE fd, char *buf, DWORD size) 57 | { 58 | DWORD written = 0; 59 | DWORD tx; 60 | 61 | while (written < size) 62 | { 63 | if (!WriteFile(fd, buf + written, size - written, &tx, NULL)) 64 | { 65 | perror("write"); 66 | exit(1); 67 | } 68 | written += tx; 69 | Log("stdout written %d, total %d", tx, written); 70 | } 71 | } 72 | 73 | void usage() 74 | { 75 | fprintf(stderr, "usage:\n\tnode server [read|write] domainid nodeid\n" 76 | "or\n" "\tnode client [read|write] domainid nodeid\n"); 77 | exit(1); 78 | } 79 | 80 | #define BUFSIZE 5000 81 | char buf[BUFSIZE]; 82 | 83 | void reader(libvchan_t *ctrl) 84 | { 85 | int size; 86 | HANDLE fd = GetStdHandle(STD_OUTPUT_HANDLE); 87 | 88 | while (1) 89 | { 90 | size = rand() % (BUFSIZE - 1) + 1; 91 | Log("reading %d", size); 92 | size = libvchan_read(ctrl, buf, size); 93 | Log("read %d", size); 94 | fprintf(stderr, "#"); 95 | 96 | if (size < 0) 97 | { 98 | perror("read vchan"); 99 | libvchan_close(ctrl); 100 | exit(1); 101 | } 102 | 103 | if (size == 0) 104 | break; 105 | 106 | write_all(fd, buf, size); 107 | } 108 | } 109 | 110 | void writer(libvchan_t *ctrl) 111 | { 112 | int size; 113 | HANDLE fd = GetStdHandle(STD_INPUT_HANDLE); 114 | DWORD tx; 115 | 116 | while (1) 117 | { 118 | size = rand() % (BUFSIZE - 1) + 1; 119 | if (!ReadFile(fd, buf, size, &tx, NULL)) 120 | { 121 | perror("read stdin"); 122 | libvchan_close(ctrl); 123 | exit(1); 124 | } 125 | 126 | Log("stdin read %d", tx); 127 | 128 | if (tx == 0) 129 | break; 130 | 131 | Log("writing %d", tx); 132 | size = libvchan_write_all(ctrl, buf, tx); 133 | Log("written %d", size); 134 | fprintf(stderr, "#"); 135 | 136 | if (size < 0) 137 | { 138 | perror("vchan write"); 139 | exit(1); 140 | } 141 | 142 | if (size == 0) 143 | { 144 | perror("write size=0?\n"); 145 | exit(1); 146 | } 147 | } 148 | } 149 | 150 | void XcLogger(int level, const CHAR *function, const WCHAR *format, va_list args) 151 | { 152 | WCHAR buf[1024]; 153 | StringCbVPrintfW(buf, sizeof(buf), format, args); 154 | fprintf(stderr, "[X] %s: %S\n", function, buf); 155 | } 156 | 157 | /** 158 | Simple libvchan application, both client and server. 159 | One side does writing, the other side does reading; both from 160 | standard input/output fds. 161 | */ 162 | int main(int argc, char **argv) 163 | { 164 | int seed = (int)time(0); 165 | libvchan_t *ctrl = 0; 166 | int wr = 0; 167 | 168 | if (argc < 4) 169 | usage(); 170 | 171 | if (!strcmp(argv[2], "read")) 172 | wr = 0; 173 | else if (!strcmp(argv[2], "write")) 174 | wr = 1; 175 | else 176 | usage(); 177 | 178 | libvchan_register_logger(XcLogger, XLL_DEBUG); 179 | 180 | if (!strcmp(argv[1], "server")) 181 | ctrl = libvchan_server_init(atoi(argv[3]), atoi(argv[4]), 1024, 1024); 182 | else if (!strcmp(argv[1], "client")) 183 | ctrl = libvchan_client_init(atoi(argv[3]), atoi(argv[4])); 184 | else 185 | usage(); 186 | 187 | if (!ctrl) 188 | { 189 | perror("libvchan_*_init"); 190 | exit(1); 191 | } 192 | 193 | srand(seed); 194 | fprintf(stderr, "seed=%d\n", seed); 195 | 196 | if (wr) 197 | writer(ctrl); 198 | else 199 | reader(ctrl); 200 | libvchan_close(ctrl); 201 | return 0; 202 | } 203 | -------------------------------------------------------------------------------- /windows/src/version.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #ifdef RC_INVOKED 3 | 4 | // qwt_version.h is generated during build by set_version.ps1 5 | // it contains definition of QWT_* macros 6 | #include "qwt_version.h" 7 | 8 | #if defined(DBG) || defined(DEBUG) || defined(_DEBUG) 9 | #define VER_DBG VS_FF_DEBUG 10 | #else 11 | #define VER_DBG 0 12 | #endif 13 | 14 | VS_VERSION_INFO VERSIONINFO 15 | FILEVERSION QWT_FILEVERSION 16 | PRODUCTVERSION QWT_PRODUCTVERSION 17 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 18 | FILEFLAGS VER_DBG 19 | FILEOS VOS_NT 20 | FILETYPE VFT_DLL 21 | BEGIN 22 | BLOCK "StringFileInfo" 23 | BEGIN 24 | BLOCK "000004B0" // LANG_NEUTRAL/SUBLANG_NEUTRAL, Unicode CP 25 | BEGIN 26 | VALUE "FileVersion", QWT_FILEVERSION_STR 27 | VALUE "ProductVersion", QWT_PRODUCTVERSION_STR 28 | VALUE "FileDescription", "Qubes vchan library" 29 | VALUE "ProductName", "Qubes Windows Tools" 30 | VALUE "CompanyName", "Invisible Things Lab" 31 | VALUE "LegalCopyright", "(C) Invisible Things Lab" 32 | END 33 | END 34 | BLOCK "VarFileInfo" 35 | BEGIN 36 | VALUE "Translation", 0x0000, 0x04B0 37 | END 38 | END 39 | #endif 40 | -------------------------------------------------------------------------------- /windows/vs2022/.gitignore: -------------------------------------------------------------------------------- 1 | /.vs 2 | /x64/ 3 | /tmp/ 4 | /**/*.user 5 | -------------------------------------------------------------------------------- /windows/vs2022/core-vchan-xen.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.6.33723.286 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libvchan", "libvchan\libvchan.vcxproj", "{D97E5DD6-FE7C-403A-8B4B-5EF885CB6409}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vchan-test", "vchan-test\vchan-test.vcxproj", "{1522B49F-EB25-43F0-B2FA-0E8550E0AD95}" 9 | ProjectSection(ProjectDependencies) = postProject 10 | {D97E5DD6-FE7C-403A-8B4B-5EF885CB6409} = {D97E5DD6-FE7C-403A-8B4B-5EF885CB6409} 11 | EndProjectSection 12 | EndProject 13 | Global 14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 15 | Debug|x64 = Debug|x64 16 | Release|x64 = Release|x64 17 | EndGlobalSection 18 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 19 | {D97E5DD6-FE7C-403A-8B4B-5EF885CB6409}.Debug|x64.ActiveCfg = Debug|x64 20 | {D97E5DD6-FE7C-403A-8B4B-5EF885CB6409}.Debug|x64.Build.0 = Debug|x64 21 | {D97E5DD6-FE7C-403A-8B4B-5EF885CB6409}.Release|x64.ActiveCfg = Release|x64 22 | {D97E5DD6-FE7C-403A-8B4B-5EF885CB6409}.Release|x64.Build.0 = Release|x64 23 | {1522B49F-EB25-43F0-B2FA-0E8550E0AD95}.Debug|x64.ActiveCfg = Debug|x64 24 | {1522B49F-EB25-43F0-B2FA-0E8550E0AD95}.Debug|x64.Build.0 = Debug|x64 25 | {1522B49F-EB25-43F0-B2FA-0E8550E0AD95}.Release|x64.ActiveCfg = Release|x64 26 | {1522B49F-EB25-43F0-B2FA-0E8550E0AD95}.Release|x64.Build.0 = Release|x64 27 | EndGlobalSection 28 | GlobalSection(SolutionProperties) = preSolution 29 | HideSolutionNode = FALSE 30 | EndGlobalSection 31 | GlobalSection(ExtensibilityGlobals) = postSolution 32 | SolutionGuid = {59BDF652-36EB-41FC-AB82-11AF6A761811} 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /windows/vs2022/libvchan/libvchan.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 16.0 27 | Win32Proj 28 | {d97e5dd6-fe7c-403a-8b4b-5ef885cb6409} 29 | libvchan 30 | 10.0 31 | 32 | 33 | 34 | DynamicLibrary 35 | true 36 | v143 37 | Unicode 38 | 39 | 40 | DynamicLibrary 41 | false 42 | v143 43 | true 44 | Unicode 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | $(SolutionDir)\tmp\$(ProjectName)\$(Platform)\$(Configuration)\ 63 | false 64 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\..\..\include;$(QUBES_INCLUDES) 65 | $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(QUBES_LIBS) 66 | $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ 67 | 68 | 69 | $(SolutionDir)\tmp\$(ProjectName)\$(Platform)\$(Configuration)\ 70 | false 71 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\..\..\include;$(QUBES_INCLUDES) 72 | $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(QUBES_LIBS) 73 | $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ 74 | 75 | 76 | 77 | Level3 78 | true 79 | _DEBUG;VCHAN_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 80 | true 81 | NotUsing 82 | 83 | 84 | ProgramDatabase 85 | 86 | 87 | Windows 88 | true 89 | false 90 | $(CoreLibraryDependencies);%(AdditionalDependencies);libxenvchan.lib;xencontrol.lib 91 | 92 | 93 | 94 | powershell $(ProjectDir)\..\..\set_version.ps1 $(ProjectDir)\..\..\..\version $(ProjectDir)\..\..\include\qwt_version.h 95 | Generate qwt_version.h 96 | 97 | 98 | 99 | 100 | Level3 101 | true 102 | true 103 | true 104 | NDEBUG;VCHAN_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 105 | true 106 | NotUsing 107 | 108 | 109 | 110 | 111 | Windows 112 | true 113 | true 114 | true 115 | false 116 | $(CoreLibraryDependencies);%(AdditionalDependencies);libxenvchan.lib;xencontrol.lib 117 | 118 | 119 | 120 | powershell $(ProjectDir)\..\..\set_version.ps1 $(ProjectDir)\..\..\..\version $(ProjectDir)\..\..\include\qwt_version.h 121 | Generate qwt_version.h 122 | 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /windows/vs2022/libvchan/libvchan.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | 26 | 27 | Source Files 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | 37 | 38 | Resource Files 39 | 40 | 41 | -------------------------------------------------------------------------------- /windows/vs2022/vchan-test/vchan-test.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | 15 | 16 | 17 | 16.0 18 | Win32Proj 19 | {1522b49f-eb25-43f0-b2fa-0e8550e0ad95} 20 | vchantest 21 | 10.0 22 | 23 | 24 | 25 | Application 26 | true 27 | v143 28 | Unicode 29 | 30 | 31 | Application 32 | false 33 | v143 34 | true 35 | Unicode 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | $(SolutionDir)\tmp\$(ProjectName)\$(Platform)\$(Configuration)\ 51 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\include;$(QUBES_INCLUDES) 52 | $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(ProjectDir)\..\$(Platform)\$(Configuration)\libvchan;$(QUBES_LIBS) 53 | false 54 | $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ 55 | 56 | 57 | $(SolutionDir)\tmp\$(ProjectName)\$(Platform)\$(Configuration)\ 58 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\include;$(QUBES_INCLUDES);$(EWDK_INCLUDE) 59 | $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(ProjectDir)\..\$(Platform)\$(Configuration)\libvchan;$(QUBES_LIBS) 60 | false 61 | $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ 62 | 63 | 64 | 65 | Level3 66 | true 67 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 68 | true 69 | ProgramDatabase 70 | 71 | 72 | 73 | 74 | Console 75 | true 76 | $(CoreLibraryDependencies);%(AdditionalDependencies);libvchan.lib 77 | 78 | 79 | 80 | 81 | 82 | Level3 83 | true 84 | true 85 | true 86 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 87 | true 88 | 89 | 90 | 91 | 92 | Console 93 | true 94 | true 95 | true 96 | $(CoreLibraryDependencies);%(AdditionalDependencies);libvchan.lib 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /windows/vs2022/vchan-test/vchan-test.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | --------------------------------------------------------------------------------