]> xenbits.xensource.com Git - pvdrivers/win/xenhid.git/commitdiff
Initial commit
authorOwen Smith <owen.smith@citrix.com>
Fri, 2 Jun 2017 13:43:31 +0000 (14:43 +0100)
committerPaul Durrant <paul.durrant@citrix.com>
Fri, 2 Jun 2017 13:43:31 +0000 (14:43 +0100)
Signed-off-by: Owen Smith <owen.smith@citrix.com>
44 files changed:
.gitignore [new file with mode: 0644]
BUILD.md [new file with mode: 0644]
INSTALL.md [new file with mode: 0644]
INTERFACES.md [new file with mode: 0644]
LICENSE [new file with mode: 0644]
MAINTAINERS [new file with mode: 0644]
README.md [new file with mode: 0644]
build.py [new file with mode: 0644]
clean.py [new file with mode: 0644]
include/hid_interface.h [new file with mode: 0644]
include/revision.h [new file with mode: 0644]
kdfiles.py [new file with mode: 0644]
msbuild.bat [new file with mode: 0644]
src/coinst/coinst.c [new file with mode: 0644]
src/coinst/xenhid_coinst.def [new file with mode: 0644]
src/xenhid.inf [new file with mode: 0644]
src/xenhid.pfx [new file with mode: 0644]
src/xenhid/assert.h [new file with mode: 0644]
src/xenhid/dbg_print.h [new file with mode: 0644]
src/xenhid/driver.c [new file with mode: 0644]
src/xenhid/driver.h [new file with mode: 0644]
src/xenhid/fdo.c [new file with mode: 0644]
src/xenhid/fdo.h [new file with mode: 0644]
src/xenhid/types.h [new file with mode: 0644]
src/xenhid/util.h [new file with mode: 0644]
src/xenhid/xenhid.rc [new file with mode: 0644]
vs2013/configs.props [new file with mode: 0644]
vs2013/package/package.vcxproj [new file with mode: 0644]
vs2013/package/package.vcxproj.user [new file with mode: 0644]
vs2013/targets.props [new file with mode: 0644]
vs2013/xenhid.sln [new file with mode: 0644]
vs2013/xenhid/xenhid.user [new file with mode: 0644]
vs2013/xenhid/xenhid.vcxproj [new file with mode: 0644]
vs2013/xenhid_coinst/xenhid_coinst.vcxproj [new file with mode: 0644]
vs2013/xenhid_coinst/xenhid_coinst.vcxproj.user [new file with mode: 0644]
vs2015/configs.props [new file with mode: 0644]
vs2015/package/package.vcxproj [new file with mode: 0644]
vs2015/package/package.vcxproj.user [new file with mode: 0644]
vs2015/targets.props [new file with mode: 0644]
vs2015/xenhid.sln [new file with mode: 0644]
vs2015/xenhid/xenhid.vcxproj [new file with mode: 0644]
vs2015/xenhid/xenhid.vcxproj.user [new file with mode: 0644]
vs2015/xenhid_coinst/xenhid_coinst.vcxproj [new file with mode: 0644]
vs2015/xenhid_coinst/xenhid_coinst.vcxproj.user [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..be0a8d1
--- /dev/null
@@ -0,0 +1,7 @@
+# Cscope/Tags
+/cscope.files
+/cscope.out
+/tags
+
+# Output
+/xenhid
diff --git a/BUILD.md b/BUILD.md
new file mode 100644 (file)
index 0000000..5353ac5
--- /dev/null
+++ b/BUILD.md
@@ -0,0 +1,45 @@
+Building the XenHid Package
+===========================
+
+First you'll need a device driver build environment for Windows 10.
+This means:
+
+*   Visual Studio 2015 (Any SKU, including Express or Community)
+*   Windows Driver Kit 10
+
+Install Visual Studio first (you only need install MFC for C++) and then
+the WDK. Set an environment variable called VS to the base of the Visual
+Studio Installation (e.g. C:\Program Files\Microsoft Visual Studio 14.0) and
+a variable called KIT to the base of the WDK
+(e.g. C:\Program Files\Windows Kits\10). Also set an environment variable
+called SYMBOL\_SERVER to point at a location where driver symbols can be
+stored. This can be local directory e.g. C:\Symbols.
+
+You will also need to acquire the DIFx re-distributable package from one
+of the older WDKs (as it appears not to be present in WDK10), so that the
+driver build can copy dpinst.exe into the output.
+Set the environment variable DPINST_REDIST to the base dpinst directory
+- the directory under which the x86 and x64 sub-directories containing
+dpinst.exe can be found
+(e.g. C:\Program Files (x86)\Windows Kits\8.1\Redist\DIFx\dpinst\EngMui)
+
+Next you'll need a 3.x version of python (which you can get from
+http://www.python.org). Make sure python.exe is somewhere on your default
+path.
+
+Now fire up a Command Prompt and navigate to the base of your git repository.
+At the prompt type:
+
+    build.py checked
+
+This will create a debug build of the driver. To create a non-debug build
+type:
+
+    build.py free
+
+Note that Static Driver Verifier is run by default as part of the build
+process. This can be very time consuming. If you don't want to run the
+verifier then you can add the 'nosdv' keyword to the end of your command
+e.g.:
+
+    build.py free nosdv
diff --git a/INSTALL.md b/INSTALL.md
new file mode 100644 (file)
index 0000000..601bf6c
--- /dev/null
@@ -0,0 +1,26 @@
+Installing XenHid
+=================
+
+It's important to note that the build scripts generate a driver which is
+*test signed*. This means that when the driver is installed on a 64-bit
+version of Windows you must enabled testsigning mode otherwise your system
+will fail signature verification checked on the next reboot.
+If you wish to install the test certificate on the target system then copy
+xenhid.pfx (which you'll find in the proj subdirectory) onto your system and
+use certmgr to install it. (It is not password protected).
+
+xenhid.sys binds to one of three devices which may be created by XenVkbd:
+
+1. XENVKBD\\VEN_XSC000&DEV_HID&REV_00000001
+2. XENVKBD\\VEN_XS0001&DEV_HID&REV_00000001
+3. XENVKBD\\VEN_XS0002&DEV_HID&REV_00000001
+
+The particular device present in your VM will be determined by the binding
+of the XenBus driver. The DeviceID of the PCI device to which it is bound is
+echoed in the VEN_ substring of the devices it creates. Hence only one of the
+above three variants will be present.
+
+To install the driver on your target system, copy the contents of the xenhid
+subdirectory onto the system, then navigate into the copy, to either the x86
+or x64 subdirectory (whichever is appropriate), and execute the copy of
+dpinst.exe you find there with Administrator privilege.
diff --git a/INTERFACES.md b/INTERFACES.md
new file mode 100644 (file)
index 0000000..077d889
--- /dev/null
@@ -0,0 +1,33 @@
+Interface Versions and PDO Revisions
+====================================
+
+It is important that introduction of a new API, introduction of a new
+version of an existing API or retirement of an old version of an API is
+managed carefully to avoid incompatibilities between clients and
+providers. The general API versioning policy is described below:
+
+Each distinct set of API versions exported by a bus driver maps to a PDO
+revision. The DeviceID of each PDO created will specify the latest
+revision supported and all others will be contained within the
+HardwareIDs and CompatibleIDs. When a new version of an API is added,
+a new PDO revision must be added. When a version of an API is removed
+then ALL revisions that API version maps to must be removed. The mapping
+of interface versions to PDO revisions is specified in the header file
+include/revision.h in the bus driver source repository.
+
+Whe introducing a new version of an interface in a bus driver it is good
+practice to continue to support the previous version so it is not
+necessary to simultaneously introduce a new PDO revision and retire a
+previous one that child drivers may still be binding to.
+Child drivers should, of course, always be built to use the latest
+interface versions (which can be copied from the include directory in the
+source repository of the bus driver providing them) but it may take
+some time to make the necessary changes and deploy new builds of child
+drivers and so some overlap is desirable.
+
+To try to avoid installation of a version of a bus driver that is
+incompatible with child drivers installed on a system. There is a check
+in the pre-install phase in the co-intaller which compares the
+MatchingDeviceId values for each child driver against the table in
+include/revision.h in the bus driver source to make sure that the
+matching revision number is present.
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..df521f1
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,29 @@
+Copyright (c) Citrix Systems Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms,
+with or without modification, are permitted provided
+that the following conditions are met:
+
+*   Redistributions of source code must retain the above
+    copyright notice, this list of conditions and the
+    following disclaimer.
+*   Redistributions in binary form must reproduce the above
+    copyright notice, this list of conditions and the
+    following disclaimer in the documentation and/or other
+    materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
diff --git a/MAINTAINERS b/MAINTAINERS
new file mode 100644 (file)
index 0000000..1b75114
--- /dev/null
@@ -0,0 +1,50 @@
+List of maintainers and how to submit changes
+=============================================
+
+If you wish to submit code, we recommend first reaching out to the maintainers,
+who will advise you on the precise procedure they wish to use.
+
+We also request you follow these basic guidelines:
+
+1.  Make sure you test your changes on both a 32- and 64-bit version of Windows.
+    (The more versions of Windows you can test on the better).
+
+2.  Make sure your changes do not introduce any new prefast warnings.
+
+3.  Make a patch available to the relevant maintainer in the list. Use 'diff -u'
+    to make the patch easy to merge. Be prepared to get your changes sent back
+    with seemingly silly requests about formatting and variable names. These
+    aren't as silly as they seem. One job the maintainers do is to keep things
+    looking the same.
+
+    NOTE that all source should have Unix line endings.
+
+    PLEASE see http://wiki.xen.org/wiki/Submitting_Xen_Patches for hints on how
+    to submit a patch in a suitable form. Whilst the PV driver source
+    repositories are distinct from the Xen Project hypervisor source, we will
+    follow the same general patch submission and review process.
+
+    PLEASE try to include any credit lines you want added with the  patch. It
+    avoids people being missed off by mistake and makes it easier to know who
+    wants adding and who doesn't.
+
+    PLEASE document known bugs. If it doesn't work for everything or does
+    something very odd once a month document it.
+
+    PLEASE remember that submissions must be made under the terms of the
+    "Developer's Certificate of Origin" (DCO) and should include a
+    Signed-off-by: line.
+
+4.  Make sure you have the right to submit any changes you make. If you do
+    changes at work you may find your employer owns the patches instead of
+    you.
+
+
+Maintainers List
+----------------
+
+* Paul Durrant <paul.durrant@citrix.com>
+
+* Ben Chalmers <ben.chalmers@citrix.com>
+
+* Owen Smith <owen.smith@citrix.com>
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..5b85e7d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,53 @@
+XenHid - The Xen Paravitual HID Minidriver for Windows
+======================================================
+
+The XenHid package consists of a single device driver:
+
+*    xenhid.sys is a driver which attaches to a virtual device created
+     by a bus driver (XenVkbd) and provides the specified HID interface.
+
+Quick Start Guide
+=================
+
+Building the driver
+-------------------
+
+See BUILD.md
+
+Installing the driver
+---------------------
+
+See INSTALL.md
+
+Driver Interfaces
+=================
+
+See INTERFACES.md
+
+Miscellaneous
+=============
+
+For convenience the source repository includes some other scripts:
+
+kdfiles.py
+----------
+
+This generates two files called kdfiles32.txt and kdfiles64.txt which can
+be used as map files for the .kdfiles WinDBG command.
+
+sdv.py
+------
+
+This runs Static Driver Verifier on the source.
+
+clean.py
+--------
+
+This removes any files not checked into the repository and not covered by
+the .gitignore file.
+
+get_xen_headers.py
+------------------
+
+This will import any necessary headers from a given tag of that Xen
+repository at git://xenbits.xen.org/xen.git.
diff --git a/build.py b/build.py
new file mode 100644 (file)
index 0000000..ec383e8
--- /dev/null
+++ b/build.py
@@ -0,0 +1,438 @@
+#!python -u
+
+import os, sys
+import datetime
+import re
+import glob
+import tarfile
+import subprocess
+import shutil
+import time
+
+def next_build_number():
+    try:
+        file = open('.build_number', 'r')
+        build_number = file.read()
+        file.close()
+    except IOError:
+        build_number = '0'
+
+    file = open('.build_number', 'w')
+    file.write(str(int(build_number) + 1))
+    file.close()
+
+    return build_number
+
+
+def make_header():
+    now = datetime.datetime.now()
+
+    file = open('include\\version.h', 'w')
+
+    file.write('#define VENDOR_NAME_STR\t\t"' + os.environ['VENDOR_NAME'] + '"\n')
+    file.write('#define VENDOR_PREFIX_STR\t"' + os.environ['VENDOR_PREFIX'] + '"\n')
+
+    if 'VENDOR_DEVICE_ID' in os.environ.keys():
+        file.write('#define VENDOR_DEVICE_ID_STR\t"' + os.environ['VENDOR_DEVICE_ID'] + '"\n')
+
+    file.write('#define PRODUCT_NAME_STR\t"' + os.environ['PRODUCT_NAME'] + '"\n')
+    file.write('\n')
+
+    file.write('#define MAJOR_VERSION\t\t' + os.environ['MAJOR_VERSION'] + '\n')
+    file.write('#define MAJOR_VERSION_STR\t"' + os.environ['MAJOR_VERSION'] + '"\n')
+    file.write('\n')
+
+    file.write('#define MINOR_VERSION\t\t' + os.environ['MINOR_VERSION'] + '\n')
+    file.write('#define MINOR_VERSION_STR\t"' + os.environ['MINOR_VERSION'] + '"\n')
+    file.write('\n')
+
+    file.write('#define MICRO_VERSION\t\t' + os.environ['MICRO_VERSION'] + '\n')
+    file.write('#define MICRO_VERSION_STR\t"' + os.environ['MICRO_VERSION'] + '"\n')
+    file.write('\n')
+
+    file.write('#define BUILD_NUMBER\t\t' + os.environ['BUILD_NUMBER'] + '\n')
+    file.write('#define BUILD_NUMBER_STR\t"' + os.environ['BUILD_NUMBER'] + '"\n')
+    file.write('\n')
+
+    file.write('#define YEAR\t\t\t' + str(now.year) + '\n')
+    file.write('#define YEAR_STR\t\t"' + str(now.year) + '"\n')
+    file.write('\n')
+
+    file.write('#define MONTH\t\t\t' + str(now.month) + '\n')
+    file.write('#define MONTH_STR\t\t"' + str(now.month) + '"\n')
+    file.write('\n')
+
+    file.write('#define DAY\t\t\t' + str(now.day) + '\n')
+    file.write('#define DAY_STR\t\t\t"' + str(now.day) + '"\n')
+    file.write('\n')
+
+    file.close()
+
+
+def copy_inf(vs, name):
+    src = open('src\\%s.inf' % name, 'r')
+    dst = open('%s\\%s.inf' % (vs, name), 'w')
+
+    for line in src:
+        line = re.sub('@MAJOR_VERSION@', os.environ['MAJOR_VERSION'], line)
+        line = re.sub('@MINOR_VERSION@', os.environ['MINOR_VERSION'], line)
+        line = re.sub('@MICRO_VERSION@', os.environ['MICRO_VERSION'], line)
+        line = re.sub('@BUILD_NUMBER@', os.environ['BUILD_NUMBER'], line)
+        line = re.sub('@VENDOR_NAME@', os.environ['VENDOR_NAME'], line)
+        line = re.sub('@VENDOR_PREFIX@', os.environ['VENDOR_PREFIX'], line)
+        line = re.sub('@PRODUCT_NAME@', os.environ['PRODUCT_NAME'], line)
+
+        if re.search('@VENDOR_DEVICE_ID@', line):
+            if 'VENDOR_DEVICE_ID' not in os.environ.keys():
+                continue
+            line = re.sub('@VENDOR_DEVICE_ID@', os.environ['VENDOR_DEVICE_ID'], line)
+
+        dst.write(line)
+
+    dst.close()
+    src.close()
+
+
+def get_expired_symbols(name, age = 30):
+    path = os.path.join(os.environ['SYMBOL_SERVER'], '000Admin\\history.txt')
+
+    try:
+        file = open(path, 'r')
+    except IOError:
+        return []
+
+    threshold = datetime.datetime.utcnow() - datetime.timedelta(days = age)
+
+    expired = []
+
+    for line in file:
+        item = line.split(',')
+
+        if (re.match('add', item[1])):
+            id = item[0]
+            date = item[3].split('/')
+            time = item[4].split(':')
+            tag = item[5].strip('"')
+
+            age = datetime.datetime(year = int(date[2]),
+                                    month = int(date[0]),
+                                    day = int(date[1]),
+                                    hour = int(time[0]),
+                                    minute = int(time[1]),
+                                    second = int(time[2]))
+            if (tag == name and age < threshold):
+                expired.append(id)
+
+        elif (re.match('del', item[1])):
+            id = item[2].rstrip()
+            try:
+                expired.remove(id)
+            except ValueError:
+                pass
+
+    file.close()
+
+    return expired
+
+
+def get_configuration(release, debug):
+    configuration = release
+
+    if debug:
+        configuration += ' Debug'
+    else:
+        configuration += ' Release'
+
+    return configuration
+
+
+def get_target_path(release, arch, debug, vs):
+    configuration = get_configuration(release, debug)
+    name = ''.join(configuration.split(' '))
+    target = { 'x86': os.sep.join([name, 'Win32']), 'x64': os.sep.join([name, 'x64']) }
+    target_path = os.sep.join([vs, target[arch]])
+
+    return target_path
+
+
+def shell(command, dir):
+    print(dir)
+    print(command)
+    sys.stdout.flush()
+
+    sub = subprocess.Popen(' '.join(command), cwd=dir,
+                           stdout=subprocess.PIPE,
+                           stderr=subprocess.STDOUT)
+
+    for line in sub.stdout:
+        print(line.decode(sys.getdefaultencoding()).rstrip())
+
+    sub.wait()
+
+    return sub.returncode
+
+
+class msbuild_failure(Exception):
+    def __init__(self, value):
+        self.value = value
+    def __str__(self):
+        return repr(self.value)
+
+def msbuild(platform, configuration, target, file, args, dir):
+    os.environ['PLATFORM'] = platform
+    os.environ['CONFIGURATION'] = configuration
+    os.environ['TARGET'] = target
+    os.environ['FILE'] = file
+    os.environ['EXTRA'] = args
+
+    bin = os.path.join(os.getcwd(), 'msbuild.bat')
+
+    status = shell([bin], dir)
+
+    if (status != 0):
+        raise msbuild_failure(configuration)
+
+
+def build_sln(name, release, arch, debug, vs):
+    configuration = get_configuration(release, debug)
+
+    if arch == 'x86':
+        platform = 'Win32'
+    elif arch == 'x64':
+        platform = 'x64'
+
+    cwd = os.getcwd()
+
+    msbuild(platform, configuration, 'Build', name + '.sln', '', vs)
+
+def copy_package(name, release, arch, debug, vs):
+    configuration = get_configuration(release, debug)
+
+    if arch == 'x86':
+        platform = 'Win32'
+    elif arch == 'x64':
+        platform = 'x64'
+
+    pattern = '/'.join([vs, ''.join(configuration.split(' ')), platform, 'package', '*'])
+    print('Copying package from %s' % pattern)
+
+    files = glob.glob(pattern)
+
+    dst = os.path.join(name, arch)
+
+    os.makedirs(dst, exist_ok=True)
+
+    for file in files:
+        new = shutil.copy(file, dst)
+        print(new)
+
+    print('')
+
+def remove_timestamps(path):
+    try:
+        os.unlink(path + '.orig')
+    except OSError:
+        pass
+
+    os.rename(path, path + '.orig')
+
+    src = open(path + '.orig', 'r')
+    dst = open(path, 'w')
+
+    for line in src:
+        if line.find('TimeStamp') == -1:
+            dst.write(line)
+
+    dst.close()
+    src.close()
+
+def run_sdv(name, dir, vs):
+    release = { 'vs2012':'Windows 8',
+                'vs2013':'Windows 8',
+                'vs2015':'Windows 10' }
+
+    configuration = get_configuration(release[vs], False)
+    platform = 'x64'
+
+    msbuild(platform, configuration, 'Build', name + '.vcxproj',
+            '', os.path.join(vs, name))
+
+    msbuild(platform, configuration, 'sdv', name + '.vcxproj',
+            '/p:Inputs="/clean"', os.path.join(vs, name))
+
+    msbuild(platform, configuration, 'sdv', name + '.vcxproj',
+            '/p:Inputs="/check:default.sdv"', os.path.join(vs, name))
+
+    path = [vs, name, 'sdv', 'SDV.DVL.xml']
+    remove_timestamps(os.path.join(*path))
+
+    msbuild(platform, configuration, 'dvl', name + '.vcxproj',
+            '', os.path.join(vs, name))
+
+    path = [vs, name, name + '.DVL.XML']
+    shutil.copy(os.path.join(*path), dir)
+
+    path = [vs, name, 'refine.sdv']
+    if os.path.isfile(os.path.join(*path)):
+        msbuild(platform, configuration, 'sdv', name + '.vcxproj',
+                '/p:Inputs=/refine', os.path.join(vs, name))
+
+
+def symstore_del(name, age):
+    symstore_path = [os.environ['KIT'], 'Debuggers']
+    if os.environ['PROCESSOR_ARCHITECTURE'] == 'x86':
+        symstore_path.append('x86')
+    else:
+        symstore_path.append('x64')
+    symstore_path.append('symstore.exe')
+
+    symstore = os.path.join(*symstore_path)
+
+    for id in get_expired_symbols(name, age):
+        command=['"' + symstore + '"']
+        command.append('del')
+        command.append('/i')
+        command.append(str(id))
+        command.append('/s')
+        command.append(os.environ['SYMBOL_SERVER'])
+
+        shell(command, None)
+
+
+def symstore_add(name, release, arch, debug, vs):
+    target_path = get_target_path(release, arch, debug, vs)
+
+    symstore_path = [os.environ['KIT'], 'Debuggers']
+    if os.environ['PROCESSOR_ARCHITECTURE'] == 'x86':
+        symstore_path.append('x86')
+    else:
+        symstore_path.append('x64')
+    symstore_path.append('symstore.exe')
+
+    symstore = os.path.join(*symstore_path)
+
+    version = '.'.join([os.environ['MAJOR_VERSION'],
+                        os.environ['MINOR_VERSION'],
+                        os.environ['MICRO_VERSION'],
+                        os.environ['BUILD_NUMBER']])
+
+    command=['"' + symstore + '"']
+    command.append('add')
+    command.append('/s')
+    command.append(os.environ['SYMBOL_SERVER'])
+    command.append('/r')
+    command.append('/f')
+    command.append('*.pdb')
+    command.append('/t')
+    command.append(name)
+    command.append('/v')
+    command.append(version)
+
+    shell(command, target_path)
+
+
+def manifest():
+    cmd = ['git', 'ls-tree', '-r', '--name-only', 'HEAD']
+
+    sub = subprocess.Popen(cmd, stdout=subprocess.PIPE)
+    output = sub.communicate()[0]
+    ret = sub.returncode
+
+    if ret != 0:
+        raise(Exception("Error %d in : %s" % (ret, cmd)))
+
+    return output.decode('utf-8')
+
+
+def archive(filename, files, tgz=False):
+    access='w'
+    if tgz:
+        access='w:gz'
+    tar = tarfile.open(filename, access)
+    for name in files :
+        try:
+            tar.add(name)
+        except:
+            pass
+    tar.close()
+
+
+def getVsVersion():
+    vsenv ={}
+    vars = subprocess.check_output([os.environ['VS']+'\\VC\\vcvarsall.bat',
+                                        '&&', 'set'],
+                                    shell=True)
+    for var in vars.splitlines():
+        k, _, v = map(str.strip, var.strip().decode('utf-8').partition('='))
+        if k.startswith('?'):
+            continue
+        vsenv[k] = v
+
+    mapping = { '11.0':'vs2012',
+                '12.0':'vs2013',
+                '14.0':'vs2015' }
+
+    return mapping[vsenv['VisualStudioVersion']]
+
+
+if __name__ == '__main__':
+    debug = { 'checked': True, 'free': False }
+    sdv = { 'nosdv': False, None: True }
+    driver = 'xenhid'
+    vs = getVsVersion()
+
+    if 'VENDOR_NAME' not in os.environ.keys():
+        os.environ['VENDOR_NAME'] = 'Xen Project'
+
+    if 'VENDOR_PREFIX' not in os.environ.keys():
+        os.environ['VENDOR_PREFIX'] = 'XP'
+
+    if 'PRODUCT_NAME' not in os.environ.keys():
+        os.environ['PRODUCT_NAME'] = 'Xen'
+
+    os.environ['MAJOR_VERSION'] = '9'
+    os.environ['MINOR_VERSION'] = '0'
+    os.environ['MICRO_VERSION'] = '0'
+
+    if 'BUILD_NUMBER' not in os.environ.keys():
+        os.environ['BUILD_NUMBER'] = next_build_number()
+
+    if 'GIT_REVISION' in os.environ.keys():
+        revision = open('revision', 'w')
+        print(os.environ['GIT_REVISION'], file=revision)
+        revision.close()
+
+    print("VENDOR_NAME\t\t'%s'" % os.environ['VENDOR_NAME'])
+    print("VENDOR_PREFIX\t\t'%s'" % os.environ['VENDOR_PREFIX'])
+    print("PRODUCT_NAME\t\t'%s'" % os.environ['PRODUCT_NAME'])
+    print("MAJOR_VERSION\t\t%s" % os.environ['MAJOR_VERSION'])
+    print("MINOR_VERSION\t\t%s" % os.environ['MINOR_VERSION'])
+    print("MICRO_VERSION\t\t%s" % os.environ['MICRO_VERSION'])
+    print("BUILD_NUMBER\t\t%s" % os.environ['BUILD_NUMBER'])
+    print()
+
+    make_header()
+    copy_inf(vs, driver)
+
+    symstore_del(driver, 30)
+
+    release = { 'vs2012':'Windows Vista',
+                'vs2013':'Windows 7',
+                'vs2015':'Windows 8' }
+
+    shutil.rmtree(driver, ignore_errors=True)
+
+    build_sln(driver, release[vs], 'x86', debug[sys.argv[1]], vs)
+    copy_package(driver, release[vs], 'x86', debug[sys.argv[1]], vs)
+
+    build_sln(driver, release[vs], 'x64', debug[sys.argv[1]], vs)
+    copy_package(driver, release[vs], 'x64', debug[sys.argv[1]], vs)
+
+    symstore_add(driver, release[vs], 'x86', debug[sys.argv[1]], vs)
+    symstore_add(driver, release[vs], 'x64', debug[sys.argv[1]], vs)
+
+    if len(sys.argv) <= 2 or sdv[sys.argv[2]]:
+        run_sdv('xenhid', driver, vs)
+
+    archive(driver + '\\source.tgz', manifest().splitlines(), tgz=True)
+    archive(driver + '.tar', [driver,'revision'])
diff --git a/clean.py b/clean.py
new file mode 100644 (file)
index 0000000..e3f3478
--- /dev/null
+++ b/clean.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+
+import os, sys, shutil
+
+if __name__ == '__main__':
+    file = os.popen('git status -u --porcelain')
+
+    for line in file:
+        item = line.split(' ')
+        if item[0] == '??':
+            path = ' '.join(item[1:]).rstrip()
+            print(path)
+            try:
+                if os.path.isfile(path):
+                    os.remove(path)
+                if os.path.isdir(path):
+                    shutil.rmtree(path)
+            except OSError:
+                None
+
+    file.close()
diff --git a/include/hid_interface.h b/include/hid_interface.h
new file mode 100644 (file)
index 0000000..08be5e0
--- /dev/null
@@ -0,0 +1,323 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, 
+ * with or without modification, are permitted provided 
+ * that the following conditions are met:
+ * 
+ * *   Redistributions of source code must retain the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer in the documentation and/or other 
+ *     materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE.
+ */
+
+/*! \file hid_interface.h
+    \brief XENHID HID Interface
+
+    This interface provides access to the PV network frontend
+*/
+
+#ifndef _XENHID_HID_INTERFACE_H
+#define _XENHID_HID_INTERFACE_H
+
+#ifndef _WINDLL
+
+/*! \typedef XENHID_HID_ACQUIRE
+    \brief Acquire a reference to the HID interface
+
+    \param Interface The interface header
+*/  
+typedef NTSTATUS
+(*XENHID_HID_ACQUIRE)(
+    IN  PINTERFACE  Interface
+    );
+
+/*! \typedef XENHID_HID_RELEASE
+    \brief Release a reference to the HID interface
+
+    \param Interface The interface header
+*/  
+typedef VOID
+(*XENHID_HID_RELEASE)(
+    IN  PINTERFACE  Interface
+    );
+
+/*! \typedef XENHID_HID_CALLBACK
+    \brief Provider to subscriber callback function
+
+    \param Argument An optional context argument passed to the callback
+    \param Buffer A HID report buffer to complete
+    \param Length The length of the \a Buffer
+*/
+typedef BOOLEAN
+(*XENHID_HID_CALLBACK)(
+    IN  PVOID       Argument OPTIONAL,
+    IN  PVOID       Buffer,
+    IN  ULONG       Length
+    );
+
+/*! \typedef XENHID_HID_ENABLE
+    \brief Enable the HID interface
+
+    All packets queued for transmit will be rejected and no packets will
+    be queued for receive until this method completes. 
+
+    \param Interface The interface header
+    \param Callback The subscriber's callback function
+    \param Argument An optional context argument passed to the callback
+*/
+typedef NTSTATUS
+(*XENHID_HID_ENABLE)(
+    IN  PINTERFACE          Interface,
+    IN  XENHID_HID_CALLBACK Callback,
+    IN  PVOID               Argument OPTIONAL
+    );
+
+/*! \typedef XENHID_HID_DISABLE
+    \brief Disable the HID interface
+
+    This method will not complete until any packets queued for receive
+    have been returned. Any packets queued for transmit may be aborted.
+
+    \param Interface The interface header
+*/
+typedef VOID
+(*XENHID_HID_DISABLE)(
+    IN  PINTERFACE  Interface
+    );
+
+/*! \typedef XENHID_HID_GET_DEVICE_ATTRIBUTES
+    \brief Get the HID Device Attributes structure
+
+*/
+typedef NTSTATUS
+(*XENHID_HID_GET_DEVICE_ATTRIBUTES)(
+    IN  PINTERFACE      Interface,
+    IN  PVOID           Buffer,
+    IN  ULONG           Length,
+    OUT PULONG          Returned
+    );
+
+/*! \typedef XENHID_HID_GET_DEVICE_DESCRIPTOR
+    \brief Get the HID Device Descriptor structure
+
+    \param Interface The interface header
+    \param Buffer The buffer to fill
+    \param Length The length of the buffer
+    \param Returned The number of bytes returned
+*/
+typedef NTSTATUS
+(*XENHID_HID_GET_DEVICE_DESCRIPTOR)(
+    IN  PINTERFACE      Interface,
+    IN  PVOID           Buffer,
+    IN  ULONG           Length,
+    OUT PULONG          Returned
+    );
+
+/*! \typedef XENHID_HID_GET_REPORT_DESCRIPTOR
+    \brief Get the HID Report Descriptor structure
+
+    \param Interface The interface header
+    \param Buffer The buffer to fill
+    \param Length The length of the buffer
+    \param Returned The number of bytes returned
+*/
+typedef NTSTATUS
+(*XENHID_HID_GET_REPORT_DESCRIPTOR)(
+    IN  PINTERFACE      Interface,
+    IN  PVOID           Buffer,
+    IN  ULONG           Length,
+    OUT PULONG          Returned
+    );
+
+/*! \typedef XENHID_HID_GET_STRING
+    \brief Get the HID Device Descriptor structure
+
+    \param Interface The interface header
+    \param Identifier The string identifier
+    \param Buffer The buffer to fill
+    \param Length The length of the buffer
+    \param Returned The number of bytes returned
+*/
+typedef NTSTATUS
+(*XENHID_HID_GET_STRING)(
+    IN  PINTERFACE      Interface,
+    IN  ULONG           Identifier,
+    IN  PVOID           Buffer,
+    IN  ULONG           Length,
+    OUT PULONG          Returned
+    );
+
+/*! \typedef XENHID_HID_GET_INDEXED_STRING
+    \brief Set the HID Device Descriptor structure
+
+    \param Interface The interface header
+    \param Index The index of the string
+    \param Buffer The buffer to fill
+    \param Length The length of the buffer
+    \param Returned The number of bytes returned
+*/
+typedef NTSTATUS
+(*XENHID_HID_GET_INDEXED_STRING)(
+    IN  PINTERFACE      Interface,
+    IN  ULONG           Index,
+    IN  PVOID           Buffer,
+    IN  ULONG           Length,
+    OUT PULONG          Returned
+    );
+
+/*! \typedef XENHID_HID_GET_FEATURE
+    \brief Get the feature
+
+    \param Interface The interface header
+    \param ReportId The report id to set
+    \param Buffer The report buffer
+    \param Length The length of the buffer
+    \param Returned The number of bytes returned
+*/
+typedef NTSTATUS
+(*XENHID_HID_GET_FEATURE)(
+    IN  PINTERFACE      Interface,
+    IN  ULONG           ReportId,
+    IN  PVOID           Buffer,
+    IN  ULONG           Length,
+    OUT PULONG          Returned
+    );
+
+/*! \typedef XENHID_HID_SET_FEATURE
+    \brief Set the feature report
+
+    \param Interface The interface header
+    \param ReportId The report id to set
+    \param Buffer The report buffer
+    \param Length The length of the buffer
+*/
+typedef NTSTATUS
+(*XENHID_HID_SET_FEATURE)(
+    IN  PINTERFACE      Interface,
+    IN  ULONG           ReportId,
+    IN  PVOID           Buffer,
+    IN  ULONG           Length
+    );
+
+/*! \typedef XENHID_HID_GET_INPUT_REPORT
+    \brief Get the input report
+
+    \param Interface The interface header
+    \param ReportId The report id to set
+    \param Buffer The report buffer
+    \param Length The length of the buffer
+    \param Returned The number of bytes returned
+*/
+typedef NTSTATUS
+(*XENHID_HID_GET_INPUT_REPORT)(
+    IN  PINTERFACE      Interface,
+    IN  ULONG           ReportId,
+    IN  PVOID           Buffer,
+    IN  ULONG           Length,
+    OUT PULONG          Returned
+    );
+
+/*! \typedef XENHID_HID_SET_OUTPUT_REPORT
+    \brief Set the output report
+
+    \param Interface The interface header
+    \param ReportId The report id to set
+    \param Buffer The write report buffer
+    \param Length The length of the buffer
+*/
+typedef NTSTATUS
+(*XENHID_HID_SET_OUTPUT_REPORT)(
+    IN  PINTERFACE      Interface,
+    IN  ULONG           ReportId,
+    IN  PVOID           Buffer,
+    IN  ULONG           Length
+    );
+
+/*! \typedef XENHID_HID_READ_REPORT
+    \brief Checks to see if any pending read reports
+           need completing. A single read report will be 
+           completed by calling the callback
+
+    \param Interface The interface header
+*/
+typedef VOID
+(*XENHID_HID_READ_REPORT)(
+    IN  PINTERFACE      Interface
+    );
+
+/*! \typedef XENHID_HID_WRITE_REPORT
+    \brief Set the output report
+
+    \param Interface The interface header
+    \param ReportId The report id to set
+    \param Buffer The write report buffer
+    \param Length The length of the buffer
+*/
+typedef NTSTATUS
+(*XENHID_HID_WRITE_REPORT)(
+    IN  PINTERFACE      Interface,
+    IN  ULONG           ReportId,
+    IN  PVOID           Buffer,
+    IN  ULONG           Length
+    );
+
+// {D215E1B5-8C38-420A-AEA6-02520DF3A621}\r
+DEFINE_GUID(GUID_XENHID_HID_INTERFACE,\r
+0xd215e1b5, 0x8c38, 0x420a, 0xae, 0xa6, 0x2, 0x52, 0xd, 0xf3, 0xa6, 0x21);\r
+
+/*! \struct _XENHID_HID_INTERFACE_V1
+    \brief HID interface version 1
+    \ingroup interfaces
+*/
+struct _XENHID_HID_INTERFACE_V1 {
+    INTERFACE                                       Interface;
+    XENHID_HID_ACQUIRE                              Acquire;
+    XENHID_HID_RELEASE                              Release;
+    XENHID_HID_ENABLE                               Enable;
+    XENHID_HID_DISABLE                              Disable;
+    XENHID_HID_GET_DEVICE_ATTRIBUTES                GetDeviceAttributes;
+    XENHID_HID_GET_DEVICE_DESCRIPTOR                GetDeviceDescriptor;
+    XENHID_HID_GET_REPORT_DESCRIPTOR                GetReportDescriptor;
+    XENHID_HID_GET_STRING                           GetString;
+    XENHID_HID_GET_INDEXED_STRING                   GetIndexedString;
+    XENHID_HID_GET_FEATURE                          GetFeature;
+    XENHID_HID_SET_FEATURE                          SetFeature;
+    XENHID_HID_GET_INPUT_REPORT                     GetInputReport;
+    XENHID_HID_SET_OUTPUT_REPORT                    SetOutputReport;
+    XENHID_HID_READ_REPORT                          ReadReport;
+    XENHID_HID_WRITE_REPORT                         WriteReport;
+};
+
+typedef struct _XENHID_HID_INTERFACE_V1 XENHID_HID_INTERFACE, *PXENHID_HID_INTERFACE;
+
+/*! \def XENHID_HID
+    \brief Macro at assist in method invocation
+*/
+#define XENHID_HID(_Method, _Interface, ...)    \
+    (_Interface)-> ## _Method((PINTERFACE)(_Interface), __VA_ARGS__)
+
+#endif  // _WINDLL
+
+#define XENHID_HID_INTERFACE_VERSION_MIN    1
+#define XENHID_HID_INTERFACE_VERSION_MAX    1
+
+#endif  // _XENHID_INTERFACE_H
diff --git a/include/revision.h b/include/revision.h
new file mode 100644 (file)
index 0000000..b30aee7
--- /dev/null
@@ -0,0 +1,45 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * *   Redistributions of source code must retain the above
+ *     copyright notice, this list of conditions and the
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the
+ *     following disclaimer in the documentation and/or other
+ *     materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _REVISION_H
+#define _REVISION_H
+
+// Key:
+// H  - XENHID_HID_INTERFACE
+
+//                    REVISION   H
+#define DEFINE_REVISION_TABLE           \
+    DEFINE_REVISION(0x0800000B,  1),    \
+    DEFINE_REVISION(0x0800000C,  1),    \
+    DEFINE_REVISION(0x0800000D,  1),    \
+    DEFINE_REVISION(0x09000000,  1)
+
+#endif  // _REVISION_H
diff --git a/kdfiles.py b/kdfiles.py
new file mode 100644 (file)
index 0000000..e77a403
--- /dev/null
@@ -0,0 +1,26 @@
+#!python -u
+
+import os, sys
+import subprocess
+import glob
+from pprint import pprint
+
+def regenerate_kdfiles(filename, arch, pkg, source):
+       cwd = os.getcwd()
+       file = open(filename, 'w')
+       os.chdir(os.path.join(pkg, arch))
+       drivers = glob.glob('*.sys')
+       pprint(drivers)
+       for driver in drivers:
+               file.write("map\n")
+               file.write('\SystemRoot\System32\drivers\\' + driver + '\n')
+               file.write(source + '\\' + pkg + '\\' + arch + '\\' + driver + '\n')
+               file.write('\n')
+       os.chdir(cwd)
+       file.close()
+
+if __name__ == '__main__':
+       pkg = 'xenhid'
+       source = os.getcwd()
+       regenerate_kdfiles('kdfiles32.txt', 'x86', pkg, source)
+       regenerate_kdfiles('kdfiles64.txt', 'x64', pkg, source)
diff --git a/msbuild.bat b/msbuild.bat
new file mode 100644 (file)
index 0000000..1b1fbc8
--- /dev/null
@@ -0,0 +1,8 @@
+call "%VS%\VC\vcvarsall.bat" x86
+@echo on
+msbuild.exe /m:1 /p:Configuration="%CONFIGURATION%" /p:Platform="%PLATFORM%" /t:"%TARGET%" %EXTRA% %FILE%
+if errorlevel 1 goto error
+exit 0
+
+:error
+exit 1
diff --git a/src/coinst/coinst.c b/src/coinst/coinst.c
new file mode 100644 (file)
index 0000000..a6e6a1a
--- /dev/null
@@ -0,0 +1,1314 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, 
+ * with or without modification, are permitted provided 
+ * that the following conditions are met:
+ * 
+ * *   Redistributions of source code must retain the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer in the documentation and/or other 
+ *     materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE.
+ */
+
+#include <windows.h>
+#include <setupapi.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strsafe.h>
+#include <malloc.h>
+#include <assert.h>
+
+#include <version.h>
+#include <revision.h>
+
+__user_code;
+
+#define MAXIMUM_BUFFER_SIZE 1024
+
+#define SERVICES_KEY "SYSTEM\\CurrentControlSet\\Services"
+
+#define SERVICE_KEY(_Driver)    \
+        SERVICES_KEY ## "\\" ## #_Driver
+
+#define UNPLUG_KEY \
+        SERVICE_KEY(XEN) ## "\\Unplug"
+
+#define CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control"
+
+#define CLASS_KEY   \
+        CONTROL_KEY ## "\\Class"
+
+#define ENUM_KEY    "SYSTEM\\CurrentControlSet\\Enum"
+
+static VOID
+#pragma prefast(suppress:6262) // Function uses '1036' bytes of stack: exceeds /analyze:stacksize'1024'
+__Log(
+    IN  const CHAR  *Format,
+    IN  ...
+    )
+{
+    TCHAR               Buffer[MAXIMUM_BUFFER_SIZE];
+    va_list             Arguments;
+    size_t              Length;
+    SP_LOG_TOKEN        LogToken;
+    DWORD               Category;
+    DWORD               Flags;
+    HRESULT             Result;
+
+    va_start(Arguments, Format);
+    Result = StringCchVPrintf(Buffer, MAXIMUM_BUFFER_SIZE, Format, Arguments);
+    va_end(Arguments);
+
+    if (Result != S_OK && Result != STRSAFE_E_INSUFFICIENT_BUFFER)
+        return;
+
+    Result = StringCchLength(Buffer, MAXIMUM_BUFFER_SIZE, &Length);
+    if (Result != S_OK)
+        return;
+
+    LogToken = SetupGetThreadLogToken();
+    Category = TXTLOG_VENDOR;
+    Flags = TXTLOG_WARNING;
+
+    SetupWriteTextLog(LogToken, Category, Flags, Buffer);
+    Length = __min(MAXIMUM_BUFFER_SIZE - 1, Length + 2);
+
+    __analysis_assume(Length < MAXIMUM_BUFFER_SIZE);
+    __analysis_assume(Length >= 2);
+    Buffer[Length] = '\0';
+    Buffer[Length - 1] = '\n';
+    Buffer[Length - 2] = '\r';
+
+    OutputDebugString(Buffer);
+}
+
+#define Log(_Format, ...) \
+        __Log(__MODULE__ "|" __FUNCTION__ ": " _Format, __VA_ARGS__)
+
+static PTCHAR
+GetErrorMessage(
+    IN  DWORD   Error
+    )
+{
+    PTCHAR      Message;
+    ULONG       Index;
+
+    if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                       FORMAT_MESSAGE_FROM_SYSTEM |
+                       FORMAT_MESSAGE_IGNORE_INSERTS,
+                       NULL,
+                       Error,
+                       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                       (LPTSTR)&Message,
+                       0,
+                       NULL))
+        return NULL;
+
+    for (Index = 0; Message[Index] != '\0'; Index++) {
+        if (Message[Index] == '\r' || Message[Index] == '\n') {
+            Message[Index] = '\0';
+            break;
+        }
+    }
+
+    return Message;
+}
+
+static FORCEINLINE const CHAR *
+__FunctionName(
+    IN  DI_FUNCTION Function
+    )
+{
+#define _NAME(_Function)        \
+        case DIF_ ## _Function: \
+            return #_Function;
+
+    switch (Function) {
+    _NAME(INSTALLDEVICE);
+    _NAME(REMOVE);
+    _NAME(SELECTDEVICE);
+    _NAME(ASSIGNRESOURCES);
+    _NAME(PROPERTIES);
+    _NAME(FIRSTTIMESETUP);
+    _NAME(FOUNDDEVICE);
+    _NAME(SELECTCLASSDRIVERS);
+    _NAME(VALIDATECLASSDRIVERS);
+    _NAME(INSTALLCLASSDRIVERS);
+    _NAME(CALCDISKSPACE);
+    _NAME(DESTROYPRIVATEDATA);
+    _NAME(VALIDATEDRIVER);
+    _NAME(MOVEDEVICE);
+    _NAME(DETECT);
+    _NAME(INSTALLWIZARD);
+    _NAME(DESTROYWIZARDDATA);
+    _NAME(PROPERTYCHANGE);
+    _NAME(ENABLECLASS);
+    _NAME(DETECTVERIFY);
+    _NAME(INSTALLDEVICEFILES);
+    _NAME(ALLOW_INSTALL);
+    _NAME(SELECTBESTCOMPATDRV);
+    _NAME(REGISTERDEVICE);
+    _NAME(NEWDEVICEWIZARD_PRESELECT);
+    _NAME(NEWDEVICEWIZARD_SELECT);
+    _NAME(NEWDEVICEWIZARD_PREANALYZE);
+    _NAME(NEWDEVICEWIZARD_POSTANALYZE);
+    _NAME(NEWDEVICEWIZARD_FINISHINSTALL);
+    _NAME(INSTALLINTERFACES);
+    _NAME(DETECTCANCEL);
+    _NAME(REGISTER_COINSTALLERS);
+    _NAME(ADDPROPERTYPAGE_ADVANCED);
+    _NAME(ADDPROPERTYPAGE_BASIC);
+    _NAME(TROUBLESHOOTER);
+    _NAME(POWERMESSAGEWAKE);
+    default:
+        break;
+    }
+
+    return "UNKNOWN";
+
+#undef  _NAME
+}
+
+static BOOLEAN
+AllowUpdate(
+    IN  PTCHAR      DriverName,
+    OUT PBOOLEAN    Allow
+    )
+{
+    TCHAR           ServiceKeyName[MAX_PATH];
+    HKEY            ServiceKey;
+    HRESULT         Result;
+    HRESULT         Error;
+    DWORD           ValueLength;
+    DWORD           Value;
+    DWORD           Type;
+
+    Log("====> (%s)", DriverName);
+
+    Result = StringCbPrintf(ServiceKeyName,
+                            MAX_PATH,
+                            SERVICES_KEY "\\%s",
+                            DriverName);
+    assert(SUCCEEDED(Result));
+
+    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                         ServiceKeyName,
+                         0,
+                         KEY_READ,
+                         &ServiceKey);
+    if (Error != ERROR_SUCCESS) {
+        if (Error == ERROR_FILE_NOT_FOUND) {
+            Value = 1;
+            goto done;
+        }
+
+        SetLastError(Error);
+        goto fail1;
+    }
+
+    ValueLength = sizeof (Value);
+
+    Error = RegQueryValueEx(ServiceKey,
+                            "AllowUpdate",
+                            NULL,
+                            &Type,
+                            (LPBYTE)&Value,
+                            &ValueLength);
+    if (Error != ERROR_SUCCESS) {
+        if (Error == ERROR_FILE_NOT_FOUND) {
+            Type = REG_DWORD;
+            Value = 1;
+        } else {
+            SetLastError(Error);
+            goto fail2;
+        }
+    }
+
+    if (Type != REG_DWORD) {
+        SetLastError(ERROR_BAD_FORMAT);
+        goto fail3;
+    }
+
+    RegCloseKey(ServiceKey);
+
+done:
+    if (Value == 0) {
+        Log("DISALLOWED");
+        *Allow = FALSE;
+    }
+
+    Log("<====");
+
+    return TRUE;
+
+fail3:
+    Log("fail3");
+
+fail2:
+    Log("fail2");
+
+    RegCloseKey(ServiceKey);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+AllowInstall(
+    OUT PBOOLEAN    Allow
+    )
+{
+    BOOLEAN         Success;
+    HRESULT         Error;
+
+    Log("====>");
+
+    *Allow = TRUE;
+
+    Success = AllowUpdate("XENHID", Allow);
+    if (!Success)
+        goto fail1;
+
+    Log("<====");
+
+    return TRUE;
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+OpenEnumKey(
+    OUT PHKEY   EnumKey
+    )
+{
+    HRESULT     Error;
+
+    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                         ENUM_KEY,
+                         0,
+                         KEY_READ,
+                         EnumKey);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail1;
+    }
+
+    return TRUE;
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+OpenBusKey(
+    IN  PTCHAR  BusKeyName,
+    OUT PHKEY   BusKey
+    )
+{
+    BOOLEAN     Success;
+    HKEY        EnumKey;
+    HRESULT     Error;
+
+    Success = OpenEnumKey(&EnumKey);
+    if (!Success)
+        goto fail1;
+
+    Error = RegOpenKeyEx(EnumKey,
+                         BusKeyName,
+                         0,
+                         KEY_READ,
+                         BusKey);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail2;
+    }
+
+    RegCloseKey(EnumKey);
+
+    return TRUE;
+
+fail2:
+    Log("fail2");
+
+    RegCloseKey(EnumKey);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+OpenDeviceKey(
+    IN  PTCHAR  BusKeyName,
+    IN  PTCHAR  DeviceKeyName,
+    OUT PHKEY   DeviceKey
+    )
+{
+    BOOLEAN     Success;
+    HKEY        BusKey;
+    HRESULT     Error;
+
+    Success = OpenBusKey(BusKeyName, &BusKey);
+    if (!Success)
+        goto fail1;
+
+    Error = RegOpenKeyEx(BusKey,
+                         DeviceKeyName,
+                         0,
+                         KEY_READ,
+                         DeviceKey);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail2;
+    }
+
+    RegCloseKey(BusKey);
+
+    return TRUE;
+
+fail2:
+    Log("fail2");
+
+    RegCloseKey(BusKey);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+GetDriverKeyName(
+    IN  HKEY    DeviceKey,
+    OUT PTCHAR  *Name
+    )
+{
+    HRESULT     Error;
+    DWORD       SubKeys;
+    DWORD       MaxSubKeyLength;
+    DWORD       SubKeyLength;
+    PTCHAR      SubKeyName;
+    DWORD       Index;
+    HKEY        SubKey;
+    PTCHAR      DriverKeyName;
+
+    Error = RegQueryInfoKey(DeviceKey,
+                            NULL,
+                            NULL,
+                            NULL,
+                            &SubKeys,
+                            &MaxSubKeyLength,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail1;
+    }
+
+    SubKeyLength = MaxSubKeyLength + sizeof (TCHAR);
+
+    SubKeyName = malloc(SubKeyLength);
+    if (SubKeyName == NULL)
+        goto fail2;
+
+    SubKey = NULL;
+    DriverKeyName = NULL;
+
+    for (Index = 0; Index < SubKeys; Index++) {
+        DWORD       MaxValueLength;
+        DWORD       DriverKeyNameLength;
+        DWORD       Type;
+
+        SubKeyLength = MaxSubKeyLength + sizeof (TCHAR);
+        memset(SubKeyName, 0, SubKeyLength);
+
+        Error = RegEnumKeyEx(DeviceKey,
+                             Index,
+                             (LPTSTR)SubKeyName,
+                             &SubKeyLength,
+                             NULL,
+                             NULL,
+                             NULL,
+                             NULL);
+        if (Error != ERROR_SUCCESS) {
+            SetLastError(Error);
+            goto fail3;
+        }
+
+        Error = RegOpenKeyEx(DeviceKey,
+                             SubKeyName,
+                             0,
+                             KEY_READ,
+                             &SubKey);
+        if (Error != ERROR_SUCCESS) {
+            SubKey = NULL;
+            continue;
+        }
+
+        Error = RegQueryInfoKey(SubKey,
+                                NULL,
+                                NULL,
+                                NULL,
+                                NULL,
+                                NULL,
+                                NULL,
+                                NULL,
+                                NULL,
+                                &MaxValueLength,
+                                NULL,
+                                NULL);
+        if (Error != ERROR_SUCCESS) {
+            SetLastError(Error);
+            goto fail4;
+        }
+
+        DriverKeyNameLength = MaxValueLength + sizeof (TCHAR);
+
+        DriverKeyName = calloc(1, DriverKeyNameLength);
+        if (DriverKeyName == NULL)
+            goto fail5;
+
+        Error = RegQueryValueEx(SubKey,
+                                "Driver",
+                                NULL,
+                                &Type,
+                                (LPBYTE)DriverKeyName,
+                                &DriverKeyNameLength);
+        if (Error == ERROR_SUCCESS &&
+            Type == REG_SZ)
+            break;
+
+        free(DriverKeyName);
+        DriverKeyName = NULL;
+
+        RegCloseKey(SubKey);
+        SubKey = NULL;
+    }
+
+    Log("%s", (DriverKeyName != NULL) ? DriverKeyName : "none found");
+
+    if (SubKey != NULL)
+        RegCloseKey(SubKey);
+
+    free(SubKeyName);
+
+    *Name = DriverKeyName;
+    return TRUE;
+
+fail5:
+    Log("fail5");
+
+fail4:
+    Log("fail4");
+
+    if (SubKey != NULL)
+        RegCloseKey(SubKey);
+
+fail3:
+    Log("fail3");
+
+    free(SubKeyName);
+
+fail2:
+    Log("fail2");
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+OpenClassKey(
+    OUT PHKEY   ClassKey
+    )
+{
+    HRESULT     Error;
+
+    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                         CLASS_KEY,
+                         0,
+                         KEY_READ,
+                         ClassKey);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail1;
+    }
+
+    return TRUE;
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+OpenDriverKey(
+    IN  PTCHAR  DriverKeyName,
+    OUT PHKEY   DriverKey
+    )
+{
+    BOOLEAN     Success;
+    HKEY        ClassKey;
+    HRESULT     Error;
+
+    Success = OpenClassKey(&ClassKey);
+    if (!Success)
+        goto fail1;
+
+    Error = RegOpenKeyEx(ClassKey,
+                         DriverKeyName,
+                         0,
+                         KEY_READ,
+                         DriverKey);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail2;
+    }
+
+    RegCloseKey(ClassKey);
+
+    return TRUE;
+
+fail2:
+    Log("fail2");
+
+    RegCloseKey(ClassKey);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+#define DEFINE_REVISION(_N, _H) \
+    (_N)
+
+static DWORD    DeviceRevision[] = {
+    DEFINE_REVISION_TABLE
+};
+
+#undef DEFINE_REVISION
+
+static BOOLEAN
+SupportDeviceID(
+    IN  PTCHAR      DeviceID
+    )
+{
+    unsigned int    Revision;
+    int             Count;
+    DWORD           Index;
+    HRESULT         Error;
+
+    DeviceID = strrchr(DeviceID, '&');
+    assert(DeviceID != NULL);
+    DeviceID++;
+
+    Count = sscanf_s(DeviceID,
+                     "REV_%8x",
+                     &Revision);
+    if (Count != 1) {
+        SetLastError(ERROR_BAD_FORMAT);
+        goto fail1;
+    }
+
+    for (Index = 0; Index < ARRAYSIZE(DeviceRevision); Index++) {
+        if (Revision == DeviceRevision[Index])
+            goto found;
+    }
+
+    SetLastError(ERROR_FILE_NOT_FOUND);
+    goto fail2;
+
+found:
+    Log("%x", Revision);
+
+    return TRUE;
+
+fail2:
+    Log("fail2");
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+GetMatchingDeviceID(
+    IN  HKEY    DriverKey,
+    OUT PTCHAR  *MatchingDeviceID
+    )
+{
+    HRESULT     Error;
+    DWORD       MaxValueLength;
+    DWORD       MatchingDeviceIDLength;
+    DWORD       Type;
+    DWORD       Index;
+
+    Error = RegQueryInfoKey(DriverKey,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            &MaxValueLength,
+                            NULL,
+                            NULL);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail1;
+    }
+
+    MatchingDeviceIDLength = MaxValueLength + sizeof (TCHAR);
+
+    *MatchingDeviceID = calloc(1, MatchingDeviceIDLength);
+    if (*MatchingDeviceID == NULL)
+        goto fail2;
+
+    Error = RegQueryValueEx(DriverKey,
+                            "MatchingDeviceId",
+                            NULL,
+                            &Type,
+                            (LPBYTE)*MatchingDeviceID,
+                            &MatchingDeviceIDLength);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail3;
+    }
+
+    if (Type != REG_SZ) {
+        SetLastError(ERROR_BAD_FORMAT);
+        goto fail4;
+    }
+
+    for (Index = 0; Index < strlen(*MatchingDeviceID); Index++)
+        (*MatchingDeviceID)[Index] = (CHAR)toupper((*MatchingDeviceID)[Index]);
+
+    Log("%s", *MatchingDeviceID);
+
+    return TRUE;
+
+fail4:
+    Log("fail4");
+
+fail3:
+    Log("fail3");
+
+    free(*MatchingDeviceID);
+
+fail2:
+    Log("fail2");
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+SupportChildDrivers(
+    VOID
+    )
+{
+    BOOLEAN     Success;
+    HKEY        XenbusKey;
+    HRESULT     Error;
+    DWORD       SubKeys;
+    DWORD       MaxSubKeyLength;
+    DWORD       SubKeyLength;
+    PTCHAR      SubKeyName;
+    HKEY        DeviceKey;
+    PTCHAR      DriverKeyName;
+    HKEY        DriverKey;
+    PTCHAR      MatchingDeviceID;
+    DWORD       Index;
+
+    Log("====>");
+
+    Success = OpenBusKey("XENHID", &XenbusKey);
+    if (!Success) {
+        // If there is no key then this must be a fresh installation
+        if (GetLastError() == ERROR_FILE_NOT_FOUND)
+            goto done;
+
+        goto fail1;
+    }
+
+    Error = RegQueryInfoKey(XenbusKey,
+                            NULL,
+                            NULL,
+                            NULL,
+                            &SubKeys,
+                            &MaxSubKeyLength,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail2;
+    }
+
+    SubKeyLength = MaxSubKeyLength + sizeof (TCHAR);
+
+    SubKeyName = malloc(SubKeyLength);
+    if (SubKeyName == NULL)
+        goto fail3;
+
+    for (Index = 0; Index < SubKeys; Index++) {
+        SubKeyLength = MaxSubKeyLength + sizeof (TCHAR);
+        memset(SubKeyName, 0, SubKeyLength);
+
+        Error = RegEnumKeyEx(XenbusKey,
+                             Index,
+                             (LPTSTR)SubKeyName,
+                             &SubKeyLength,
+                             NULL,
+                             NULL,
+                             NULL,
+                             NULL);
+        if (Error != ERROR_SUCCESS) {
+            SetLastError(Error);
+            goto fail4;
+        }
+
+        Success = OpenDeviceKey("XENHID", SubKeyName, &DeviceKey);
+        if (!Success)
+            goto fail5;
+
+        Success = GetDriverKeyName(DeviceKey, &DriverKeyName);
+        if (!Success)
+            goto fail6;
+
+        if (DriverKeyName == NULL)
+            goto loop;
+
+        Success = OpenDriverKey(DriverKeyName, &DriverKey);
+        if (!Success)
+            goto loop;
+
+        Success = GetMatchingDeviceID(DriverKey, &MatchingDeviceID);
+        if (!Success)
+            goto fail7;
+
+        Success = SupportDeviceID(MatchingDeviceID);
+        if (!Success)
+            goto fail8;
+
+        free(MatchingDeviceID);
+
+        RegCloseKey(DriverKey);
+
+    loop:
+        if (DriverKeyName != NULL)
+            free(DriverKeyName);
+
+        RegCloseKey(DeviceKey);
+    }
+
+    free(SubKeyName);
+
+    RegCloseKey(XenbusKey);
+
+done:
+    Log("<====");
+
+    return TRUE;
+
+fail8:
+    Log("fail8");
+
+    free(MatchingDeviceID);
+
+fail7:
+    Log("fail7");
+
+    RegCloseKey(DriverKey);
+
+    free(DriverKeyName);
+
+fail6:
+    Log("fail6");
+
+    RegCloseKey(DeviceKey);
+
+fail5:
+    Log("fail5");
+
+fail4:
+    Log("fail4");
+
+    free(SubKeyName);
+
+fail3:
+    Log("fail3");
+
+fail2:
+    Log("fail2");
+
+    RegCloseKey(XenbusKey);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static HRESULT
+DifInstallPreProcess(
+    IN  HDEVINFO                    DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA            DeviceInfoData,
+    IN  PCOINSTALLER_CONTEXT_DATA   Context
+    )
+{
+    HRESULT                         Error;
+    BOOLEAN                         Success;
+    BOOLEAN                         Allow;
+
+    UNREFERENCED_PARAMETER(DeviceInfoSet);
+    UNREFERENCED_PARAMETER(DeviceInfoData);
+    UNREFERENCED_PARAMETER(Context);
+
+    Log("====>");
+
+    Success = AllowInstall(&Allow);
+    if (!Success)
+        goto fail1;
+
+    if (!Allow) {
+        SetLastError(ERROR_ACCESS_DENIED);
+        goto fail2;
+    }
+
+    Success = SupportChildDrivers();
+    if (!Success)
+        goto fail3;
+
+    Log("<====");
+
+    return NO_ERROR;
+
+fail3:
+    Log("fail3");
+
+fail2:
+    Log("fail2");
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return Error;
+}
+
+static HRESULT
+DifInstallPostProcess(
+    IN  HDEVINFO                    DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA            DeviceInfoData,
+    IN  PCOINSTALLER_CONTEXT_DATA   Context
+    )
+{
+    UNREFERENCED_PARAMETER(DeviceInfoSet);
+    UNREFERENCED_PARAMETER(DeviceInfoData);
+    UNREFERENCED_PARAMETER(Context);
+
+    Log("<===>");
+
+    return NO_ERROR;
+}
+
+static DECLSPEC_NOINLINE HRESULT
+DifInstall(
+    IN  HDEVINFO                    DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA            DeviceInfoData,
+    IN  PCOINSTALLER_CONTEXT_DATA   Context
+    )
+{
+    SP_DEVINSTALL_PARAMS            DeviceInstallParams;
+    HRESULT                         Error;
+
+    DeviceInstallParams.cbSize = sizeof (DeviceInstallParams);
+
+    if (!SetupDiGetDeviceInstallParams(DeviceInfoSet,
+                                       DeviceInfoData,
+                                       &DeviceInstallParams))
+        goto fail1;
+
+    Log("Flags = %08x", DeviceInstallParams.Flags);
+
+    if (!Context->PostProcessing) {
+        Error = DifInstallPreProcess(DeviceInfoSet, DeviceInfoData, Context);
+
+        if (Error == NO_ERROR)
+            Error = ERROR_DI_POSTPROCESSING_REQUIRED; 
+    } else {
+        Error = Context->InstallResult;
+        
+        if (Error == NO_ERROR) {
+            (VOID) DifInstallPostProcess(DeviceInfoSet, DeviceInfoData, Context);
+        } else {
+            PTCHAR  Message;
+
+            Message = GetErrorMessage(Error);
+            Log("NOT RUNNING (DifInstallPreProcess Error: %s)", Message);
+            LocalFree(Message);
+        }
+
+        Error = NO_ERROR; 
+    }
+
+    return Error;
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return Error;
+}
+
+static HRESULT
+DifRemovePreProcess(
+    IN  HDEVINFO                    DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA            DeviceInfoData,
+    IN  PCOINSTALLER_CONTEXT_DATA   Context
+    )
+{
+    UNREFERENCED_PARAMETER(DeviceInfoSet);
+    UNREFERENCED_PARAMETER(DeviceInfoData);
+    UNREFERENCED_PARAMETER(Context);
+
+    Log("<===>");
+
+    return NO_ERROR; 
+}
+
+static HRESULT
+DifRemovePostProcess(
+    IN  HDEVINFO                    DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA            DeviceInfoData,
+    IN  PCOINSTALLER_CONTEXT_DATA   Context
+    )
+{
+    UNREFERENCED_PARAMETER(DeviceInfoSet);
+    UNREFERENCED_PARAMETER(DeviceInfoData);
+    UNREFERENCED_PARAMETER(Context);
+
+    Log("<===>");
+
+    return NO_ERROR;
+}
+
+static DECLSPEC_NOINLINE HRESULT
+DifRemove(
+    IN  HDEVINFO                    DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA            DeviceInfoData,
+    IN  PCOINSTALLER_CONTEXT_DATA   Context
+    )
+{
+    SP_DEVINSTALL_PARAMS            DeviceInstallParams;
+    HRESULT                         Error;
+
+    DeviceInstallParams.cbSize = sizeof (DeviceInstallParams);
+
+    if (!SetupDiGetDeviceInstallParams(DeviceInfoSet,
+                                       DeviceInfoData,
+                                       &DeviceInstallParams))
+        goto fail1;
+
+    Log("Flags = %08x", DeviceInstallParams.Flags);
+
+    if (!Context->PostProcessing) {
+        Error = DifRemovePreProcess(DeviceInfoSet, DeviceInfoData, Context);
+
+        if (Error == NO_ERROR)
+            Error = ERROR_DI_POSTPROCESSING_REQUIRED; 
+    } else {
+        Error = Context->InstallResult;
+        
+        if (Error == NO_ERROR) {
+            (VOID) DifRemovePostProcess(DeviceInfoSet, DeviceInfoData, Context);
+        } else {
+            PTCHAR  Message;
+
+            Message = GetErrorMessage(Error);
+            Log("NOT RUNNING (DifRemovePreProcess Error: %s)", Message);
+            LocalFree(Message);
+        }
+
+        Error = NO_ERROR; 
+    }
+
+    return Error;
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return Error;
+}
+
+DWORD CALLBACK
+Entry(
+    IN  DI_FUNCTION                 Function,
+    IN  HDEVINFO                    DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA            DeviceInfoData,
+    IN  PCOINSTALLER_CONTEXT_DATA   Context
+    )
+{
+    HRESULT                         Error;
+
+    Log("%s (%s) ===>",
+        MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR,
+        DAY_STR "/" MONTH_STR "/" YEAR_STR);
+
+    if (!Context->PostProcessing) {
+        Log("%s PreProcessing",
+            __FunctionName(Function));
+    } else {
+        Log("%s PostProcessing (%08x)",
+            __FunctionName(Function),
+            Context->InstallResult);
+    }
+
+    switch (Function) {
+    case DIF_INSTALLDEVICE: {
+        SP_DRVINFO_DATA         DriverInfoData;
+        BOOLEAN                 DriverInfoAvailable;
+
+        DriverInfoData.cbSize = sizeof (DriverInfoData);
+        DriverInfoAvailable = SetupDiGetSelectedDriver(DeviceInfoSet,
+                                                       DeviceInfoData,
+                                                       &DriverInfoData) ?
+                              TRUE :
+                              FALSE;
+
+        // If there is no driver information then the NULL driver is being
+        // installed. Treat this as we would a DIF_REMOVE.
+        Error = (DriverInfoAvailable) ?
+                DifInstall(DeviceInfoSet, DeviceInfoData, Context) :
+                DifRemove(DeviceInfoSet, DeviceInfoData, Context);
+        break;
+    }
+    case DIF_REMOVE:
+        Error = DifRemove(DeviceInfoSet, DeviceInfoData, Context);
+        break;
+    default:
+        if (!Context->PostProcessing) {
+            Error = NO_ERROR;
+        } else {
+            Error = Context->InstallResult;
+        }
+
+        break;
+    }
+
+    Log("%s (%s) <===",
+        MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR,
+        DAY_STR "/" MONTH_STR "/" YEAR_STR);
+
+    return (DWORD)Error;
+}
+
+DWORD CALLBACK
+Version(
+    IN  HWND        Window,
+    IN  HINSTANCE   Module,
+    IN  PTCHAR      Buffer,
+    IN  INT         Reserved
+    )
+{
+    UNREFERENCED_PARAMETER(Window);
+    UNREFERENCED_PARAMETER(Module);
+    UNREFERENCED_PARAMETER(Buffer);
+    UNREFERENCED_PARAMETER(Reserved);
+
+    Log("%s (%s)",
+        MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR,
+        DAY_STR "/" MONTH_STR "/" YEAR_STR);
+
+    return NO_ERROR;
+}
+
+static FORCEINLINE const CHAR *
+__ReasonName(
+    IN  DWORD       Reason
+    )
+{
+#define _NAME(_Reason)          \
+        case DLL_ ## _Reason:   \
+            return #_Reason;
+
+    switch (Reason) {
+    _NAME(PROCESS_ATTACH);
+    _NAME(PROCESS_DETACH);
+    _NAME(THREAD_ATTACH);
+    _NAME(THREAD_DETACH);
+    default:
+        break;
+    }
+
+    return "UNKNOWN";
+
+#undef  _NAME
+}
+
+BOOL WINAPI
+DllMain(
+    IN  HINSTANCE   Module,
+    IN  DWORD       Reason,
+    IN  PVOID       Reserved
+    )
+{
+    UNREFERENCED_PARAMETER(Module);
+    UNREFERENCED_PARAMETER(Reserved);
+
+    Log("%s (%s): %s",
+        MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR,
+        DAY_STR "/" MONTH_STR "/" YEAR_STR,
+        __ReasonName(Reason));
+
+    return TRUE;
+}
diff --git a/src/coinst/xenhid_coinst.def b/src/coinst/xenhid_coinst.def
new file mode 100644 (file)
index 0000000..df65c7f
--- /dev/null
@@ -0,0 +1,37 @@
+; Copyright (c) Citrix Systems Inc.
+; All rights reserved.
+; 
+; Redistribution and use in source and binary forms, 
+; with or without modification, are permitted provided 
+; that the following conditions are met:
+; 
+; *   Redistributions of source code must retain the above 
+;     copyright notice, this list of conditions and the 
+;     following disclaimer.
+; *   Redistributions in binary form must reproduce the above 
+;     copyright notice, this list of conditions and the 
+;     following disclaimer in the documentation and/or other 
+;     materials provided with the distribution.
+; 
+; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+; CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+; INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+; SUCH DAMAGE.
+
+LIBRARY  XENBUS_COINST
+
+EXPORTS   
+   Entry 
+   Version
+
+   DllMain PRIVATE
diff --git a/src/xenhid.inf b/src/xenhid.inf
new file mode 100644 (file)
index 0000000..d440876
--- /dev/null
@@ -0,0 +1,111 @@
+; Copyright (c) Citrix Systems Inc.
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, 
+; with or without modification, are permitted provided 
+; that the following conditions are met:
+;
+; *   Redistributions of source code must retain the above 
+;     copyright notice, this list of conditions and the 
+;     following disclaimer.
+; *   Redistributions in binary form must reproduce the above 
+;     copyright notice, this list of conditions and the 
+;     following disclaimer in the documentation and/or other 
+;     materials provided with the distribution.
+;
+; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+; CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+; INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+; SUCH DAMAGE.
+
+[Version] 
+Signature="$Windows NT$" 
+Class=HIDClass
+ClassGUID={745a17a0-74d3-11d0-b6fe-00a0c90f57da}
+Provider=%Vendor%
+CatalogFile=xenhid.cat
+DriverVer=01/01/1900,0.0.0.0
+DriverPackageDisplayName=%DiskDesc%
+
+[DestinationDirs] 
+DefaultDestDir=12 
+CoInst_CopyFiles=11
+
+[SourceDisksNames]
+0=%DiskDesc%
+
+[SourceDisksFiles]
+xenhid.sys=0,,
+xenhid_coinst.dll=0,,
+
+[CoInst_CopyFiles]
+xenhid_coinst_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.dll,xenhid_coinst.dll
+
+[Manufacturer] 
+%Vendor%=Inst,NT$ARCH$
+
+[Inst.NT$ARCH$]
+; DisplayName          Section         DeviceID
+; -----------          -------         --------
+
+%XenHidName%           =XenHid_Inst,   XENVKBD\VEN_@VENDOR_PREFIX@@VENDOR_DEVICE_ID@&DEV_HID&REV_09000000
+%XenHidName%           =XenHid_Inst,   XENVKBD\VEN_@VENDOR_PREFIX@0001&DEV_HID&REV_09000000
+%XenHidName%           =XenHid_Inst,   XENVKBD\VEN_@VENDOR_PREFIX@0002&DEV_HID&REV_09000000
+
+[XenHid_Inst] 
+CopyFiles=XenHid_Copyfiles
+
+[XenHid_Copyfiles]
+xenhid.sys
+
+[XenHid_Inst.Services] 
+AddService=xenhid,0x02,XenHid_Service,
+
+[XenHid_Service]
+DisplayName=%XenHidName%
+ServiceType=%SERVICE_KERNEL_DRIVER% 
+StartType=%SERVICE_DEMAND_START% 
+ErrorControl=%SERVICE_ERROR_NORMAL% 
+ServiceBinary=%12%\xenhid.sys 
+AddReg = XenHid_Parameters
+
+[XenHid_Parameters]
+HKR,"Parameters",,0x00000010
+HKR,"Parameters","RequestKey",0x00000000,%RequestKey%
+
+[XenHid_Inst.CoInstallers]
+CopyFiles=CoInst_CopyFiles
+AddReg=CoInst_AddReg
+
+[CoInst_AddReg]
+HKR,,CoInstallers32,0x00010000,"xenhid_coinst_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.dll,Entry"
+
+[Strings] 
+
+Vendor="@VENDOR_NAME@"
+DiskDesc="@PRODUCT_NAME@ PV HID Device Package"
+XenHidName="@PRODUCT_NAME@ PV HID Device"
+RequestKey="SYSTEM\CurrentControlSet\Services\xenbus_monitor\Request"
+
+SERVICE_BOOT_START=0x0 
+SERVICE_SYSTEM_START=0x1 
+SERVICE_AUTO_START=0x2 
+SERVICE_DEMAND_START=0x3 
+SERVICE_DISABLED=0x4 
+
+SERVICE_KERNEL_DRIVER=0x1 
+SERVICE_ERROR_IGNORE=0x0 
+SERVICE_ERROR_NORMAL=0x1 
+SERVICE_ERROR_SEVERE=0x2 
+SERVICE_ERROR_CRITICAL=0x3 
diff --git a/src/xenhid.pfx b/src/xenhid.pfx
new file mode 100644 (file)
index 0000000..b8e384d
Binary files /dev/null and b/src/xenhid.pfx differ
diff --git a/src/xenhid/assert.h b/src/xenhid/assert.h
new file mode 100644 (file)
index 0000000..def95a2
--- /dev/null
@@ -0,0 +1,202 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, 
+ * with or without modification, are permitted provided 
+ * that the following conditions are met:
+ * 
+ * *   Redistributions of source code must retain the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer in the documentation and/or other 
+ *     materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE.
+ */
+
+#ifndef _XENHID_ASSERT_H
+#define _XENHID_ASSERT_H
+
+#include <ntddk.h>
+
+#include "dbg_print.h"
+
+static FORCEINLINE VOID
+__Bug(
+    IN  ULONG       Code,
+    IN  ULONG_PTR   Parameter1,
+    IN  ULONG_PTR   Parameter2,
+    IN  ULONG_PTR   Parameter3,
+    IN  ULONG_PTR   Parameter4
+    )
+{
+#pragma prefast(suppress:28159)
+    KeBugCheckEx(Code,
+                 Parameter1,
+                 Parameter2,
+                 Parameter3,
+                 Parameter4);
+}
+
+#define ASSERTION_FAILURE   0x0000DEAD
+
+#define BUG(_TEXT)                                              \
+        do {                                                    \
+            const CHAR  *_Text = (_TEXT);                       \
+            const CHAR  *_File = __FILE__;                      \
+            ULONG       _Line = __LINE__;                       \
+                                                                \
+            Error("BUG: " _TEXT "\n");                          \
+            __Bug(ASSERTION_FAILURE,                            \
+                  (ULONG_PTR)_Text,                             \
+                  (ULONG_PTR)_File,                             \
+                  (ULONG_PTR)_Line,                             \
+                  0);                                           \
+        } while (FALSE)
+
+#define BUG_ON(_EXP)                \
+        if (_EXP) BUG(#_EXP)
+
+#undef  ASSERT
+
+#if DBG
+
+#define __NT_ASSERT(_EXP)                                       \
+        ((!(_EXP)) ?                                            \
+        (Error("ASSERTION FAILED: " #_EXP "\n"),                \
+         __annotation(L"Debug", L"AssertFail", L#_EXP),         \
+         DbgRaiseAssertionFailure(), FALSE) :                   \
+        TRUE)
+
+#define __ASSERT(_EXP)  __NT_ASSERT(_EXP)
+
+#define ASSERT(_EXP)                    \
+        do {                            \
+            __ASSERT(_EXP);             \
+            __analysis_assume(_EXP);    \
+        } while (FALSE)
+
+#define ASSERT3U(_X, _OP, _Y)                       \
+        do {                                        \
+            ULONGLONG   _Lval = (ULONGLONG)(_X);    \
+            ULONGLONG   _Rval = (ULONGLONG)(_Y);    \
+            if (!(_Lval _OP _Rval)) {               \
+                Error("%s = %llu\n", #_X, _Lval);   \
+                Error("%s = %llu\n", #_Y, _Rval);   \
+                ASSERT((_X) _OP (_Y));              \
+            }                                       \
+        } while (FALSE)
+
+#define ASSERT3S(_X, _OP, _Y)                       \
+        do {                                        \
+            LONGLONG    _Lval = (LONGLONG)(_X);     \
+            LONGLONG    _Rval = (LONGLONG)(_Y);     \
+            if (!(_Lval _OP _Rval)) {               \
+                Error("%s = %lld\n", #_X, _Lval);   \
+                Error("%s = %lld\n", #_Y, _Rval);   \
+                ASSERT((_X) _OP (_Y));              \
+            }                                       \
+        } while (FALSE)
+
+#define ASSERT3P(_X, _OP, _Y)                       \
+        do {                                        \
+            PVOID   _Lval = (PVOID)(_X);            \
+            PVOID   _Rval = (PVOID)(_Y);            \
+            if (!(_Lval _OP _Rval)) {               \
+                Error("%s = %p\n", #_X, _Lval);     \
+                Error("%s = %p\n", #_Y, _Rval);     \
+                ASSERT((_X) _OP (_Y));              \
+            }                                       \
+        } while (FALSE)
+
+#else   // DBG
+
+#pragma warning(disable:4100)
+#pragma warning(disable:4189)
+
+#define ASSERT(_EXP)                    \
+        do {                            \
+            __analysis_assume(_EXP);    \
+        } while (FALSE)
+
+#define ASSERT3U(_X, _OP, _Y)           \
+        ASSERT((_X) _OP (_Y))
+
+#define ASSERT3S(_X, _OP, _Y)           \
+        ASSERT((_X) _OP (_Y))
+
+#define ASSERT3P(_X, _OP, _Y)           \
+        ASSERT((_X) _OP (_Y))
+
+#endif  // DBG
+
+#ifndef TEST_MEMORY
+#define TEST_MEMORY DBG
+#endif
+
+#if TEST_MEMORY
+
+static __inline BOOLEAN
+_IsZeroMemory(
+    IN  const PCHAR Caller,
+    IN  const PCHAR Name,
+    IN  PVOID       Buffer,
+    IN  ULONG       Length
+    )
+{
+    ULONG           Offset;
+
+    Offset = 0;
+    while (Offset < Length) {
+        if (*((PUCHAR)Buffer + Offset) != 0) {
+            Error("%s: non-zero byte in %s (0x%p+0x%x)\n", Caller, Name, Buffer, Offset);
+            return FALSE;
+        }
+        Offset++;
+    }
+
+    return TRUE;
+}
+
+#else   // TEST_MEMORY
+
+static __inline BOOLEAN
+_IsZeroMemory(
+    IN  const PCHAR Caller,
+    IN  const PCHAR Name,
+    IN  PVOID       Buffer,
+    IN  ULONG       Length
+    )
+{
+    UNREFERENCED_PARAMETER(Caller);
+    UNREFERENCED_PARAMETER(Name);
+    UNREFERENCED_PARAMETER(Buffer);
+    UNREFERENCED_PARAMETER(Length);
+
+    return TRUE;
+}
+
+#endif  // TEST_MEMORY
+
+#define IsZeroMemory(_Buffer, _Length) \
+        _IsZeroMemory(__FUNCTION__, #_Buffer, (_Buffer), (_Length))
+
+#define IMPLY(_X, _Y)   (!(_X) || (_Y))
+#define EQUIV(_X, _Y)   (IMPLY((_X), (_Y)) && IMPLY((_Y), (_X)))
+
+#endif  // _XENHID_ASSERT_H
diff --git a/src/xenhid/dbg_print.h b/src/xenhid/dbg_print.h
new file mode 100644 (file)
index 0000000..5097bb3
--- /dev/null
@@ -0,0 +1,153 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, 
+ * with or without modification, are permitted provided 
+ * that the following conditions are met:
+ * 
+ * *   Redistributions of source code must retain the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer in the documentation and/or other 
+ *     materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE.
+ */
+
+#ifndef _XENHID_DBG_PRINT_H
+#define _XENHID_DBG_PRINT_H
+
+#include <ntddk.h>
+#include <stdarg.h>
+
+#ifdef  _SDV_
+#define __MODULE__ ""
+#endif
+
+#pragma warning(disable:4127)   // conditional expression is constant
+
+static __inline VOID
+__Error(
+    IN  const CHAR  *Prefix,
+    IN  const CHAR  *Format,
+    ...
+    )
+{
+    va_list         Arguments;
+
+    va_start(Arguments, Format);
+
+#pragma prefast(suppress:6001) // Using uninitialized memory
+    vDbgPrintExWithPrefix(Prefix,
+                          DPFLTR_IHVDRIVER_ID,
+                          DPFLTR_ERROR_LEVEL,
+                          Format,
+                          Arguments);
+    va_end(Arguments);
+}
+
+#define Error(...)  \
+        __Error(__MODULE__ "|" __FUNCTION__ ": ", __VA_ARGS__)
+
+static __inline VOID
+__Warning(
+    IN  const CHAR  *Prefix,
+    IN  const CHAR  *Format,
+    ...
+    )
+{
+    va_list         Arguments;
+
+    va_start(Arguments, Format);
+
+#pragma prefast(suppress:6001) // Using uninitialized memory
+    vDbgPrintExWithPrefix(Prefix,
+                          DPFLTR_IHVDRIVER_ID,
+                          DPFLTR_WARNING_LEVEL,
+                          Format,
+                          Arguments);
+    va_end(Arguments);
+}
+
+#define Warning(...)  \
+        __Warning(__MODULE__ "|" __FUNCTION__ ": ", __VA_ARGS__)
+
+#if DBG
+
+static __inline VOID
+__Trace(
+    IN  const CHAR  *Prefix,
+    IN  const CHAR  *Format,
+    ...
+    )
+{
+    va_list         Arguments;
+
+    va_start(Arguments, Format);
+
+#pragma prefast(suppress:6001) // Using uninitialized memory
+    vDbgPrintExWithPrefix(Prefix,
+                          DPFLTR_IHVDRIVER_ID,
+                          DPFLTR_TRACE_LEVEL,
+                          Format,
+                          Arguments);
+    va_end(Arguments);
+}
+
+#else   // DBG
+
+static __inline VOID
+__Trace(
+    IN  const CHAR  *Prefix,
+    IN  const CHAR  *Format,
+    ...
+    )
+{
+    UNREFERENCED_PARAMETER(Prefix);
+    UNREFERENCED_PARAMETER(Format);
+}
+
+#endif  // DBG
+
+#define Trace(...)  \
+        __Trace(__MODULE__ "|" __FUNCTION__ ": ", __VA_ARGS__)
+
+static __inline VOID
+__Info(
+    IN  const CHAR  *Prefix,
+    IN  const CHAR  *Format,
+    ...
+    )
+{
+    va_list         Arguments;
+
+    va_start(Arguments, Format);
+
+#pragma prefast(suppress:6001) // Using uninitialized memory
+    vDbgPrintExWithPrefix(Prefix,
+                          DPFLTR_IHVDRIVER_ID,
+                          DPFLTR_INFO_LEVEL,
+                          Format,
+                          Arguments);
+    va_end(Arguments);
+}
+
+#define Info(...)  \
+        __Info(__MODULE__ "|"  __FUNCTION__ ": ", __VA_ARGS__)
+
+#endif  // _XENHID_DBG_PRINT_H
diff --git a/src/xenhid/driver.c b/src/xenhid/driver.c
new file mode 100644 (file)
index 0000000..9436518
--- /dev/null
@@ -0,0 +1,218 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, 
+ * with or without modification, are permitted provided 
+ * that the following conditions are met:
+ * 
+ * *   Redistributions of source code must retain the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer in the documentation and/or other 
+ *     materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE.
+ */
+
+#include <ntddk.h>
+#include <procgrp.h>
+#include <ntstrsafe.h>
+#include <hidport.h>
+
+#include <version.h>
+
+#include "fdo.h"
+#include "driver.h"
+#include "dbg_print.h"
+#include "assert.h"
+#include "util.h"
+
+typedef struct _XENHID_DRIVER {
+    PDRIVER_OBJECT      DriverObject;
+} XENHID_DRIVER, *PXENHID_DRIVER;
+
+static XENHID_DRIVER    Driver;
+
+static FORCEINLINE VOID
+__DriverSetDriverObject(
+    IN  PDRIVER_OBJECT  DriverObject
+    )
+{
+    Driver.DriverObject = DriverObject;
+}
+
+static FORCEINLINE PDRIVER_OBJECT
+__DriverGetDriverObject(
+    VOID
+    )
+{
+    return Driver.DriverObject;
+}
+
+PDRIVER_OBJECT
+DriverGetDriverObject(
+    VOID
+    )
+{
+    return __DriverGetDriverObject();
+}
+
+DRIVER_UNLOAD       DriverUnload;
+
+VOID
+DriverUnload(
+    IN  PDRIVER_OBJECT  DriverObject
+    )
+{
+    ASSERT3P(DriverObject, ==, __DriverGetDriverObject());
+
+    Trace("====>\n");
+
+    Info("XENHID %d.%d.%d (%d) (%02d.%02d.%04d)\n",
+         MAJOR_VERSION,
+         MINOR_VERSION,
+         MICRO_VERSION,
+         BUILD_NUMBER,
+         DAY,
+         MONTH,
+         YEAR);
+
+    __DriverSetDriverObject(NULL);
+
+    ASSERT(IsZeroMemory(&Driver, sizeof (XENHID_DRIVER)));
+
+    Trace("<====\n");
+}
+
+DRIVER_ADD_DEVICE   AddDevice;
+
+NTSTATUS
+AddDevice(
+    IN  PDRIVER_OBJECT  DriverObject,
+    IN  PDEVICE_OBJECT  DeviceObject
+    )
+{
+    PHID_DEVICE_EXTENSION   Hid;
+    PXENHID_FDO             Fdo;
+    PDEVICE_OBJECT          LowerDeviceObject;
+    NTSTATUS                status;
+
+    ASSERT3P(__DriverGetDriverObject(), ==, DriverObject);
+
+    Hid = DeviceObject->DeviceExtension;
+    Fdo = Hid->MiniDeviceExtension;
+    LowerDeviceObject = Hid->NextDeviceObject;
+
+    status = FdoCreate(Fdo,
+                       DeviceObject,
+                       LowerDeviceObject);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
+    return status;
+
+fail1:
+    Error("fail1 %08x\n", status);
+    return status;
+}
+
+DRIVER_DISPATCH Dispatch;
+
+NTSTATUS 
+Dispatch(
+    IN PDEVICE_OBJECT   DeviceObject,
+    IN PIRP             Irp
+    )
+{
+    PHID_DEVICE_EXTENSION   Hid;
+    PXENHID_FDO             Fdo;
+    NTSTATUS                status;
+
+    Hid = DeviceObject->DeviceExtension;
+    Fdo = Hid->MiniDeviceExtension;
+
+    status = FdoDispatch(Fdo, Irp);
+
+    return status;
+}
+
+DRIVER_INITIALIZE   DriverEntry;
+
+NTSTATUS
+DriverEntry(
+    IN  PDRIVER_OBJECT          DriverObject,
+    IN  PUNICODE_STRING         RegistryPath
+    )
+{
+    HID_MINIDRIVER_REGISTRATION Minidriver;
+    ULONG                       Index;
+    NTSTATUS                    status;
+
+    ASSERT3P(__DriverGetDriverObject(), ==, NULL);
+
+    ExInitializeDriverRuntime(DrvRtPoolNxOptIn);
+    WdmlibProcgrpInitialize();
+
+    Trace("====>\n");
+
+    __DriverSetDriverObject(DriverObject);
+
+    Driver.DriverObject->DriverUnload = DriverUnload;
+
+    Info("XENHID %d.%d.%d (%d) (%02d.%02d.%04d)\n",
+         MAJOR_VERSION,
+         MINOR_VERSION,
+         MICRO_VERSION,
+         BUILD_NUMBER,
+         DAY,
+         MONTH,
+         YEAR);
+
+    DriverObject->DriverExtension->AddDevice = AddDevice;
+
+    for (Index = 0; Index <= IRP_MJ_MAXIMUM_FUNCTION; Index++) {
+#pragma prefast(suppress:28169) // No __drv_dispatchType annotation
+#pragma prefast(suppress:28168) // No matching __drv_dispatchType annotation for IRP_MJ_CREATE
+        DriverObject->MajorFunction[Index] = Dispatch;
+    }
+
+    RtlZeroMemory(&Minidriver, sizeof(Minidriver));
+    Minidriver.Revision             = HID_REVISION;
+    Minidriver.DriverObject         = DriverObject;
+    Minidriver.RegistryPath         = RegistryPath;
+    Minidriver.DeviceExtensionSize  = FdoGetSize();
+    Minidriver.DevicesArePolled     = FALSE;
+
+    status = HidRegisterMinidriver(&Minidriver);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    Trace("<====\n");
+
+    return STATUS_SUCCESS;
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    __DriverSetDriverObject(NULL);
+
+    ASSERT(IsZeroMemory(&Driver, sizeof (XENHID_DRIVER)));
+
+    return status;
+}
diff --git a/src/xenhid/driver.h b/src/xenhid/driver.h
new file mode 100644 (file)
index 0000000..6202017
--- /dev/null
@@ -0,0 +1,40 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, 
+ * with or without modification, are permitted provided 
+ * that the following conditions are met:
+ * 
+ * *   Redistributions of source code must retain the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer in the documentation and/or other 
+ *     materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE.
+ */ 
+
+#ifndef _XENHID_DRIVER_H
+#define _XENHID_DRIVER_H
+
+extern PDRIVER_OBJECT
+DriverGetDriverObject(
+    VOID
+    );
+
+#endif  // _XENHID_DRIVER_H
diff --git a/src/xenhid/fdo.c b/src/xenhid/fdo.c
new file mode 100644 (file)
index 0000000..e0630ce
--- /dev/null
@@ -0,0 +1,723 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, 
+ * with or without modification, are permitted provided 
+ * that the following conditions are met:
+ * 
+ * *   Redistributions of source code must retain the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer in the documentation and/or other 
+ *     materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE.
+ */ 
+
+#define INITGUID
+#include <ntddk.h>
+#include <procgrp.h>
+#include <ntstrsafe.h>
+#include <hidport.h>
+
+#include <hid_interface.h>
+
+#include "fdo.h"
+#include "driver.h"
+#include "dbg_print.h"
+#include "assert.h"
+#include "util.h"
+
+struct _XENHID_FDO {
+    PDEVICE_OBJECT          DeviceObject;
+    PDEVICE_OBJECT          LowerDeviceObject;
+    BOOLEAN                 Enabled;
+    XENHID_HID_INTERFACE    HidInterface;
+    IO_CSQ                  Queue;
+    KSPIN_LOCK              Lock;
+    LIST_ENTRY              List;
+};
+
+ULONG
+FdoGetSize(
+    VOID
+    )
+{
+    return sizeof(XENHID_FDO);
+}
+
+VOID
+FdoCsqInsertIrp(
+    IN  PIO_CSQ Csq,
+    IN  PIRP    Irp
+    )
+{
+    PXENHID_FDO Fdo = CONTAINING_RECORD(Csq, XENHID_FDO, Queue);
+
+    InsertTailList(&Fdo->List, &Irp->Tail.Overlay.ListEntry);
+}
+
+VOID
+FdoCsqRemoveIrp(
+    IN  PIO_CSQ Csq,
+    IN  PIRP    Irp
+    )
+{
+    UNREFERENCED_PARAMETER(Csq);
+
+    RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
+}
+
+PIRP
+FdoCsqPeekNextIrp(
+    IN  PIO_CSQ Csq,
+    IN  PIRP    Irp,
+    IN  PVOID   Context
+    )
+{
+    PXENHID_FDO Fdo = CONTAINING_RECORD(Csq, XENHID_FDO, Queue);
+    PLIST_ENTRY ListEntry;
+    PIRP        NextIrp;
+
+    UNREFERENCED_PARAMETER(Context);
+
+    if (Irp == NULL)
+        ListEntry = Fdo->List.Flink;
+    else
+        ListEntry = Irp->Tail.Overlay.ListEntry.Flink;
+
+    NextIrp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.ListEntry);
+    // should walk through the list until a match against Context is found
+    return NextIrp;
+}
+
+VOID
+FdoCsqAcquireLock(
+    IN  PIO_CSQ Csq,
+    OUT PKIRQL  Irql
+    )
+{
+    PXENHID_FDO Fdo = CONTAINING_RECORD(Csq, XENHID_FDO, Queue);
+
+    KeAcquireSpinLock(&Fdo->Lock, Irql);
+}
+
+VOID
+FdoCsqReleaseLock(
+    IN  PIO_CSQ Csq,
+    IN  KIRQL   Irql
+    )
+{
+    PXENHID_FDO Fdo = CONTAINING_RECORD(Csq, XENHID_FDO, Queue);
+
+#pragma warning(suppress:26110)
+    KeReleaseSpinLock(&Fdo->Lock, Irql);
+}
+
+VOID
+FdoCsqCompleteCanceledIrp(
+    IN  PIO_CSQ Csq,
+    IN  PIRP    Irp
+    )
+{
+    UNREFERENCED_PARAMETER(Csq);
+
+    Irp->IoStatus.Information = 0;
+    Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+}
+
+static DECLSPEC_NOINLINE BOOLEAN
+FdoHidCallback(
+    IN  PVOID       Argument,
+    IN  PVOID       Buffer,
+    IN  ULONG       Length
+    )
+{
+    PXENHID_FDO     Fdo = Argument;
+    BOOLEAN         Completed = FALSE;
+    PIRP            Irp;
+
+    Irp = IoCsqRemoveNextIrp(&Fdo->Queue, NULL);
+    if (Irp == NULL)
+        goto done;
+
+    RtlCopyMemory(Irp->UserBuffer,
+                  Buffer,
+                  Length);
+    Irp->IoStatus.Information = Length;
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    Completed = TRUE;
+
+done:
+    return Completed;
+}
+
+static DECLSPEC_NOINLINE NTSTATUS
+FdoD3ToD0(
+    IN  PXENHID_FDO Fdo
+    )
+{
+    NTSTATUS        status;
+
+    Trace("=====>\n");
+
+    if (Fdo->Enabled)
+        goto done;
+
+    status = XENHID_HID(Acquire,
+                        &Fdo->HidInterface);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    status = XENHID_HID(Enable,
+                        &Fdo->HidInterface,
+                        FdoHidCallback,
+                        Fdo);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    Fdo->Enabled = TRUE;
+done:
+    Trace("<=====\n");
+    return STATUS_SUCCESS;
+
+fail2:
+    Error("fail2\n");
+
+    XENHID_HID(Release,
+               &Fdo->HidInterface);
+
+fail1:
+    Error("fail1 %08x\n", status);
+    return status;
+}
+
+static DECLSPEC_NOINLINE VOID
+FdoD0ToD3(
+    IN  PXENHID_FDO Fdo
+    )
+{
+    Trace("=====>\n");
+
+    if (!Fdo->Enabled)
+        goto done;
+
+    XENHID_HID(Disable,
+               &Fdo->HidInterface);
+
+    XENHID_HID(Release,
+               &Fdo->HidInterface);
+
+    Fdo->Enabled = FALSE;
+done:
+    Trace("<=====\n");
+}
+
+static DECLSPEC_NOINLINE NTSTATUS
+FdoDispatchDefault(
+    IN  PXENHID_FDO Fdo,
+    IN  PIRP        Irp
+    )
+{
+    NTSTATUS        status;
+
+    IoSkipCurrentIrpStackLocation(Irp);
+    status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+
+    return status;
+}
+
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
+static NTSTATUS
+__FdoForwardIrpSynchronously(
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  PIRP            Irp,
+    IN  PVOID           Context
+    )
+{
+    PKEVENT             Event = Context;
+
+    UNREFERENCED_PARAMETER(DeviceObject);
+    UNREFERENCED_PARAMETER(Irp);
+
+    KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
+
+    return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+static NTSTATUS
+FdoForwardIrpSynchronously(
+    IN  PXENHID_FDO     Fdo,
+    IN  PIRP            Irp
+    )
+{
+    KEVENT              Event;
+    NTSTATUS            status;
+
+    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+    KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+    IoCopyCurrentIrpStackLocationToNext(Irp);
+    IoSetCompletionRoutine(Irp,
+                           __FdoForwardIrpSynchronously,
+                           &Event,
+                           TRUE,
+                           TRUE,
+                           TRUE);
+
+    status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+    if (status == STATUS_PENDING) {
+        (VOID) KeWaitForSingleObject(&Event,
+                                     Executive,
+                                     KernelMode,
+                                     FALSE,
+                                     NULL);
+        status = Irp->IoStatus.Status;
+    } else {
+        ASSERT3U(status, ==, Irp->IoStatus.Status);
+    }
+
+    Trace("%08x\n", status);
+
+    return status;
+}
+
+static DECLSPEC_NOINLINE NTSTATUS\r
+FdoStartDevice(\r
+    IN  PXENHID_FDO     Fdo,\r
+    IN  PIRP            Irp\r
+    )\r
+{\r
+    NTSTATUS            status;\r
+\r
+    status = FdoForwardIrpSynchronously(Fdo, Irp);\r
+    if (!NT_SUCCESS(status))\r
+        goto fail1;\r
+\r
+    status = FdoD3ToD0(Fdo);\r
+    if (!NT_SUCCESS(status))\r
+        goto fail2;\r
+\r
+    status = Irp->IoStatus.Status;\r
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);\r
+\r
+    return status;\r
+\r
+fail2:\r
+    Error("fail2\n");\r
+\r
+fail1:\r
+    Error("fail1 (%08x)\n", status);\r
+\r
+    Irp->IoStatus.Status = status;\r
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);\r
+\r
+    return status;\r
+}\r
+\r
+static DECLSPEC_NOINLINE NTSTATUS\r
+FdoStopDevice(\r
+    IN  PXENHID_FDO Fdo,\r
+    IN  PIRP        Irp\r
+    )\r
+{\r
+    NTSTATUS        status;\r
+\r
+    FdoD0ToD3(Fdo);\r
+\r
+    Irp->IoStatus.Status = STATUS_SUCCESS;\r
+\r
+    IoSkipCurrentIrpStackLocation(Irp);\r
+    status = IoCallDriver(Fdo->LowerDeviceObject, Irp);\r
+\r
+    return status;\r
+}\r
+\r
+static DECLSPEC_NOINLINE NTSTATUS\r
+FdoRemoveDevice(\r
+    IN  PXENHID_FDO Fdo,\r
+    IN  PIRP        Irp\r
+    )\r
+{\r
+    NTSTATUS        status;\r
+\r
+    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);\r
+\r
+    FdoD0ToD3(Fdo);\r
+\r
+    Irp->IoStatus.Status = STATUS_SUCCESS;\r
+\r
+    IoSkipCurrentIrpStackLocation(Irp);\r
+    status = IoCallDriver(Fdo->LowerDeviceObject, Irp);\r
+\r
+    FdoDestroy(Fdo);\r
+\r
+    return status;\r
+}
+
+static DECLSPEC_NOINLINE NTSTATUS
+FdoDispatchPnp(
+    IN  PXENHID_FDO Fdo,
+    IN  PIRP        Irp
+    )
+{
+    PIO_STACK_LOCATION  StackLocation;
+    NTSTATUS            status;
+
+    StackLocation = IoGetCurrentIrpStackLocation(Irp);
+
+    switch (StackLocation->MinorFunction) {
+    case IRP_MN_START_DEVICE:
+        status = FdoStartDevice(Fdo, Irp);
+        break;
+
+    case IRP_MN_REMOVE_DEVICE:
+        status = FdoRemoveDevice(Fdo, Irp);
+        break;
+
+    case IRP_MN_STOP_DEVICE:
+        status = FdoStopDevice(Fdo, Irp);
+        break;
+
+    case IRP_MN_QUERY_STOP_DEVICE:
+    case IRP_MN_CANCEL_STOP_DEVICE:
+    case IRP_MN_QUERY_REMOVE_DEVICE:
+    case IRP_MN_SURPRISE_REMOVAL:
+    case IRP_MN_CANCEL_REMOVE_DEVICE:
+        Irp->IoStatus.Status = STATUS_SUCCESS;\r
+        IoSkipCurrentIrpStackLocation(Irp);\r
+        status = IoCallDriver(Fdo->LowerDeviceObject, Irp);\r
+        break;
+
+    default:
+        IoSkipCurrentIrpStackLocation(Irp);
+        status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+        break;
+    }
+
+    return status;
+}
+
+static DECLSPEC_NOINLINE NTSTATUS
+FdoDispatchInternal(
+    IN  PXENHID_FDO Fdo,
+    IN  PIRP        Irp
+    )
+{
+    PIO_STACK_LOCATION  StackLocation;
+    ULONG               Type3Input;
+    ULONG               IoControlCode;
+    ULONG               InputLength;
+    ULONG               OutputLength;
+    PVOID               Buffer;
+    ULONG               Returned;
+    PHID_XFER_PACKET    Packet;
+    NTSTATUS            status;
+
+    StackLocation = IoGetCurrentIrpStackLocation(Irp);
+    IoControlCode = StackLocation->Parameters.DeviceIoControl.IoControlCode;
+    Type3Input = (ULONG)(ULONG_PTR)StackLocation->Parameters.DeviceIoControl.Type3InputBuffer;
+    InputLength = StackLocation->Parameters.DeviceIoControl.InputBufferLength;
+    OutputLength = StackLocation->Parameters.DeviceIoControl.OutputBufferLength;
+    Buffer = Irp->UserBuffer;
+    Packet = Irp->UserBuffer;
+
+    switch (IoControlCode) {
+    case IOCTL_HID_GET_DEVICE_ATTRIBUTES:
+        status = XENHID_HID(GetDeviceAttributes,
+                            &Fdo->HidInterface,
+                            Buffer,
+                            OutputLength,
+                            &Returned);
+        if (NT_SUCCESS(status))
+            Irp->IoStatus.Information = (ULONG_PTR)Returned;
+        break;
+
+    case IOCTL_HID_GET_DEVICE_DESCRIPTOR:
+        status = XENHID_HID(GetDeviceDescriptor,
+                            &Fdo->HidInterface,
+                            Buffer,
+                            OutputLength,
+                            &Returned);
+        if (NT_SUCCESS(status))
+            Irp->IoStatus.Information = (ULONG_PTR)Returned;
+        break;
+
+    case IOCTL_HID_GET_REPORT_DESCRIPTOR:
+        status = XENHID_HID(GetReportDescriptor,
+                            &Fdo->HidInterface,
+                            Buffer,
+                            OutputLength,
+                            &Returned);
+        if (NT_SUCCESS(status))
+            Irp->IoStatus.Information = (ULONG_PTR)Returned;
+        break;
+
+    case IOCTL_HID_GET_STRING:
+        status = XENHID_HID(GetString,
+                            &Fdo->HidInterface,
+                            Type3Input,
+                            Buffer,
+                            OutputLength,
+                            &Returned);
+        if (NT_SUCCESS(status))
+            Irp->IoStatus.Information = (ULONG_PTR)Returned;
+        break;
+
+    case IOCTL_HID_GET_INDEXED_STRING:
+        status = XENHID_HID(GetIndexedString,
+                            &Fdo->HidInterface,
+                            Type3Input,
+                            Buffer,
+                            OutputLength,
+                            &Returned);
+        if (NT_SUCCESS(status))
+            Irp->IoStatus.Information = (ULONG_PTR)Returned;
+
+        break;
+
+    case IOCTL_HID_GET_FEATURE:
+        status = XENHID_HID(GetFeature,
+                            &Fdo->HidInterface,
+                            Packet->reportId,
+                            Packet->reportBuffer,
+                            Packet->reportBufferLen,
+                            &Returned);
+        if (NT_SUCCESS(status))
+            Irp->IoStatus.Information = (ULONG_PTR)Returned;
+        break;
+
+    case IOCTL_HID_SET_FEATURE:
+        status = XENHID_HID(SetFeature,
+                            &Fdo->HidInterface,
+                            Packet->reportId,
+                            Packet->reportBuffer,
+                            Packet->reportBufferLen);
+        break;
+
+    case IOCTL_HID_GET_INPUT_REPORT:
+        status = XENHID_HID(GetInputReport,
+                            &Fdo->HidInterface,
+                            Packet->reportId,
+                            Packet->reportBuffer,
+                            Packet->reportBufferLen,
+                            &Returned);
+        if (NT_SUCCESS(status))
+            Irp->IoStatus.Information = (ULONG_PTR)Returned;
+        break;
+
+    case IOCTL_HID_SET_OUTPUT_REPORT:
+        status = XENHID_HID(SetOutputReport,
+                            &Fdo->HidInterface,
+                            Packet->reportId,
+                            Packet->reportBuffer,
+                            Packet->reportBufferLen);
+        break;
+
+    case IOCTL_HID_READ_REPORT:
+        status = STATUS_PENDING;
+        IoCsqInsertIrp(&Fdo->Queue, Irp, NULL);
+        XENHID_HID(ReadReport,
+                   &Fdo->HidInterface);
+        break;
+
+    case IOCTL_HID_WRITE_REPORT:
+        status = XENHID_HID(WriteReport,
+                            &Fdo->HidInterface,
+                            Packet->reportId,
+                            Packet->reportBuffer,
+                            Packet->reportBufferLen);
+        break;
+
+    // Other HID IOCTLs are failed as not supported
+    default:
+        status = STATUS_NOT_SUPPORTED;
+        break;
+    }
+
+    if (status != STATUS_PENDING) {
+        Irp->IoStatus.Status = status;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    }
+    return status;
+}
+
+NTSTATUS
+FdoDispatch(
+    IN  PXENHID_FDO Fdo,
+    IN  PIRP        Irp
+    )
+{
+    PIO_STACK_LOCATION  StackLocation;
+    NTSTATUS            status;
+
+    StackLocation = IoGetCurrentIrpStackLocation(Irp);
+    switch (StackLocation->MajorFunction) {
+    case IRP_MJ_INTERNAL_DEVICE_CONTROL:
+        status = FdoDispatchInternal(Fdo, Irp);
+        break;
+
+    case IRP_MJ_PNP:
+        status = FdoDispatchPnp(Fdo, Irp);
+        break;
+
+    default:
+        status = FdoDispatchDefault(Fdo, Irp);
+        break;
+    }
+
+    return status;
+}
+
+static FORCEINLINE NTSTATUS
+FdoQueryHidInterface(
+    IN  PXENHID_FDO     Fdo
+    )
+{
+    KEVENT              Event;
+    IO_STATUS_BLOCK     StatusBlock;
+    PIRP                Irp;
+    PIO_STACK_LOCATION  StackLocation;
+    NTSTATUS            status;
+
+    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+    KeInitializeEvent(&Event, NotificationEvent, FALSE);
+    RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK));
+
+    Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
+                                       Fdo->LowerDeviceObject,
+                                       NULL,
+                                       0,
+                                       NULL,
+                                       &Event,
+                                       &StatusBlock);
+
+    status = STATUS_UNSUCCESSFUL;
+    if (Irp == NULL)
+        goto fail1;
+
+    StackLocation = IoGetNextIrpStackLocation(Irp);
+    StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE;
+
+    StackLocation->Parameters.QueryInterface.InterfaceType = &GUID_XENHID_HID_INTERFACE;
+    StackLocation->Parameters.QueryInterface.Size = sizeof (XENHID_HID_INTERFACE);
+    StackLocation->Parameters.QueryInterface.Version = XENHID_HID_INTERFACE_VERSION_MAX;
+    StackLocation->Parameters.QueryInterface.Interface = (PINTERFACE)&Fdo->HidInterface;
+
+    Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+
+    status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+    if (status == STATUS_PENDING) {
+        (VOID) KeWaitForSingleObject(&Event,
+                                     Executive,
+                                     KernelMode,
+                                     FALSE,
+                                     NULL);
+        status = StatusBlock.Status;
+    }
+
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    return STATUS_SUCCESS;
+
+fail2:
+    Error("fail2\n");
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+    return status;
+}
+
+NTSTATUS
+FdoCreate(
+    IN  PXENHID_FDO     Fdo,
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  PDEVICE_OBJECT  LowerDeviceObject
+    )
+{
+    NTSTATUS            status;
+
+    Trace("=====>\n");
+
+    Fdo->DeviceObject = DeviceObject;
+    Fdo->LowerDeviceObject = LowerDeviceObject;
+
+    InitializeListHead(&Fdo->List);
+    KeInitializeSpinLock(&Fdo->Lock);
+
+    status = IoCsqInitialize(&Fdo->Queue,
+                             FdoCsqInsertIrp,
+                             FdoCsqRemoveIrp,
+                             FdoCsqPeekNextIrp,
+                             FdoCsqAcquireLock,
+                             FdoCsqReleaseLock,
+                             FdoCsqCompleteCanceledIrp);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    status = FdoQueryHidInterface(Fdo);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    Trace("<=====\n");
+    return STATUS_SUCCESS;
+
+fail2:
+    Error("fail2\n");
+
+    RtlZeroMemory(&Fdo->Queue, sizeof(IO_CSQ));
+
+fail1:
+    Error("fail1 %08x\n", status);
+
+    RtlZeroMemory(&Fdo->List, sizeof(LIST_ENTRY));
+    RtlZeroMemory(&Fdo->Lock, sizeof(KSPIN_LOCK));
+
+    Fdo->DeviceObject = NULL;
+    Fdo->LowerDeviceObject = NULL;
+
+    ASSERT(IsZeroMemory(Fdo, sizeof(XENHID_FDO)));
+    return status;
+}
+
+VOID
+FdoDestroy(
+    IN  PXENHID_FDO Fdo
+    )
+{
+    Trace("=====>\n");
+
+    RtlZeroMemory(&Fdo->HidInterface,
+                  sizeof(XENHID_HID_INTERFACE));
+    RtlZeroMemory(&Fdo->Queue, sizeof(IO_CSQ));
+    RtlZeroMemory(&Fdo->List, sizeof(LIST_ENTRY));
+    RtlZeroMemory(&Fdo->Lock, sizeof(KSPIN_LOCK));
+
+    Fdo->DeviceObject = NULL;
+    Fdo->LowerDeviceObject = NULL;
+
+    ASSERT(IsZeroMemory(Fdo, sizeof(XENHID_FDO)));
+    Trace("<=====\n");
+}
diff --git a/src/xenhid/fdo.h b/src/xenhid/fdo.h
new file mode 100644 (file)
index 0000000..f88fc24
--- /dev/null
@@ -0,0 +1,60 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, 
+ * with or without modification, are permitted provided 
+ * that the following conditions are met:
+ * 
+ * *   Redistributions of source code must retain the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer in the documentation and/or other 
+ *     materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE.
+ */ 
+
+#ifndef _XENHID_FDO_H
+#define _XENHID_FDO_H
+
+typedef struct _XENHID_FDO XENHID_FDO, *PXENHID_FDO;
+
+extern ULONG
+FdoGetSize(
+    VOID
+    );
+
+extern NTSTATUS
+FdoDispatch(
+    IN  PXENHID_FDO Fdo,
+    IN  PIRP        Irp
+    );
+
+extern NTSTATUS
+FdoCreate(
+    IN  PXENHID_FDO     Fdo,
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  PDEVICE_OBJECT  LowerDeviceObject
+    );
+
+extern VOID
+FdoDestroy(
+    IN  PXENHID_FDO Fdo
+    );
+
+#endif  // _XENHID_FDO_H
diff --git a/src/xenhid/types.h b/src/xenhid/types.h
new file mode 100644 (file)
index 0000000..2517c47
--- /dev/null
@@ -0,0 +1,48 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, 
+ * with or without modification, are permitted provided 
+ * that the following conditions are met:
+ * 
+ * *   Redistributions of source code must retain the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer in the documentation and/or other 
+ *     materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE.
+ */
+
+#ifndef _XENHID_TYPES_H
+#define _XENHID_TYPES_H
+
+typedef enum _DEVICE_PNP_STATE {
+    Invalid = 0,
+    Present,        // PDO only
+    Enumerated,     // PDO only
+    Added,          // FDO only
+    Started,
+    StopPending,
+    Stopped,
+    RemovePending,
+    SurpriseRemovePending,
+    Deleted
+} DEVICE_PNP_STATE, *PDEVICE_PNP_STATE;
+
+#endif  // _XENHID_TYPES_H
diff --git a/src/xenhid/util.h b/src/xenhid/util.h
new file mode 100644 (file)
index 0000000..f294db7
--- /dev/null
@@ -0,0 +1,361 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * *   Redistributions of source code must retain the above
+ *     copyright notice, this list of conditions and the
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the
+ *     following disclaimer in the documentation and/or other
+ *     materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _XENHID_UTIL_H
+#define _XENHID_UTIL_H
+
+#include <ntddk.h>
+
+#include "assert.h"
+
+#define        P2ROUNDUP(_x, _a)   \
+        (-(-(_x) & -(_a)))
+
+static FORCEINLINE LONG
+__ffs(
+    IN  unsigned long long  mask
+    )
+{
+    unsigned char           *array = (unsigned char *)&mask;
+    unsigned int            byte;
+    unsigned int            bit;
+    unsigned char           val;
+
+    val = 0;
+
+    byte = 0;
+    while (byte < 8) {
+        val = array[byte];
+
+        if (val != 0)
+            break;
+
+        byte++;
+    }
+    if (byte == 8)
+        return -1;
+
+    bit = 0;
+    while (bit < 8) {
+        if (val & 0x01)
+            break;
+
+        val >>= 1;
+        bit++;
+    }
+
+    return (byte * 8) + bit;
+}
+
+#define __ffu(_mask)  \
+        __ffs(~(_mask))
+
+static FORCEINLINE VOID
+__CpuId(
+    IN  ULONG   Leaf,
+    OUT PULONG  EAX OPTIONAL,
+    OUT PULONG  EBX OPTIONAL,
+    OUT PULONG  ECX OPTIONAL,
+    OUT PULONG  EDX OPTIONAL
+    )
+{
+    ULONG       Value[4] = {0};
+
+    __cpuid(Value, Leaf);
+
+    if (EAX)
+        *EAX = Value[0];
+
+    if (EBX)
+        *EBX = Value[1];
+
+    if (ECX)
+        *ECX = Value[2];
+
+    if (EDX)
+        *EDX = Value[3];
+}
+
+static FORCEINLINE LONG
+__InterlockedAdd(
+    IN  LONG    *Value,
+    IN  LONG    Delta
+    )
+{
+    LONG        New;
+    LONG        Old;
+
+    do {
+        Old = *Value;
+        New = Old + Delta;
+    } while (InterlockedCompareExchange(Value, New, Old) != Old);
+
+    return New;
+}
+
+static FORCEINLINE LONG
+__InterlockedSubtract(
+    IN  LONG    *Value,
+    IN  LONG    Delta
+    )
+{
+    LONG        New;
+    LONG        Old;
+
+    do {
+        Old = *Value;
+        New = Old - Delta;
+    } while (InterlockedCompareExchange(Value, New, Old) != Old);
+
+    return New;
+}
+
+__checkReturn
+static FORCEINLINE PVOID
+__AllocatePoolWithTag(
+    IN  POOL_TYPE   PoolType,
+    IN  SIZE_T      NumberOfBytes,
+    IN  ULONG       Tag
+    )
+{
+    PUCHAR          Buffer;
+
+    __analysis_assume(PoolType == NonPagedPool ||
+                      PoolType == PagedPool);
+
+#pragma warning(suppress:28160) // annotation error
+    Buffer = ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag);
+    if (Buffer == NULL)
+        return NULL;
+
+    RtlZeroMemory(Buffer, NumberOfBytes);
+    return Buffer;
+}
+
+static FORCEINLINE VOID
+__FreePoolWithTag(
+    IN  PVOID   Buffer,
+    IN  ULONG   Tag
+    )
+{
+    ExFreePoolWithTag(Buffer, Tag);
+}
+
+static FORCEINLINE PMDL
+__AllocatePages(
+    IN  ULONG           Count
+    )
+{
+    PHYSICAL_ADDRESS    LowAddress;
+    PHYSICAL_ADDRESS    HighAddress;
+    LARGE_INTEGER       SkipBytes;
+    SIZE_T              TotalBytes;
+    PMDL                Mdl;
+    PUCHAR              MdlMappedSystemVa;
+    NTSTATUS            status;
+
+    LowAddress.QuadPart = 0ull;
+    HighAddress.QuadPart = ~0ull;
+    SkipBytes.QuadPart = 0ull;
+    TotalBytes = (SIZE_T)PAGE_SIZE * Count;
+
+    Mdl = MmAllocatePagesForMdlEx(LowAddress,
+                                  HighAddress,
+                                  SkipBytes,
+                                  TotalBytes,
+                                  MmCached,
+                                  MM_DONT_ZERO_ALLOCATION);
+
+    status = STATUS_NO_MEMORY;
+    if (Mdl == NULL)
+        goto fail1;
+
+    if (Mdl->ByteCount < TotalBytes)
+        goto fail2;
+
+    ASSERT((Mdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA |
+                             MDL_PARTIAL_HAS_BEEN_MAPPED |
+                             MDL_PARTIAL |
+                             MDL_PARENT_MAPPED_SYSTEM_VA |
+                             MDL_SOURCE_IS_NONPAGED_POOL |
+                             MDL_IO_SPACE)) == 0);
+
+    MdlMappedSystemVa = MmMapLockedPagesSpecifyCache(Mdl,
+                                                     KernelMode,
+                                                                            MmCached,
+                                                                            NULL,
+                                                                            FALSE,
+                                                                            NormalPagePriority);
+
+    status = STATUS_UNSUCCESSFUL;
+    if (MdlMappedSystemVa == NULL)
+        goto fail3;
+
+    ASSERT3P(MdlMappedSystemVa, ==, Mdl->MappedSystemVa);
+
+    RtlZeroMemory(MdlMappedSystemVa, Mdl->ByteCount);
+
+    return Mdl;
+
+fail3:
+    Error("fail3\n");
+
+fail2:
+    Error("fail2\n");
+
+    MmFreePagesFromMdl(Mdl);
+    ExFreePool(Mdl);
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return NULL;
+}
+
+#define __AllocatePage()    __AllocatePages(1)
+
+static FORCEINLINE VOID
+__FreePages(
+    IN PMDL    Mdl
+    )
+{
+    PUCHAR     MdlMappedSystemVa;
+
+    ASSERT(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA);
+    MdlMappedSystemVa = Mdl->MappedSystemVa;
+
+    MmUnmapLockedPages(MdlMappedSystemVa, Mdl);
+
+    MmFreePagesFromMdl(Mdl);
+    ExFreePool(Mdl);
+}
+
+#define __FreePage(_Mdl)    __FreePages(_Mdl)
+
+static FORCEINLINE PCHAR
+__strtok_r(
+    IN      PCHAR   Buffer,
+    IN      PCHAR   Delimiter,
+    IN OUT  PCHAR   *Context
+    )
+{
+    PCHAR           Token;
+    PCHAR           End;
+
+    if (Buffer != NULL)
+        *Context = Buffer;
+
+    Token = *Context;
+
+    if (Token == NULL)
+        return NULL;
+
+    while (*Token != '\0' &&
+           strchr(Delimiter, *Token) != NULL)
+        Token++;
+
+    if (*Token == '\0')
+        return NULL;
+
+    End = Token + 1;
+    while (*End != '\0' &&
+           strchr(Delimiter, *End) == NULL)
+        End++;
+
+    if (*End != '\0')
+        *End++ = '\0';
+
+    *Context = End;
+
+    return Token;
+}
+
+static FORCEINLINE PWCHAR
+__wcstok_r(
+    IN      PWCHAR  Buffer,
+    IN      PWCHAR  Delimiter,
+    IN OUT  PWCHAR  *Context
+    )
+{
+    PWCHAR          Token;
+    PWCHAR          End;
+
+    if (Buffer != NULL)
+        *Context = Buffer;
+
+    Token = *Context;
+
+    if (Token == NULL)
+        return NULL;
+
+    while (*Token != L'\0' &&
+           wcschr(Delimiter, *Token) != NULL)
+        Token++;
+
+    if (*Token == L'\0')
+        return NULL;
+
+    End = Token + 1;
+    while (*End != L'\0' &&
+           wcschr(Delimiter, *End) == NULL)
+        End++;
+
+    if (*End != L'\0')
+        *End++ = L'\0';
+
+    *Context = End;
+
+    return Token;
+}
+
+static FORCEINLINE CHAR
+__toupper(
+    IN  CHAR    Character
+    )
+{
+    if (Character < 'a' || Character > 'z')
+        return Character;
+
+    return 'A' + Character - 'a';
+}
+
+static FORCEINLINE CHAR
+__tolower(
+    IN  CHAR    Character
+    )
+{
+    if (Character < 'A' || Character > 'Z')
+        return Character;
+
+    return 'a' + Character - 'A';
+}
+
+#endif  // _XENHID_UTIL_H
diff --git a/src/xenhid/xenhid.rc b/src/xenhid/xenhid.rc
new file mode 100644 (file)
index 0000000..3363671
--- /dev/null
@@ -0,0 +1,56 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, 
+ * with or without modification, are permitted provided 
+ * that the following conditions are met:
+ * 
+ * *   Redistributions of source code must retain the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer in the documentation and/or other 
+ *     materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE.
+ */
+
+#include <windows.h>
+#include <ntverp.h>
+
+
+#undef VER_COMPANYNAME_STR
+#undef VER_PRODUCTNAME_STR
+#undef VER_PRODUCTVERSION
+#undef VER_PRODUCTVERSION_STR
+
+#include <version.h>
+
+#define        VER_COMPANYNAME_STR         VENDOR_NAME_STR
+#define VER_LEGALCOPYRIGHT_STR      "Copyright (c) Citrix Systems Inc."
+
+#define VER_PRODUCTNAME_STR         "XENHID"
+#define VER_PRODUCTVERSION          MAJOR_VERSION,MINOR_VERSION,MICRO_VERSION,BUILD_NUMBER
+#define VER_PRODUCTVERSION_STR      MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR
+
+#define VER_INTERNALNAME_STR        "XENHID.SYS"
+#define VER_FILEDESCRIPTION_STR     "XENHID"
+
+#define VER_FILETYPE                VFT_DRV
+#define VER_FILESUBTYPE             VFT2_DRV_SYSTEM
+
+#include <common.ver>
diff --git a/vs2013/configs.props b/vs2013/configs.props
new file mode 100644 (file)
index 0000000..43987fb
--- /dev/null
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
+       <ItemGroup Label="ProjectConfigurations"> 
+               <ProjectConfiguration Include="Windows 8 Debug|Win32"> 
+                       <Configuration>Windows 8 Debug</Configuration> 
+                       <Platform>Win32</Platform> 
+               </ProjectConfiguration> 
+               <ProjectConfiguration Include="Windows 7 Debug|Win32"> 
+                       <Configuration>Windows 7 Debug</Configuration> 
+                       <Platform>Win32</Platform> 
+               </ProjectConfiguration> 
+               <ProjectConfiguration Include="Windows Vista Debug|Win32"> 
+                       <Configuration>Windows Vista Debug</Configuration> 
+                       <Platform>Win32</Platform> 
+               </ProjectConfiguration> 
+               <ProjectConfiguration Include="Windows 8 Release|Win32"> 
+                       <Configuration>Windows 8 Release</Configuration> 
+                       <Platform>Win32</Platform> 
+               </ProjectConfiguration> 
+               <ProjectConfiguration Include="Windows 7 Release|Win32"> 
+                       <Configuration>Windows 7 Release</Configuration> 
+                       <Platform>Win32</Platform> 
+               </ProjectConfiguration> 
+               <ProjectConfiguration Include="Windows Vista Release|Win32"> 
+                       <Configuration>Windows Vista Release</Configuration> 
+                       <Platform>Win32</Platform> 
+               </ProjectConfiguration> 
+               <ProjectConfiguration Include="Windows 8 Debug|x64"> 
+                       <Configuration>Windows 8 Debug</Configuration> 
+                       <Platform>x64</Platform> 
+               </ProjectConfiguration> 
+               <ProjectConfiguration Include="Windows 7 Debug|x64"> 
+                       <Configuration>Windows 7 Debug</Configuration> 
+                       <Platform>x64</Platform> 
+               </ProjectConfiguration> 
+               <ProjectConfiguration Include="Windows Vista Debug|x64"> 
+                       <Configuration>Windows Vista Debug</Configuration> 
+                       <Platform>x64</Platform> 
+               </ProjectConfiguration> 
+               <ProjectConfiguration Include="Windows 8 Release|x64"> 
+                       <Configuration>Windows 8 Release</Configuration> 
+                       <Platform>x64</Platform> 
+               </ProjectConfiguration> 
+               <ProjectConfiguration Include="Windows 7 Release|x64"> 
+                       <Configuration>Windows 7 Release</Configuration> 
+                       <Platform>x64</Platform> 
+               </ProjectConfiguration> 
+               <ProjectConfiguration Include="Windows Vista Release|x64"> 
+                       <Configuration>Windows Vista Release</Configuration> 
+                       <Platform>x64</Platform> 
+               </ProjectConfiguration> 
+       </ItemGroup> 
+</Project>
diff --git a/vs2013/package/package.vcxproj b/vs2013/package/package.vcxproj
new file mode 100644 (file)
index 0000000..3c91542
--- /dev/null
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\configs.props" />
+  <PropertyGroup Label="PropertySheets">
+    <DriverType>WDM</DriverType>
+    <PlatformToolset>WindowsApplicationForDrivers8.1</PlatformToolset>
+    <ConfigurationType>Utility</ConfigurationType>
+    <DriverType>Package</DriverType>
+    <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
+  </PropertyGroup>
+  <PropertyGroup Label="Globals">
+    <Configuration>Windows Vista Debug</Configuration>
+    <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{73768CC9-DB26-4297-9EC8-1042F815EB15}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="..\targets.props" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <PropertyGroup>
+    <EnableInf2cat>true</EnableInf2cat>
+    <Inf2CatWindowsVersionList Condition="'$(Platform)'=='x64'">Vista_x64;7_x64;Server2008_x64;Server2008R2_x64;Server8_x64</Inf2CatWindowsVersionList>
+    <Inf2CatWindowsVersionList Condition="'$(Platform)'=='Win32'">Vista_x86;7_x86;Server2008_x86;8_x86</Inf2CatWindowsVersionList>
+    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+    <EnableDeployment>False</EnableDeployment>
+    <ImportToStore>False</ImportToStore>
+    <InstallMode>None</InstallMode>
+    <ScriptDeviceQuery>%PathToInf%</ScriptDeviceQuery>
+    <EnableVerifier>False</EnableVerifier>
+    <AllDrivers>False</AllDrivers>
+    <VerifyProjectOutput>True</VerifyProjectOutput>
+    <VerifyFlags>133563</VerifyFlags>
+    <IntDir>..\$(ProjectName)\$(ConfigurationName)\$(Platform)\</IntDir>
+    <OutDir>..\$(ConfigurationName)\$(Platform)\</OutDir>
+    <PackageDir>..\..\xenhid\$(DDKPlatform)</PackageDir>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\xenhid\xenhid.vcxproj">
+      <Project>{C3F96D4C-E441-47F7-A44C-D2D0543C1D18}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\xenhid_coinst\xenhid_coinst.vcxproj">
+      <Project>{2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <FilesToPackage Include="$(KIT)\Redist\DIFx\dpinst\EngMui\x86\dpinst.exe" Condition="'$(Platform)'=='Win32'" />
+    <FilesToPackage Include="$(KIT)\Redist\DIFx\dpinst\EngMui\x64\dpinst.exe" Condition="'$(Platform)'=='x64'" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/vs2013/package/package.vcxproj.user b/vs2013/package/package.vcxproj.user
new file mode 100644 (file)
index 0000000..70cfbf8
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <SignMode>TestSign</SignMode>
+    <TestCertificate>..\..\src\xenhid.pfx</TestCertificate>
+    <TimeStampServer>http://timestamp.verisign.com/scripts/timstamp.dll</TimeStampServer>
+  </PropertyGroup>
+</Project>
diff --git a/vs2013/targets.props b/vs2013/targets.props
new file mode 100644 (file)
index 0000000..c8aba92
--- /dev/null
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+       <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 8 Debug|Win32'"> 
+               <TargetVersion>Windows8</TargetVersion> 
+               <UseDebugLibraries>true</UseDebugLibraries> 
+       </PropertyGroup> 
+       <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 8 Release|Win32'"> 
+               <TargetVersion>Windows8</TargetVersion> 
+               <UseDebugLibraries>false</UseDebugLibraries> 
+       </PropertyGroup> 
+       <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 8 Debug|x64'"> 
+               <TargetVersion>Windows8</TargetVersion> 
+               <UseDebugLibraries>true</UseDebugLibraries> 
+       </PropertyGroup> 
+       <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 8 Release|x64'"> 
+               <TargetVersion>Windows8</TargetVersion> 
+               <UseDebugLibraries>false</UseDebugLibraries> 
+       </PropertyGroup>
+       <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 7 Debug|Win32'"> 
+               <TargetVersion>Windows7</TargetVersion> 
+               <UseDebugLibraries>true</UseDebugLibraries> 
+       </PropertyGroup> 
+       <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 7 Release|Win32'"> 
+               <TargetVersion>Windows7</TargetVersion> 
+               <UseDebugLibraries>false</UseDebugLibraries> 
+       </PropertyGroup> 
+       <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 7 Debug|x64'"> 
+               <TargetVersion>Windows7</TargetVersion> 
+               <UseDebugLibraries>true</UseDebugLibraries> 
+       </PropertyGroup> 
+       <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 7 Release|x64'"> 
+               <TargetVersion>Windows7</TargetVersion> 
+               <UseDebugLibraries>false</UseDebugLibraries> 
+       </PropertyGroup>
+       <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows Vista Debug|Win32'"> 
+               <TargetVersion>Vista</TargetVersion> 
+               <UseDebugLibraries>true</UseDebugLibraries> 
+       </PropertyGroup> 
+       <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows Vista Release|Win32'"> 
+               <TargetVersion>Vista</TargetVersion> 
+               <UseDebugLibraries>false</UseDebugLibraries> 
+       </PropertyGroup> 
+       <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows Vista Debug|x64'"> 
+               <TargetVersion>Vista</TargetVersion> 
+               <UseDebugLibraries>true</UseDebugLibraries> 
+       </PropertyGroup> 
+       <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows Vista Release|x64'"> 
+               <TargetVersion>Vista</TargetVersion> 
+               <UseDebugLibraries>false</UseDebugLibraries> 
+       </PropertyGroup>
+</Project>
diff --git a/vs2013/xenhid.sln b/vs2013/xenhid.sln
new file mode 100644 (file)
index 0000000..2af5afd
--- /dev/null
@@ -0,0 +1,138 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xenhid", "xenhid\xenhid.vcxproj", "{C3F96D4C-E441-47F7-A44C-D2D0543C1D18}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xenhid_coinst", "xenhid_coinst\xenhid_coinst.vcxproj", "{2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}"
+       ProjectSection(ProjectDependencies) = postProject
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18} = {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}
+       EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "package", "package\package.vcxproj", "{73768CC9-DB26-4297-9EC8-1042F815EB15}"
+       ProjectSection(ProjectDependencies) = postProject
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18} = {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44} = {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}
+       EndProjectSection
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Windows 7 Debug|Win32 = Windows 7 Debug|Win32
+               Windows 7 Debug|x64 = Windows 7 Debug|x64
+               Windows 7 Release|Win32 = Windows 7 Release|Win32
+               Windows 7 Release|x64 = Windows 7 Release|x64
+               Windows 8 Debug|Win32 = Windows 8 Debug|Win32
+               Windows 8 Debug|x64 = Windows 8 Debug|x64
+               Windows 8 Release|Win32 = Windows 8 Release|Win32
+               Windows 8 Release|x64 = Windows 8 Release|x64
+               Windows Vista Debug|Win32 = Windows Vista Debug|Win32
+               Windows Vista Debug|x64 = Windows Vista Debug|x64
+               Windows Vista Release|Win32 = Windows Vista Release|Win32
+               Windows Vista Release|x64 = Windows Vista Release|x64
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 7 Debug|Win32.ActiveCfg = Windows 7 Debug|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 7 Debug|Win32.Build.0 = Windows 7 Debug|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 7 Debug|Win32.Deploy.0 = Windows 7 Debug|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 7 Debug|x64.ActiveCfg = Windows 7 Debug|x64
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 7 Debug|x64.Build.0 = Windows 7 Debug|x64
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 7 Release|Win32.ActiveCfg = Windows 7 Release|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 7 Release|Win32.Build.0 = Windows 7 Release|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 7 Release|Win32.Deploy.0 = Windows 7 Release|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 7 Release|x64.ActiveCfg = Windows 7 Release|x64
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 7 Release|x64.Build.0 = Windows 7 Release|x64
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 8 Debug|Win32.ActiveCfg = Windows 8 Debug|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 8 Debug|Win32.Build.0 = Windows 8 Debug|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 8 Debug|Win32.Deploy.0 = Windows 8 Debug|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 8 Debug|x64.ActiveCfg = Windows 8 Debug|x64
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 8 Debug|x64.Build.0 = Windows 8 Debug|x64
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 8 Release|Win32.ActiveCfg = Windows 8 Release|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 8 Release|Win32.Build.0 = Windows 8 Release|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 8 Release|Win32.Deploy.0 = Windows 8 Release|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 8 Release|x64.ActiveCfg = Windows 8 Release|x64
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 8 Release|x64.Build.0 = Windows 8 Release|x64
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows Vista Debug|Win32.ActiveCfg = Windows Vista Debug|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows Vista Debug|Win32.Build.0 = Windows Vista Debug|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows Vista Debug|Win32.Deploy.0 = Windows Vista Debug|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows Vista Debug|x64.ActiveCfg = Windows Vista Debug|x64
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows Vista Debug|x64.Build.0 = Windows Vista Debug|x64
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows Vista Release|Win32.ActiveCfg = Windows Vista Release|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows Vista Release|Win32.Build.0 = Windows Vista Release|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows Vista Release|Win32.Deploy.0 = Windows Vista Release|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows Vista Release|x64.ActiveCfg = Windows Vista Release|x64
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows Vista Release|x64.Build.0 = Windows Vista Release|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 7 Debug|Win32.ActiveCfg = Windows 7 Debug|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 7 Debug|Win32.Build.0 = Windows 7 Debug|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 7 Debug|Win32.Deploy.0 = Windows 7 Debug|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 7 Debug|x64.ActiveCfg = Windows 7 Debug|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 7 Debug|x64.Build.0 = Windows 7 Debug|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 7 Debug|x64.Deploy.0 = Windows 7 Debug|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 7 Release|Win32.ActiveCfg = Windows 7 Release|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 7 Release|Win32.Build.0 = Windows 7 Release|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 7 Release|Win32.Deploy.0 = Windows 7 Release|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 7 Release|x64.ActiveCfg = Windows 7 Release|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 7 Release|x64.Build.0 = Windows 7 Release|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 7 Release|x64.Deploy.0 = Windows 7 Release|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 8 Debug|Win32.ActiveCfg = Windows 8 Debug|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 8 Debug|Win32.Build.0 = Windows 8 Debug|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 8 Debug|Win32.Deploy.0 = Windows 8 Debug|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 8 Debug|x64.ActiveCfg = Windows 8 Debug|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 8 Debug|x64.Build.0 = Windows 8 Debug|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 8 Debug|x64.Deploy.0 = Windows 8 Debug|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 8 Release|Win32.ActiveCfg = Windows 8 Release|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 8 Release|Win32.Build.0 = Windows 8 Release|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 8 Release|Win32.Deploy.0 = Windows 8 Release|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 8 Release|x64.ActiveCfg = Windows 8 Release|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 8 Release|x64.Build.0 = Windows 8 Release|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 8 Release|x64.Deploy.0 = Windows 8 Release|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows Vista Debug|Win32.ActiveCfg = Windows Vista Debug|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows Vista Debug|Win32.Build.0 = Windows Vista Debug|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows Vista Debug|Win32.Deploy.0 = Windows Vista Debug|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows Vista Debug|x64.ActiveCfg = Windows Vista Debug|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows Vista Debug|x64.Build.0 = Windows Vista Debug|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows Vista Debug|x64.Deploy.0 = Windows Vista Debug|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows Vista Release|Win32.ActiveCfg = Windows Vista Release|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows Vista Release|Win32.Build.0 = Windows Vista Release|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows Vista Release|Win32.Deploy.0 = Windows Vista Release|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows Vista Release|x64.ActiveCfg = Windows Vista Release|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows Vista Release|x64.Build.0 = Windows Vista Release|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows Vista Release|x64.Deploy.0 = Windows Vista Release|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 7 Debug|Win32.ActiveCfg = Windows 7 Debug|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 7 Debug|Win32.Build.0 = Windows 7 Debug|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 7 Debug|Win32.Deploy.0 = Windows 7 Debug|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 7 Debug|x64.ActiveCfg = Windows 7 Debug|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 7 Debug|x64.Build.0 = Windows 7 Debug|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 7 Debug|x64.Deploy.0 = Windows 7 Debug|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 7 Release|Win32.ActiveCfg = Windows 7 Release|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 7 Release|Win32.Build.0 = Windows 7 Release|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 7 Release|Win32.Deploy.0 = Windows 7 Release|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 7 Release|x64.ActiveCfg = Windows 7 Release|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 7 Release|x64.Build.0 = Windows 7 Release|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 7 Release|x64.Deploy.0 = Windows 7 Release|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 8 Debug|Win32.ActiveCfg = Windows 8 Debug|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 8 Debug|Win32.Build.0 = Windows 8 Debug|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 8 Debug|Win32.Deploy.0 = Windows 8 Debug|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 8 Debug|x64.ActiveCfg = Windows 8 Debug|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 8 Debug|x64.Build.0 = Windows 8 Debug|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 8 Debug|x64.Deploy.0 = Windows 8 Debug|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 8 Release|Win32.ActiveCfg = Windows 8 Release|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 8 Release|Win32.Build.0 = Windows 8 Release|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 8 Release|Win32.Deploy.0 = Windows 8 Release|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 8 Release|x64.ActiveCfg = Windows 8 Release|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 8 Release|x64.Build.0 = Windows 8 Release|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 8 Release|x64.Deploy.0 = Windows 8 Release|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows Vista Debug|Win32.ActiveCfg = Windows Vista Debug|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows Vista Debug|Win32.Build.0 = Windows Vista Debug|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows Vista Debug|Win32.Deploy.0 = Windows Vista Debug|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows Vista Debug|x64.ActiveCfg = Windows Vista Debug|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows Vista Debug|x64.Build.0 = Windows Vista Debug|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows Vista Debug|x64.Deploy.0 = Windows Vista Debug|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows Vista Release|Win32.ActiveCfg = Windows Vista Release|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows Vista Release|Win32.Build.0 = Windows Vista Release|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows Vista Release|Win32.Deploy.0 = Windows Vista Release|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows Vista Release|x64.ActiveCfg = Windows Vista Release|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows Vista Release|x64.Build.0 = Windows Vista Release|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows Vista Release|x64.Deploy.0 = Windows Vista Release|x64
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+EndGlobal
diff --git a/vs2013/xenhid/xenhid.user b/vs2013/xenhid/xenhid.user
new file mode 100644 (file)
index 0000000..70cfbf8
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <SignMode>TestSign</SignMode>
+    <TestCertificate>..\..\src\xenhid.pfx</TestCertificate>
+    <TimeStampServer>http://timestamp.verisign.com/scripts/timstamp.dll</TimeStampServer>
+  </PropertyGroup>
+</Project>
diff --git a/vs2013/xenhid/xenhid.vcxproj b/vs2013/xenhid/xenhid.vcxproj
new file mode 100644 (file)
index 0000000..eeeba2f
--- /dev/null
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\configs.props" />
+  <PropertyGroup Label="Globals">
+    <Configuration>Windows Vista Debug</Configuration>
+    <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Label="PropertySheets">
+    <DriverType>WDM</DriverType>
+    <PlatformToolset>WindowsKernelModeDriver8.1</PlatformToolset>
+    <ConfigurationType>Driver</ConfigurationType>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{C3F96D4C-E441-47F7-A44C-D2D0543C1D18}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="..\targets.props" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <PropertyGroup>
+    <RunCodeAnalysis>true</RunCodeAnalysis>
+    <EnableInf2cat>false</EnableInf2cat>
+    <IntDir>..\$(ProjectName)\$(ConfigurationName)\$(Platform)\</IntDir>
+    <OutDir>..\$(ConfigurationName)\$(Platform)\</OutDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup>
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(WindowsSdkDir)\include\km;..\..\include;..\..\include\xen;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>__MODULE__="XENHID";POOL_NX_OPTIN=1;NT_PROCESSOR_GROUPS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <WarningLevel>EnableAllWarnings</WarningLevel>
+      <DisableSpecificWarnings>4711;4548;4820;4668;4255;6001;6054;28196;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <EnablePREfast>true</EnablePREfast>
+    </ClCompile>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+    <Link>
+      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+      <AdditionalDependencies>$(DDK_LIB_PATH)/hidclass.lib;$(DDK_LIB_PATH)/Rtlver.lib;$(DDK_LIB_PATH)/libcntpr.lib;$(DDK_LIB_PATH)/aux_klib.lib;$(DDK_LIB_PATH)/ksecdd.lib;$(DDK_LIB_PATH)/procgrp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <EnableCOMDATFolding>false</EnableCOMDATFolding>
+    </Link>
+    <Inf>
+      <SpecifyArchitecture>true</SpecifyArchitecture>
+      <SpecifyDriverVerDirectiveVersion>true</SpecifyDriverVerDirectiveVersion>
+      <TimeStamp>$(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION).$(BUILD_NUMBER)</TimeStamp>
+      <EnableVerbose>true</EnableVerbose>
+    </Inf>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
+    <ClCompile>
+      <PreprocessorDefinitions>__i386__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Inf>
+      <Architecture>x86</Architecture>
+    </Inf>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Platform)'=='x64'">
+    <ClCompile>
+      <PreprocessorDefinitions>__x86_64__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Inf>
+      <Architecture>amd64</Architecture>
+    </Inf>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <FilesToPackage Include="$(TargetPath)" />
+    <FilesToPackage Include="$(OutDir)$(TargetName).pdb" />
+    <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="../../src/xenhid/driver.c" />
+    <ClCompile Include="../../src/xenhid/fdo.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="..\..\src\xenhid\xenhid.rc" />
+  </ItemGroup>
+  <ItemGroup>
+    <Inf Include="..\xenhid.inf" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="..\package\package.vcxproj" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/vs2013/xenhid_coinst/xenhid_coinst.vcxproj b/vs2013/xenhid_coinst/xenhid_coinst.vcxproj
new file mode 100644 (file)
index 0000000..a317127
--- /dev/null
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\configs.props" />
+  <PropertyGroup Label="PropertySheets">
+    <DriverType>WDM</DriverType>
+    <PlatformToolset>WindowsApplicationForDrivers8.1</PlatformToolset>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Label="Globals">
+    <Configuration>Windows Vista Debug</Configuration>
+    <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="..\targets.props" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <PropertyGroup>
+    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+    <IncludePath>..\..\include;$(IncludePath)</IncludePath>
+    <RunCodeAnalysis>true</RunCodeAnalysis>
+    <EnableInf2cat>false</EnableInf2cat>
+    <IntDir>..\$(ProjectName)\$(ConfigurationName)\$(Platform)\</IntDir>
+    <OutDir>..\$(ConfigurationName)\$(Platform)\</OutDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup>
+    <ClCompile>
+      <PreprocessorDefinitions>__MODULE__="XENHID_COINST";%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <WarningLevel>EnableAllWarnings</WarningLevel>
+      <DisableSpecificWarnings>4127;4548;4711;4820;4668;4255;6001;6054;28196;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <EnablePREfast>true</EnablePREfast>
+      <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebug</RuntimeLibrary>
+      <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='false'">MultiThreaded</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <ModuleDefinitionFile>../../src/coinst/xenhid_coinst.def</ModuleDefinitionFile>
+      <AdditionalDependencies>setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
+    <ClCompile>
+      <PreprocessorDefinitions>__i386__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Platform)'=='x64'">
+    <ClCompile>
+      <PreprocessorDefinitions>__x86_64__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <FilesToPackage Include="$(TargetPath)" />
+    <FilesToPackage Include="$(OutDir)$(TargetName).pdb" />
+    <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\src\coinst\coinst.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="..\..\src\coinst\xenhid_coinst.def" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
\ No newline at end of file
diff --git a/vs2013/xenhid_coinst/xenhid_coinst.vcxproj.user b/vs2013/xenhid_coinst/xenhid_coinst.vcxproj.user
new file mode 100644 (file)
index 0000000..70cfbf8
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <SignMode>TestSign</SignMode>
+    <TestCertificate>..\..\src\xenhid.pfx</TestCertificate>
+    <TimeStampServer>http://timestamp.verisign.com/scripts/timstamp.dll</TimeStampServer>
+  </PropertyGroup>
+</Project>
diff --git a/vs2015/configs.props b/vs2015/configs.props
new file mode 100644 (file)
index 0000000..cdbb3c8
--- /dev/null
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+       <ItemGroup Label="ProjectConfigurations">
+               <ProjectConfiguration Include="Windows 10 Debug|Win32">
+                       <Configuration>Windows 10 Debug</Configuration>
+                       <Platform>Win32</Platform>
+                       <WindowsTargetPlatformVersion>10</WindowsTargetPlatformVersion>
+               </ProjectConfiguration>
+               <ProjectConfiguration Include="Windows 10 Release|Win32">
+                       <Configuration>Windows 10 Release</Configuration>
+                       <Platform>Win32</Platform>
+                       <WindowsTargetPlatformVersion>10</WindowsTargetPlatformVersion>
+               </ProjectConfiguration>
+               <ProjectConfiguration Include="Windows 10 Debug|x64">
+                       <Configuration>Windows 10 Debug</Configuration>
+                       <Platform>x64</Platform>
+                       <WindowsTargetPlatformVersion>10</WindowsTargetPlatformVersion>
+               </ProjectConfiguration>
+               <ProjectConfiguration Include="Windows 10 Release|x64">
+                       <Configuration>Windows 10 Release</Configuration>
+                       <Platform>x64</Platform>
+                       <WindowsTargetPlatformVersion>10</WindowsTargetPlatformVersion>
+               </ProjectConfiguration>
+               <ProjectConfiguration Include="Windows 8 Debug|Win32">
+                       <Configuration>Windows 8 Debug</Configuration>
+                       <Platform>Win32</Platform>
+                       <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+               </ProjectConfiguration>
+               <ProjectConfiguration Include="Windows 8 Release|Win32">
+                       <Configuration>Windows 8 Release</Configuration>
+                       <Platform>Win32</Platform>
+                       <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+               </ProjectConfiguration>
+               <ProjectConfiguration Include="Windows 8 Debug|x64">
+                       <Configuration>Windows 8 Debug</Configuration>
+                       <Platform>x64</Platform>
+                       <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+               </ProjectConfiguration>
+               <ProjectConfiguration Include="Windows 8 Release|x64">
+                       <Configuration>Windows 8 Release</Configuration>
+                       <Platform>x64</Platform>
+                       <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+               </ProjectConfiguration>
+       </ItemGroup>
+</Project>
diff --git a/vs2015/package/package.vcxproj b/vs2015/package/package.vcxproj
new file mode 100644 (file)
index 0000000..7d4a7dd
--- /dev/null
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\configs.props" />
+  <PropertyGroup Label="PropertySheets">
+    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+    <ConfigurationType>Utility</ConfigurationType>
+    <DriverType>Package</DriverType>
+    <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
+    <SupportsPackaging>true</SupportsPackaging>
+    <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{73768CC9-DB26-4297-9EC8-1042F815EB15}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="..\targets.props" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <PropertyGroup>
+    <EnableInf2cat>true</EnableInf2cat>
+    <Inf2CatWindowsVersionList Condition="'$(Platform)'=='x64'">8_x64;Server8_x64;10_x64;Server10_x64</Inf2CatWindowsVersionList>
+    <Inf2CatWindowsVersionList Condition="'$(Platform)'=='Win32'">8_x86;10_x86</Inf2CatWindowsVersionList>
+    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+    <EnableDeployment>False</EnableDeployment>
+    <ImportToStore>False</ImportToStore>
+    <InstallMode>None</InstallMode>
+    <ScriptDeviceQuery>%PathToInf%</ScriptDeviceQuery>
+    <EnableVerifier>False</EnableVerifier>
+    <AllDrivers>False</AllDrivers>
+    <VerifyProjectOutput>True</VerifyProjectOutput>
+    <VerifyFlags>133563</VerifyFlags>
+    <IntDir>..\$(ProjectName)\$(ConfigurationName)\$(Platform)\</IntDir>
+    <OutDir>..\$(ConfigurationName)\$(Platform)\</OutDir>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\xenhid\xenhid.vcxproj">
+      <Project>{C3F96D4C-E441-47F7-A44C-D2D0543C1D18}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\xenhid_coinst\xenhid_coinst.vcxproj">
+      <Project>{2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <FilesToPackage Include="$(DPINST_REDIST)\x86\dpinst.exe" Condition="'$(Platform)'=='Win32'" />
+    <FilesToPackage Include="$(DPINST_REDIST)\x64\dpinst.exe" Condition="'$(Platform)'=='x64'" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
diff --git a/vs2015/package/package.vcxproj.user b/vs2015/package/package.vcxproj.user
new file mode 100644 (file)
index 0000000..eca4a5d
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <SignMode>TestSign</SignMode>
+    <TestCertificate>..\..\src\xenhid.pfx</TestCertificate>
+    <TimeStampServer>http://timestamp.verisign.com/scripts/timstamp.dll</TimeStampServer>
+  </PropertyGroup>
+</Project>
diff --git a/vs2015/targets.props b/vs2015/targets.props
new file mode 100644 (file)
index 0000000..64598fc
--- /dev/null
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+       <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 10 Debug|Win32'">
+               <TargetVersion>Windows10</TargetVersion>
+               <UseDebugLibraries>true</UseDebugLibraries>
+       </PropertyGroup>
+       <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 10 Release|Win32'">
+               <TargetVersion>Windows10</TargetVersion>
+               <UseDebugLibraries>false</UseDebugLibraries>
+       </PropertyGroup>
+       <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 10 Debug|x64'">
+               <TargetVersion>Windows10</TargetVersion>
+               <UseDebugLibraries>true</UseDebugLibraries>
+       </PropertyGroup>
+       <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 10 Release|x64'">
+               <TargetVersion>Windows10</TargetVersion>
+               <UseDebugLibraries>false</UseDebugLibraries>
+       </PropertyGroup>
+       <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 8 Debug|Win32'">
+               <TargetVersion>Windows8</TargetVersion>
+               <UseDebugLibraries>true</UseDebugLibraries>
+       </PropertyGroup>
+       <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 8 Release|Win32'">
+               <TargetVersion>Windows8</TargetVersion>
+               <UseDebugLibraries>false</UseDebugLibraries>
+       </PropertyGroup>
+       <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 8 Debug|x64'">
+               <TargetVersion>Windows8</TargetVersion>
+               <UseDebugLibraries>true</UseDebugLibraries>
+       </PropertyGroup>
+       <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 8 Release|x64'">
+               <TargetVersion>Windows8</TargetVersion>
+               <UseDebugLibraries>false</UseDebugLibraries>
+       </PropertyGroup>
+</Project>
diff --git a/vs2015/xenhid.sln b/vs2015/xenhid.sln
new file mode 100644 (file)
index 0000000..160d2ce
--- /dev/null
@@ -0,0 +1,102 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xenhid", "xenhid\xenhid.vcxproj", "{C3F96D4C-E441-47F7-A44C-D2D0543C1D18}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xenhid_coinst", "xenhid_coinst\xenhid_coinst.vcxproj", "{2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}"
+       ProjectSection(ProjectDependencies) = postProject
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18} = {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}
+       EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "package", "package\package.vcxproj", "{73768CC9-DB26-4297-9EC8-1042F815EB15}"
+       ProjectSection(ProjectDependencies) = postProject
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18} = {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44} = {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}
+       EndProjectSection
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Windows 8 Debug|Win32 = Windows 8 Debug|Win32
+               Windows 8 Debug|x64 = Windows 8 Debug|x64
+               Windows 8 Release|Win32 = Windows 8 Release|Win32
+               Windows 8 Release|x64 = Windows 8 Release|x64
+               Windows 10 Debug|Win32 = Windows 10 Debug|Win32
+               Windows 10 Debug|x64 = Windows 10 Debug|x64
+               Windows 10 Release|Win32 = Windows 10 Release|Win32
+               Windows 10 Release|x64 = Windows 10 Release|x64
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 8 Debug|Win32.ActiveCfg = Windows 8 Debug|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 8 Debug|Win32.Build.0 = Windows 8 Debug|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 8 Debug|Win32.Deploy.0 = Windows 8 Debug|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 8 Debug|x64.ActiveCfg = Windows 8 Debug|x64
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 8 Debug|x64.Build.0 = Windows 8 Debug|x64
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 8 Release|Win32.ActiveCfg = Windows 8 Release|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 8 Release|Win32.Build.0 = Windows 8 Release|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 8 Release|Win32.Deploy.0 = Windows 8 Release|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 8 Release|x64.ActiveCfg = Windows 8 Release|x64
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 8 Release|x64.Build.0 = Windows 8 Release|x64
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 10 Debug|Win32.ActiveCfg = Windows 10 Debug|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 10 Debug|Win32.Build.0 = Windows 10 Debug|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 10 Debug|Win32.Deploy.0 = Windows 10 Debug|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 10 Debug|x64.ActiveCfg = Windows 10 Debug|x64
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 10 Debug|x64.Build.0 = Windows 10 Debug|x64
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 10 Release|Win32.ActiveCfg = Windows 10 Release|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 10 Release|Win32.Build.0 = Windows 10 Release|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 10 Release|Win32.Deploy.0 = Windows 10 Release|Win32
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 10 Release|x64.ActiveCfg = Windows 10 Release|x64
+               {2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}.Windows 10 Release|x64.Build.0 = Windows 10 Release|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 8 Debug|Win32.ActiveCfg = Windows 8 Debug|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 8 Debug|Win32.Build.0 = Windows 8 Debug|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 8 Debug|Win32.Deploy.0 = Windows 8 Debug|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 8 Debug|x64.ActiveCfg = Windows 8 Debug|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 8 Debug|x64.Build.0 = Windows 8 Debug|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 8 Debug|x64.Deploy.0 = Windows 8 Debug|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 8 Release|Win32.ActiveCfg = Windows 8 Release|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 8 Release|Win32.Build.0 = Windows 8 Release|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 8 Release|Win32.Deploy.0 = Windows 8 Release|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 8 Release|x64.ActiveCfg = Windows 8 Release|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 8 Release|x64.Build.0 = Windows 8 Release|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 8 Release|x64.Deploy.0 = Windows 8 Release|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 10 Debug|Win32.ActiveCfg = Windows 10 Debug|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 10 Debug|Win32.Build.0 = Windows 10 Debug|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 10 Debug|Win32.Deploy.0 = Windows 10 Debug|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 10 Debug|x64.ActiveCfg = Windows 10 Debug|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 10 Debug|x64.Build.0 = Windows 10 Debug|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 10 Debug|x64.Deploy.0 = Windows 10 Debug|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 10 Release|Win32.ActiveCfg = Windows 10 Release|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 10 Release|Win32.Build.0 = Windows 10 Release|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 10 Release|Win32.Deploy.0 = Windows 10 Release|Win32
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 10 Release|x64.ActiveCfg = Windows 10 Release|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 10 Release|x64.Build.0 = Windows 10 Release|x64
+               {73768CC9-DB26-4297-9EC8-1042F815EB15}.Windows 10 Release|x64.Deploy.0 = Windows 10 Release|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 8 Debug|Win32.ActiveCfg = Windows 8 Debug|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 8 Debug|Win32.Build.0 = Windows 8 Debug|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 8 Debug|Win32.Deploy.0 = Windows 8 Debug|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 8 Debug|x64.ActiveCfg = Windows 8 Debug|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 8 Debug|x64.Build.0 = Windows 8 Debug|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 8 Debug|x64.Deploy.0 = Windows 8 Debug|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 8 Release|Win32.ActiveCfg = Windows 8 Release|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 8 Release|Win32.Build.0 = Windows 8 Release|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 8 Release|Win32.Deploy.0 = Windows 8 Release|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 8 Release|x64.ActiveCfg = Windows 8 Release|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 8 Release|x64.Build.0 = Windows 8 Release|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 8 Release|x64.Deploy.0 = Windows 8 Release|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 10 Debug|Win32.ActiveCfg = Windows 10 Debug|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 10 Debug|Win32.Build.0 = Windows 10 Debug|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 10 Debug|Win32.Deploy.0 = Windows 10 Debug|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 10 Debug|x64.ActiveCfg = Windows 10 Debug|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 10 Debug|x64.Build.0 = Windows 10 Debug|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 10 Debug|x64.Deploy.0 = Windows 10 Debug|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 10 Release|Win32.ActiveCfg = Windows 10 Release|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 10 Release|Win32.Build.0 = Windows 10 Release|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 10 Release|Win32.Deploy.0 = Windows 10 Release|Win32
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 10 Release|x64.ActiveCfg = Windows 10 Release|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 10 Release|x64.Build.0 = Windows 10 Release|x64
+               {C3F96D4C-E441-47F7-A44C-D2D0543C1D18}.Windows 10 Release|x64.Deploy.0 = Windows 10 Release|x64
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+EndGlobal
diff --git a/vs2015/xenhid/xenhid.vcxproj b/vs2015/xenhid/xenhid.vcxproj
new file mode 100644 (file)
index 0000000..424ad8b
--- /dev/null
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\configs.props" />
+  <PropertyGroup Label="PropertySheets">
+    <DriverType>WDM</DriverType>
+    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+    <ConfigurationType>Driver</ConfigurationType>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{C3F96D4C-E441-47F7-A44C-D2D0543C1D18}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="..\targets.props" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <PropertyGroup>
+    <RunCodeAnalysis>true</RunCodeAnalysis>
+    <EnableInf2cat>false</EnableInf2cat>
+    <IntDir>..\$(ProjectName)\$(ConfigurationName)\$(Platform)\</IntDir>
+    <OutDir>..\$(ConfigurationName)\$(Platform)\</OutDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup>
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(WindowsSdkDir)\include\km;..\..\include;..\..\include\xen;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>__MODULE__="XENHID";POOL_NX_OPTIN=1;NT_PROCESSOR_GROUPS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <WarningLevel>EnableAllWarnings</WarningLevel>
+      <DisableSpecificWarnings>4464;4711;4548;4820;4668;4255;6001;6054;28196;30030;30029;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <EnablePREfast>true</EnablePREfast>
+    </ClCompile>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+    <Link>
+      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+      <AdditionalDependencies>$(DDK_LIB_PATH)/hidclass.lib;$(DDK_LIB_PATH)/Rtlver.lib;$(DDK_LIB_PATH)/libcntpr.lib;$(DDK_LIB_PATH)/aux_klib.lib;$(DDK_LIB_PATH)/ksecdd.lib;$(DDK_LIB_PATH)/procgrp.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <EnableCOMDATFolding>false</EnableCOMDATFolding>
+    </Link>
+    <Inf>
+      <SpecifyArchitecture>true</SpecifyArchitecture>
+      <SpecifyDriverVerDirectiveVersion>true</SpecifyDriverVerDirectiveVersion>
+      <TimeStamp>$(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION).$(BUILD_NUMBER)</TimeStamp>
+      <EnableVerbose>true</EnableVerbose>
+    </Inf>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
+    <ClCompile>
+      <PreprocessorDefinitions>__i386__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Inf>
+      <Architecture>x86</Architecture>
+    </Inf>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Platform)'=='x64'">
+    <ClCompile>
+      <PreprocessorDefinitions>__x86_64__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Inf>
+      <Architecture>amd64</Architecture>
+    </Inf>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <FilesToPackage Include="$(TargetPath)" />
+    <FilesToPackage Include="$(OutDir)$(TargetName).pdb" />
+    <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="../../src/xenhid/driver.c" />
+    <ClCompile Include="../../src/xenhid/fdo.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="..\..\src\xenhid\xenhid.rc" />
+  </ItemGroup>
+  <ItemGroup>
+    <Inf Include="..\xenhid.inf" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="..\package\package.vcxproj" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/vs2015/xenhid/xenhid.vcxproj.user b/vs2015/xenhid/xenhid.vcxproj.user
new file mode 100644 (file)
index 0000000..eca4a5d
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <SignMode>TestSign</SignMode>
+    <TestCertificate>..\..\src\xenhid.pfx</TestCertificate>
+    <TimeStampServer>http://timestamp.verisign.com/scripts/timstamp.dll</TimeStampServer>
+  </PropertyGroup>
+</Project>
diff --git a/vs2015/xenhid_coinst/xenhid_coinst.vcxproj b/vs2015/xenhid_coinst/xenhid_coinst.vcxproj
new file mode 100644 (file)
index 0000000..2fc29d6
--- /dev/null
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\configs.props" />
+  <PropertyGroup Label="PropertySheets">
+    <DriverType>WDM</DriverType>
+    <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{2BFAC7E6-3420-47A5-A092-BDC5C9D78A44}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="..\targets.props" />
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <PropertyGroup>
+    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+    <IncludePath>..\..\include;$(IncludePath)</IncludePath>
+    <RunCodeAnalysis>true</RunCodeAnalysis>
+    <EnableInf2cat>false</EnableInf2cat>
+    <IntDir>..\$(ProjectName)\$(ConfigurationName)\$(Platform)\</IntDir>
+    <OutDir>..\$(ConfigurationName)\$(Platform)\</OutDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup>
+    <ClCompile>
+      <PreprocessorDefinitions>__MODULE__="XENHID_COINST";%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <WarningLevel>EnableAllWarnings</WarningLevel>
+      <DisableSpecificWarnings>4127;4548;4711;4820;4668;4255;6001;6054;28196;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <EnablePREfast>true</EnablePREfast>
+      <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebug</RuntimeLibrary>
+      <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='false'">MultiThreaded</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <ModuleDefinitionFile>../../src/coinst/xenhid_coinst.def</ModuleDefinitionFile>
+      <AdditionalDependencies>setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
+    <ClCompile>
+      <PreprocessorDefinitions>__i386__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Platform)'=='x64'">
+    <ClCompile>
+      <PreprocessorDefinitions>__x86_64__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <FilesToPackage Include="$(TargetPath)" />
+    <FilesToPackage Include="$(OutDir)$(TargetName).pdb" />
+    <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\src\coinst\coinst.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="..\..\src\coinst\xenhid_coinst.def" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
diff --git a/vs2015/xenhid_coinst/xenhid_coinst.vcxproj.user b/vs2015/xenhid_coinst/xenhid_coinst.vcxproj.user
new file mode 100644 (file)
index 0000000..eca4a5d
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <SignMode>TestSign</SignMode>
+    <TestCertificate>..\..\src\xenhid.pfx</TestCertificate>
+    <TimeStampServer>http://timestamp.verisign.com/scripts/timstamp.dll</TimeStampServer>
+  </PropertyGroup>
+</Project>