From: Paul Durrant Date: Tue, 22 Jul 2014 14:28:56 +0000 (+0100) Subject: Implement new API version scheme X-Git-Tag: 8.1.0-rc1~18 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=c3ca72ed4d5ee111f8bc17c9153c56ac78e20bac;p=pvdrivers%2Fwin%2Fxeniface.git Implement new API version scheme This patch changes the way APIs work in an incompatible way. (See README.md for details). The patch also includes a *lot* of code tidying and movement and as such is not really suitable for review as a patch; the resulting code should itself be reviewed. Given the scale of the change, the major version number has been revised to 8 and other version numbers reset to zero. Signed-off-by: Paul Durrant --- diff --git a/.gitignore b/.gitignore index b389700..5b7056e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ # Cscope/Tags -cscope.files -cscope.out -tags +/cscope.files +/cscope.out +/tags # Output -xeniface +/xeniface diff --git a/CHANGELOG b/CHANGELOG index 80861c7..40b8fb3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -7,3 +7,6 @@ 7.2.0 (2013-09-27): * Drivers compatible with upstream Xen, QEMU and Linux dom0 + +8.0.0 (2014-08-15): +* Drivers with new API version scheme diff --git a/README.md b/README.md index 1d11f3d..98f47f7 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,11 @@ -XenIface - The XenServer Interface Driver for Windows -===================================================== +XenIface - The Xen Interface Driver for Windows +=============================================== The XenIface package consists of a single device driver: * xeniface.sys is a driver which attaches to a virtual device created - by XenBus (see https://github.com/xenserver/win-xenbus) and provides - a WMI to xenstore (and also an IOCTL interface for simple xenstore - read/write access). + by XenBus and provides a WMI to xenstore (and also an IOCTL interface + for simple xenstore read/write access). Quick Start Guide ================= @@ -51,6 +50,35 @@ Installing the driver See INSTALL.md +API Versions +============ + +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 driver maps to a PDO +revision. The DeviceID of each PDO created by the driver will specify the +latest revision supported and all others will be contained within the +HardwareIDs and CompatibleIDs. +Hence, when a new version of an API is added, a new PDO revision will be +added. When a version of an API is removed then ALL revisions that API +version maps to will be removed. + +To avoid a situation where a new version of the package is installed that +is incompatible with any child drivers that make use of the APIs, each +child 'subscribes' to an API by writing a registry value with the version +number of that API that they consume into a registry key under the service +key of the providing driver. E.g. if driver 'foo' consumes version 1 of +driver 'bar''s 'widget' API, then it will write +HLKM/CurrentControlSet/Services/BAR/Interfaces/FOO/WIDGET with the value 1. +The 'bar' package co-installer can then check, prior to installation of a +new version of a driver, that it can still support all of its subscribers. +If any of the API versions subscribed to has been removed then installation +will be vetoed until all the subscriber drivers have been updated to use +the newer versions of the APIs exported by the newer providing driver. + Miscellaneous ============= diff --git a/build.py b/build.py index 02a2fdb..98cc6e4 100644 --- a/build.py +++ b/build.py @@ -1,36 +1,5 @@ #!python -u -# 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. - - import os, sys import datetime import re @@ -38,11 +7,32 @@ 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 COMPANY_NAME_STR\t"' + os.environ['COMPANY_NAME'] + '"\n') + file.write('#define PRODUCT_NAME_STR\t"' + os.environ['PRODUCT_NAME'] + '"\n') + file.write('\n') + file.write('#define MAJOR_VERSION\t' + os.environ['MAJOR_VERSION'] + '\n') file.write('#define MAJOR_VERSION_STR\t"' + os.environ['MAJOR_VERSION'] + '"\n') file.write('\n') @@ -61,18 +51,37 @@ def make_header(): file.write('#define YEAR\t' + str(now.year) + '\n') file.write('#define YEAR_STR\t"' + str(now.year) + '"\n') + file.write('\n') file.write('#define MONTH\t' + str(now.month) + '\n') file.write('#define MONTH_STR\t"' + str(now.month) + '"\n') + file.write('\n') file.write('#define DAY\t' + str(now.day) + '\n') file.write('#define DAY_STR\t"' + str(now.day) + '"\n') - + file.write('\n') file.close() -def get_expired_symbols(age = 30): +def copy_inf(name): + src = open('src\\%s.inf' % name, 'r') + dst = open('proj\\%s.inf' % 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('@COMPANY_NAME@', os.environ['COMPANY_NAME'], line) + line = re.sub('@PRODUCT_NAME@', os.environ['PRODUCT_NAME'], 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: @@ -91,6 +100,7 @@ def get_expired_symbols(age = 30): 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]), @@ -98,7 +108,7 @@ def get_expired_symbols(age = 30): hour = int(time[0]), minute = int(time[1]), second = int(time[2])) - if (age < threshold): + if (tag == name and age < threshold): expired.append(id) elif (re.match('del', item[1])): @@ -111,6 +121,8 @@ def get_expired_symbols(age = 30): file.close() return expired + + def get_configuration(release, debug): configuration = release @@ -121,25 +133,32 @@ def get_configuration(release, debug): return configuration + def get_target_path(release, arch, debug): configuration = get_configuration(release, debug) name = ''.join(configuration.split(' ')) - target = { 'x86': 'proj', 'x64': os.sep.join(['proj', 'x64']) } - target_path = os.sep.join([target[arch], name]) + target = { 'x86': os.sep.join([name, 'Win32']), 'x64': os.sep.join([name, 'x64']) } + target_path = os.sep.join(['proj', target[arch]]) return target_path -def shell(command): +def shell(command, dir): + print(dir) print(command) sys.stdout.flush() + + sub = subprocess.Popen(' '.join(command), cwd=dir, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + universal_newlines=True) - pipe = os.popen(command, 'r', 1) - - for line in pipe: + for line in sub.stdout: print(line.rstrip()) - return pipe.close() + sub.wait() + + return sub.returncode class msbuild_failure(Exception): @@ -149,23 +168,20 @@ class msbuild_failure(Exception): 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 - cwd = os.getcwd() - bin = os.path.join(cwd, 'msbuild.bat') + bin = os.path.join(os.getcwd(), 'msbuild.bat') - os.chdir(dir) - status = shell(bin) - os.chdir(cwd) + status = shell([bin], dir) - if (status != None): + if (status != 0): raise msbuild_failure(configuration) + def build_sln(name, release, arch, debug): configuration = get_configuration(release, debug) @@ -176,7 +192,7 @@ def build_sln(name, release, arch, debug): cwd = os.getcwd() - msbuild(platform, configuration, 'Build', name+'.sln', '', 'proj') + msbuild(platform, configuration, 'Build', name + '.sln', '', 'proj') def remove_timestamps(path): @@ -197,14 +213,62 @@ def remove_timestamps(path): dst.close() src.close() +def sdv_clean(name): + path = ['proj', name, 'sdv'] + print(path) + + shutil.rmtree(os.path.join(*path), True) + + path = ['proj', name, 'sdv.temp'] + print(path) + + shutil.rmtree(os.path.join(*path), True) + + path = ['proj', name, 'staticdv.job'] + print(path) + + try: + os.unlink(os.path.join(*path)) + except OSError: + pass + + path = ['proj', name, 'refine.sdv'] + print(path) + + try: + os.unlink(os.path.join(*path)) + except OSError: + pass + + path = ['proj', name, 'sdv-map.h'] + print(path) + + try: + os.unlink(os.path.join(*path)) + except OSError: + pass + + def run_sdv(name, dir): configuration = get_configuration('Windows 8', False) platform = 'x64' msbuild(platform, configuration, 'Build', name + '.vcxproj', '', os.path.join('proj', name)) + + sdv_clean(name) + msbuild(platform, configuration, 'sdv', name + '.vcxproj', - '/p:Inputs="/clean"', os.path.join('proj', name)) + '/p:Inputs="/scan"', os.path.join('proj', name)) + + path = ['proj', name, 'sdv-map.h'] + file = open(os.path.join(*path), 'r') + + for line in file: + print(line) + + file.close() + msbuild(platform, configuration, 'sdv', name + '.vcxproj', '/p:Inputs="/check:default.sdv"', os.path.join('proj', name)) @@ -217,7 +281,13 @@ def run_sdv(name, dir): path = ['proj', name, name + '.DVL.XML'] shutil.copy(os.path.join(*path), dir) -def symstore_del(age): + path = ['proj', name, 'refine.sdv'] + if os.path.isfile(os.path.join(*path)): + msbuild(platform, configuration, 'sdv', name + '.vcxproj', + '/p:Inputs=/refine', os.path.join('proj', name)) + + +def symstore_del(name, age): symstore_path = [os.environ['KIT'], 'Debuggers'] if os.environ['PROCESSOR_ARCHITECTURE'] == 'x86': symstore_path.append('x86') @@ -227,7 +297,7 @@ def symstore_del(age): symstore = os.path.join(*symstore_path) - for id in get_expired_symbols(age): + for id in get_expired_symbols(name, age): command=['"' + symstore + '"'] command.append('del') command.append('/i') @@ -235,10 +305,10 @@ def symstore_del(age): command.append('/s') command.append(os.environ['SYMBOL_SERVER']) - shell(' '.join(command)) + shell(command, None) + def symstore_add(name, release, arch, debug): - cwd = os.getcwd() target_path = get_target_path(release, arch, debug) symstore_path = [os.environ['KIT'], 'Debuggers'] @@ -255,7 +325,6 @@ def symstore_add(name, release, arch, debug): os.environ['MICRO_VERSION'], os.environ['BUILD_NUMBER']]) - os.chdir(target_path) command=['"' + symstore + '"'] command.append('add') command.append('/s') @@ -268,12 +337,11 @@ def symstore_add(name, release, arch, debug): command.append('/v') command.append(version) - shell(' '.join(command)) + shell(command, target_path) - os.chdir(cwd) -def callfnout(cmd): - print(cmd) +def manifest(): + cmd = ['git', 'ls-tree', '-r', '--name-only', 'HEAD'] sub = subprocess.Popen(cmd, stdout=subprocess.PIPE) output = sub.communicate()[0] @@ -284,6 +352,7 @@ def callfnout(cmd): return output.decode('utf-8') + def archive(filename, files, tgz=False): access='w' if tgz: @@ -298,25 +367,35 @@ def archive(filename, files, tgz=False): if __name__ == '__main__': - + debug = { 'checked': True, 'free': False } + sdv = { 'nosdv': False, None: True } driver = 'xeniface' - os.environ['MAJOR_VERSION'] = '7' - os.environ['MINOR_VERSION'] = '2' + + if 'COMPANY_NAME' not in os.environ.keys(): + os.environ['COMPANY_NAME'] = 'Xen Project' + + if 'PRODUCT_NAME' not in os.environ.keys(): + os.environ['PRODUCT_NAME'] = 'Xen' + + os.environ['MAJOR_VERSION'] = '8' + os.environ['MINOR_VERSION'] = '0' os.environ['MICRO_VERSION'] = '0' if 'BUILD_NUMBER' not in os.environ.keys(): - os.environ['BUILD_NUMBER'] = '0' + os.environ['BUILD_NUMBER'] = next_build_number() + + print("BUILD_NUMBER=%s" % os.environ['BUILD_NUMBER']) if 'GIT_REVISION' in os.environ.keys(): revision = open('revision', 'w') print(os.environ['GIT_REVISION'], file=revision) revision.close() - debug = { 'checked': True, 'free': False } - make_header() - symstore_del(30) + copy_inf(driver) + + symstore_del(driver, 30) release = 'Windows Vista' @@ -326,9 +405,9 @@ if __name__ == '__main__': symstore_add(driver, release, 'x86', debug[sys.argv[1]]) symstore_add(driver, release, 'x64', debug[sys.argv[1]]) - if len(sys.argv) <= 2 or sys.argv[2] != 'nosdv': - run_sdv(driver, driver) + if len(sys.argv) <= 2 or sdv[sys.argv[2]]: + run_sdv('xeniface', driver) + + archive(driver + '\\source.tgz', manifest().splitlines(), tgz=True) + archive(driver + '.tar', [driver,'revision']) - listfile = callfnout(['git','ls-tree', '-r', '--name-only', 'HEAD']) - archive('xeniface\\source.tgz', listfile.splitlines(), tgz=True) - archive('xeniface.tar', ['xeniface', 'revision']) diff --git a/include/shared_info_interface.h b/include/shared_info_interface.h index af550c3..af0f243 100644 --- a/include/shared_info_interface.h +++ b/include/shared_info_interface.h @@ -1,10 +1,10 @@ /* 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. @@ -12,7 +12,7 @@ * 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 @@ -29,94 +29,117 @@ * SUCH DAMAGE. */ +/*! \file shared_info_interface.h + \brief XENBUS SHARED_INFO Interface + + This interface provides access to the hypervisor shared info +*/ + #ifndef _XENBUS_SHARED_INFO_INTERFACE_H #define _XENBUS_SHARED_INFO_INTERFACE_H -#define DEFINE_SHARED_INFO_OPERATIONS \ - SHARED_INFO_OPERATION(VOID, \ - Acquire, \ - ( \ - IN PXENBUS_SHARED_INFO_CONTEXT Context \ - ) \ - ) \ - SHARED_INFO_OPERATION(VOID, \ - Release, \ - ( \ - IN PXENBUS_SHARED_INFO_CONTEXT Context \ - ) \ - ) \ - SHARED_INFO_OPERATION(BOOLEAN, \ - EvtchnPoll, \ - ( \ - IN PXENBUS_SHARED_INFO_CONTEXT Context, \ - IN BOOLEAN (*Function)(PVOID, ULONG), \ - IN PVOID Argument \ - ) \ - ) \ - SHARED_INFO_OPERATION(VOID, \ - EvtchnAck, \ - ( \ - IN PXENBUS_SHARED_INFO_CONTEXT Context, \ - IN ULONG Port \ - ) \ - ) \ - SHARED_INFO_OPERATION(VOID, \ - EvtchnMask, \ - ( \ - IN PXENBUS_SHARED_INFO_CONTEXT Context, \ - IN ULONG Port \ - ) \ - ) \ - SHARED_INFO_OPERATION(BOOLEAN, \ - EvtchnUnmask, \ - ( \ - IN PXENBUS_SHARED_INFO_CONTEXT Context, \ - IN ULONG Port \ - ) \ - ) \ - SHARED_INFO_OPERATION(LARGE_INTEGER, \ - GetTime, \ - ( \ - IN PXENBUS_SHARED_INFO_CONTEXT Context \ - ) \ - ) - -typedef struct _XENBUS_SHARED_INFO_CONTEXT XENBUS_SHARED_INFO_CONTEXT, *PXENBUS_SHARED_INFO_CONTEXT; - -#define SHARED_INFO_OPERATION(_Type, _Name, _Arguments) \ - _Type (*SHARED_INFO_ ## _Name) _Arguments; - -typedef struct _XENBUS_SHARED_INFO_OPERATIONS { - DEFINE_SHARED_INFO_OPERATIONS -} XENBUS_SHARED_INFO_OPERATIONS, *PXENBUS_SHARED_INFO_OPERATIONS; - -#undef SHARED_INFO_OPERATION - -typedef struct _XENBUS_SHARED_INFO_INTERFACE XENBUS_SHARED_INFO_INTERFACE, *PXENBUS_SHARED_INFO_INTERFACE; - -// {05DC267C-36CA-44a3-A124-B9BA9FE3780B} -DEFINE_GUID(GUID_SHARED_INFO_INTERFACE, - 0x5dc267c, - 0x36ca, - 0x44a3, - 0xa1, - 0x24, - 0xb9, - 0xba, - 0x9f, - 0xe3, - 0x78, - 0xb); - -#define SHARED_INFO_INTERFACE_VERSION 4 - -#define SHARED_INFO_OPERATIONS(_Interface) \ - (PXENBUS_SHARED_INFO_OPERATIONS *)((ULONG_PTR)(_Interface)) - -#define SHARED_INFO_CONTEXT(_Interface) \ - (PXENBUS_SHARED_INFO_CONTEXT *)((ULONG_PTR)(_Interface) + sizeof (PVOID)) - -#define SHARED_INFO(_Operation, _Interface, ...) \ - (*SHARED_INFO_OPERATIONS(_Interface))->SHARED_INFO_ ## _Operation((*SHARED_INFO_CONTEXT(_Interface)), __VA_ARGS__) +#ifndef _WINDLL + +#define XENBUS_SHARED_INFO_EVTCHN_PER_SELECTOR (sizeof (ULONG_PTR) * 8) +#define XENBUS_SHARED_INFO_EVTCHN_SELECTOR_COUNT (RTL_FIELD_SIZE(shared_info_t, evtchn_pending) / sizeof (ULONG_PTR)) + +/*! \typedef XENBUS_SHARED_INFO_ACQUIRE + \brief Acquire a reference to the SHARED_INFO interface + + \param Interface The interface header +*/ +typedef NTSTATUS +(*XENBUS_SHARED_INFO_ACQUIRE)( + IN PINTERFACE Interface + ); + +/*! \typedef XENBUS_SHARED_INFO_RELEASE + \brief Release a reference to the SHARED_INFO interface + + \param Interface The interface header +*/ +typedef VOID +(*XENBUS_SHARED_INFO_RELEASE)( + IN PINTERFACE Interface + ); + +/*! \typedef XENBUS_SHARED_INFO_EVTCHN_POLL + \brief Private method for EVTCHN inerface +*/ +typedef BOOLEAN +(*XENBUS_SHARED_INFO_EVTCHN_POLL)( + IN PINTERFACE Interface, + IN BOOLEAN (*Function)(PVOID, ULONG), + IN PVOID Argument + ); + +/*! \typedef XENBUS_SHARED_INFO_EVTCHN_ACK + \brief Private method for EVTCHN inerface +*/ +typedef VOID +(*XENBUS_SHARED_INFO_EVTCHN_ACK)( + IN PINTERFACE Interface, + IN ULONG Port + ); + +/*! \typedef XENBUS_SHARED_INFO_EVTCHN_MASK + \brief Private method for EVTCHN inerface +*/ +typedef VOID +(*XENBUS_SHARED_INFO_EVTCHN_MASK)( + IN PINTERFACE Interface, + IN ULONG Port + ); + +/*! \typedef XENBUS_SHARED_INFO_EVTCHN_UNMASK + \brief Private method for EVTCHN inerface +*/ +typedef BOOLEAN +(*XENBUS_SHARED_INFO_EVTCHN_UNMASK)( + IN PINTERFACE Interface, + IN ULONG Port + ); + +/*! \typedef XENBUS_SHARED_INFO_GET_TIME + \brief Return the wallclock time from the shared info + + \param Interface The interface header + \return The wallclock time in units of 100ns +*/ +typedef LARGE_INTEGER +(*XENBUS_SHARED_INFO_GET_TIME)( + IN PINTERFACE Interface + ); + +// {7E73C34F-1640-4649-A8F3-263BC930A004} +DEFINE_GUID(GUID_XENBUS_SHARED_INFO_INTERFACE, +0x7e73c34f, 0x1640, 0x4649, 0xa8, 0xf3, 0x26, 0x3b, 0xc9, 0x30, 0xa0, 0x4); + +/*! \struct _XENBUS_SHARED_INFO_INTERFACE_V1 + \brief SHARED_INFO interface version 1 +*/ +struct _XENBUS_SHARED_INFO_INTERFACE_V1 { + INTERFACE Interface; + XENBUS_SHARED_INFO_ACQUIRE SharedInfoAcquire; + XENBUS_SHARED_INFO_RELEASE SharedInfoRelease; + XENBUS_SHARED_INFO_EVTCHN_POLL SharedInfoEvtchnPoll; + XENBUS_SHARED_INFO_EVTCHN_ACK SharedInfoEvtchnAck; + XENBUS_SHARED_INFO_EVTCHN_MASK SharedInfoEvtchnMask; + XENBUS_SHARED_INFO_EVTCHN_UNMASK SharedInfoEvtchnUnmask; + XENBUS_SHARED_INFO_GET_TIME SharedInfoGetTime; +}; + +typedef struct _XENBUS_SHARED_INFO_INTERFACE_V1 XENBUS_SHARED_INFO_INTERFACE, *PXENBUS_SHARED_INFO_INTERFACE; + +/*! \def XENBUS_SHARED_INFO + \brief Macro at assist in method invocation +*/ +#define XENBUS_SHARED_INFO(_Method, _Interface, ...) \ + (_Interface)->SharedInfo ## _Method((PINTERFACE)(_Interface), __VA_ARGS__) + +#endif // _WINDLL + +#define XENBUS_SHARED_INFO_INTERFACE_VERSION_MIN 1 +#define XENBUS_SHARED_INFO_INTERFACE_VERSION_MAX 1 #endif // _XENBUS_SHARED_INFO_H diff --git a/include/store_interface.h b/include/store_interface.h index 6c3218e..f052b8f 100644 --- a/include/store_interface.h +++ b/include/store_interface.h @@ -1,10 +1,10 @@ /* 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. @@ -12,7 +12,7 @@ * 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 @@ -29,158 +29,259 @@ * SUCH DAMAGE. */ +/*! \file store_interface.h + \brief XENBUS STORE Interface + + This interface provides access to XenStore +*/ + #ifndef _XENBUS_STORE_INTERFACE_H #define _XENBUS_STORE_INTERFACE_H +#ifndef _WINDLL + +/*! \typedef XENBUS_STORE_TRANSACTION + \brief XenStore transaction handle +*/ typedef struct _XENBUS_STORE_TRANSACTION XENBUS_STORE_TRANSACTION, *PXENBUS_STORE_TRANSACTION; + +/*! \typedef XENBUS_STORE_WATCH + \brief XenStore watch handle +*/ typedef struct _XENBUS_STORE_WATCH XENBUS_STORE_WATCH, *PXENBUS_STORE_WATCH; -#define DEFINE_STORE_OPERATIONS \ - STORE_OPERATION(VOID, \ - Acquire, \ - ( \ - IN PXENBUS_STORE_CONTEXT Context \ - ) \ - ) \ - STORE_OPERATION(VOID, \ - Release, \ - ( \ - IN PXENBUS_STORE_CONTEXT Context \ - ) \ - ) \ - STORE_OPERATION(VOID, \ - Free, \ - ( \ - IN PXENBUS_STORE_CONTEXT Context, \ - IN PCHAR Value \ - ) \ - ) \ - STORE_OPERATION(NTSTATUS, \ - Read, \ - ( \ - IN PXENBUS_STORE_CONTEXT Context, \ - IN PXENBUS_STORE_TRANSACTION Transaction OPTIONAL, \ - IN PCHAR Prefix OPTIONAL, \ - IN PCHAR Node, \ - OUT PCHAR *Value \ - ) \ - ) \ - STORE_OPERATION(NTSTATUS, \ - Write, \ - ( \ - IN PXENBUS_STORE_CONTEXT Context, \ - IN PXENBUS_STORE_TRANSACTION Transaction OPTIONAL, \ - IN PCHAR Prefix OPTIONAL, \ - IN PCHAR Node, \ - IN PCHAR Value \ - ) \ - ) \ - STORE_OPERATION(NTSTATUS, \ - Printf, \ - ( \ - IN PXENBUS_STORE_CONTEXT Context, \ - IN PXENBUS_STORE_TRANSACTION Transaction OPTIONAL, \ - IN PCHAR Prefix OPTIONAL, \ - IN PCHAR Node, \ - IN const CHAR *Format, \ - ... \ - ) \ - ) \ - STORE_OPERATION(NTSTATUS, \ - Remove, \ - ( \ - IN PXENBUS_STORE_CONTEXT Context, \ - IN PXENBUS_STORE_TRANSACTION Transaction OPTIONAL, \ - IN PCHAR Prefix OPTIONAL, \ - IN PCHAR Node \ - ) \ - ) \ - STORE_OPERATION(NTSTATUS, \ - Directory, \ - ( \ - IN PXENBUS_STORE_CONTEXT Context, \ - IN PXENBUS_STORE_TRANSACTION Transaction OPTIONAL, \ - IN PCHAR Prefix OPTIONAL, \ - IN PCHAR Node, \ - OUT PCHAR *Value \ - ) \ - ) \ - STORE_OPERATION(NTSTATUS, \ - TransactionStart, \ - ( \ - IN PXENBUS_STORE_CONTEXT Context, \ - OUT PXENBUS_STORE_TRANSACTION *Transaction \ - ) \ - ) \ - STORE_OPERATION(NTSTATUS, \ - TransactionEnd, \ - ( \ - IN PXENBUS_STORE_CONTEXT Context, \ - IN PXENBUS_STORE_TRANSACTION Transaction, \ - IN BOOLEAN Commit \ - ) \ - ) \ - STORE_OPERATION(NTSTATUS, \ - Watch, \ - ( \ - IN PXENBUS_STORE_CONTEXT Context, \ - IN PCHAR Prefix OPTIONAL, \ - IN PCHAR Node, \ - IN PKEVENT Event, \ - OUT PXENBUS_STORE_WATCH *Watch \ - ) \ - ) \ - STORE_OPERATION(NTSTATUS, \ - Unwatch, \ - ( \ - IN PXENBUS_STORE_CONTEXT Context, \ - IN PXENBUS_STORE_WATCH Watch \ - ) \ - ) \ - STORE_OPERATION(VOID, \ - Poll, \ - ( \ - IN PXENBUS_STORE_CONTEXT Context \ - ) \ - ) - -typedef struct _XENBUS_STORE_CONTEXT XENBUS_STORE_CONTEXT, *PXENBUS_STORE_CONTEXT; - -#define STORE_OPERATION(_Type, _Name, _Arguments) \ - _Type (*STORE_ ## _Name) _Arguments; - -typedef struct _XENBUS_STORE_OPERATIONS { - DEFINE_STORE_OPERATIONS -} XENBUS_STORE_OPERATIONS, *PXENBUS_STORE_OPERATIONS; - -#undef STORE_OPERATION - -typedef struct _XENBUS_STORE_INTERFACE XENBUS_STORE_INTERFACE, *PXENBUS_STORE_INTERFACE; - -// {916920F1-F9EE-465d-8137-5CC61786B840} -DEFINE_GUID(GUID_STORE_INTERFACE, - 0x916920f1, - 0xf9ee, - 0x465d, - 0x81, - 0x37, - 0x5c, - 0xc6, - 0x17, - 0x86, - 0xb8, - 0x40); - -#define STORE_INTERFACE_VERSION 4 - -#define STORE_OPERATIONS(_Interface) \ - (PXENBUS_STORE_OPERATIONS *)((ULONG_PTR)(_Interface)) - -#define STORE_CONTEXT(_Interface) \ - (PXENBUS_STORE_CONTEXT *)((ULONG_PTR)(_Interface) + sizeof (PVOID)) - -#define STORE(_Operation, _Interface, ...) \ - (*STORE_OPERATIONS(_Interface))->STORE_ ## _Operation((*STORE_CONTEXT(_Interface)), __VA_ARGS__) +/*! \typedef XENBUS_STORE_ACQUIRE + \brief Acquire a reference to the STORE interface + + \param Interface The interface header +*/ +typedef NTSTATUS +(*XENBUS_STORE_ACQUIRE)( + IN PINTERFACE Interface + ); + +/*! \typedef XENBUS_STORE_RELEASE + \brief Release a reference to the STORE interface + + \param Interface The interface header +*/ +typedef VOID +(*XENBUS_STORE_RELEASE)( + IN PINTERFACE Interface + ); + +/*! \typedef XENBUS_STORE_FREE + \brief Free a memory buffer allocated by the STORE interface + + \param Interface The interface header + \param Buffer Pointer to the memory buffer +*/ +typedef VOID +(*XENBUS_STORE_FREE)( + IN PINTERFACE Interface, + IN PCHAR Buffer + ); + +/*! \typedef XENBUS_STORE_READ + \brief Read a value from XenStore + + \param Interface The interface header + \param Transaction The transaction handle (NULL if this read is not + part of a transaction) + \param Prefix An optional prefix for the \a Node + \param Node The concatenation of the \a Prefix and this value specifies + the XenStore key to read + \param A pointer to a pointer that will be initialized with a memory + buffer containing the value read + + The \a Buffer should be freed using \a XENBUS_STORE_FREE +*/ +typedef NTSTATUS +(*XENBUS_STORE_READ)( + IN PINTERFACE Interface, + IN PXENBUS_STORE_TRANSACTION Transaction OPTIONAL, + IN PCHAR Prefix OPTIONAL, + IN PCHAR Node, + OUT PCHAR *Buffer + ); + +/*! \typedef XENBUS_STORE_PRINTF + \brief Write a value to XenStore + + \param Interface The interface header + \param Transaction The transaction handle (NULL if this write is not + part of a transaction) + \param Prefix An optional prefix for the \a Node + \param Node The concatenation of the \a Prefix and this value specifies + the XenStore key to write + \param Format A format specifier + \param ... Additional parameters required by \a Format + + If the \a Node does not exist then it is created +*/ +typedef NTSTATUS +(*XENBUS_STORE_PRINTF)( + IN PINTERFACE Interface, + IN PXENBUS_STORE_TRANSACTION Transaction OPTIONAL, + IN PCHAR Prefix OPTIONAL, + IN PCHAR Node, + IN const CHAR *Format, + ... + ); + +/*! \typedef XENBUS_STORE_REMOVE + \brief Remove a key from XenStore + + \param Interface The interface header + \param Transaction The transaction handle (NULL if this removal is not + part of a transaction) + \param Prefix An optional prefix for the \a Node + \param Node The concatenation of the \a Prefix and this value specifies + the XenStore key to remove +*/ +typedef NTSTATUS +(*XENBUS_STORE_REMOVE)( + IN PINTERFACE Interface, + IN PXENBUS_STORE_TRANSACTION Transaction OPTIONAL, + IN PCHAR Prefix OPTIONAL, + IN PCHAR Node + ); + +/*! \typedef XENBUS_STORE_DIRECTORY + \brief Enumerate all immediate child keys of a XenStore key + + \param Interface The interface header + \param Transaction The transaction handle (NULL if this removal is not + part of a transaction) + \param Prefix An optional prefix for the \a Node + \param Node The concatenation of the \a Prefix and this value specifies + the XenStore key to enumerate + \param A pointer to a pointer that will be initialized with a memory + buffer containing a NUL separated list of key names + + The \a Buffer should be freed using \a XENBUS_STORE_FREE +*/ +typedef NTSTATUS +(*XENBUS_STORE_DIRECTORY)( + IN PINTERFACE Interface, + IN PXENBUS_STORE_TRANSACTION Transaction OPTIONAL, + IN PCHAR Prefix OPTIONAL, + IN PCHAR Node, + OUT PCHAR *Buffer + ); + +/*! \typedef XENBUS_STORE_TRANSACTION_START + \brief Start a XenStore transaction + + \param Interface The interface header + \param Transaction Pointer to a transaction handle to be initialized +*/ +typedef NTSTATUS +(*XENBUS_STORE_TRANSACTION_START)( + IN PINTERFACE Interface, + OUT PXENBUS_STORE_TRANSACTION *Transaction + ); + +/*! \typedef XENBUS_STORE_TRANSACTION_END + \brief End a XenStore transaction + + \param Interface The interface header + \param Transaction The transaction handle + \param Commit Set to TRUE if actions performed within the transaction should + be made visible, or FALSE if they should not be + + If \a Commit is TRUE and the transaction to found to clash then + STATUS_RETRY will be returned +*/ +typedef NTSTATUS +(*XENBUS_STORE_TRANSACTION_END)( + IN PINTERFACE Interface, + IN PXENBUS_STORE_TRANSACTION Transaction, + IN BOOLEAN Commit + ); + +/*! \typedef XENBUS_STORE_WATCH_ADD + \brief Add a XenStore watch + + \param Interface The interface header + \param Prefix An optional prefix for the \a Node + \param Node The concatenation of the \a Prefix and this value specifies + the XenStore key to watch + \param Event A pointer to an event object to be signalled when the + watch fires + \param Watch A pointer to a watch handle to be initialized +*/ +typedef NTSTATUS +(*XENBUS_STORE_WATCH_ADD)( + IN PINTERFACE Interface, + IN PCHAR Prefix OPTIONAL, + IN PCHAR Node, + IN PKEVENT Event, + OUT PXENBUS_STORE_WATCH *Watch + ); + +/*! \typedef XENBUS_STORE_WATCH_REMOVE + \brief Remove a XenStore watch + + \param Interface The interface header + \param Watch The watch handle +*/ +typedef NTSTATUS +(*XENBUS_STORE_WATCH_REMOVE)( + IN PINTERFACE Interface, + IN PXENBUS_STORE_WATCH Watch + ); + +/*! \typedef XENBUS_STORE_POLL + \brief Poll for XenStore activity + + \param Interface The interface header + + If it is necessary to spin at DISPATCH_LEVEL waiting for XenStore + activity then this will block the normal STORE interface DPC so this + method must be regularly invoked during the spin loop to check for + XenStore activity +*/ +typedef VOID +(*XENBUS_STORE_POLL)( + IN PINTERFACE Interface + ); + +// {86824C3B-D34E-4753-B281-2F1E3AD214D7} +DEFINE_GUID(GUID_XENBUS_STORE_INTERFACE, +0x86824c3b, 0xd34e, 0x4753, 0xb2, 0x81, 0x2f, 0x1e, 0x3a, 0xd2, 0x14, 0xd7); + +struct _XENBUS_STORE_INTERFACE_V1 { + INTERFACE Interface; + XENBUS_STORE_ACQUIRE StoreAcquire; + XENBUS_STORE_RELEASE StoreRelease; + XENBUS_STORE_FREE StoreFree; + XENBUS_STORE_READ StoreRead; + XENBUS_STORE_PRINTF StorePrintf; + XENBUS_STORE_REMOVE StoreRemove; + XENBUS_STORE_DIRECTORY StoreDirectory; + XENBUS_STORE_TRANSACTION_START StoreTransactionStart; + XENBUS_STORE_TRANSACTION_END StoreTransactionEnd; + XENBUS_STORE_WATCH_ADD StoreWatchAdd; + XENBUS_STORE_WATCH_REMOVE StoreWatchRemove; + XENBUS_STORE_POLL StorePoll; +}; + +/*! \struct _XENBUS_STORE_INTERFACE_V1 + \brief STORE interface version 1 +*/ +typedef struct _XENBUS_STORE_INTERFACE_V1 XENBUS_STORE_INTERFACE, *PXENBUS_STORE_INTERFACE; + +/*! \def XENBUS_STORE + \brief Macro at assist in method invocation +*/ +#define XENBUS_STORE(_Method, _Interface, ...) \ + (_Interface)->Store ## _Method((PINTERFACE)(_Interface), __VA_ARGS__) + +#endif // _WINDLL + +#define XENBUS_STORE_INTERFACE_VERSION_MIN 1 +#define XENBUS_STORE_INTERFACE_VERSION_MAX 1 #endif // _XENBUS_STORE_INTERFACE_H diff --git a/include/suspend_interface.h b/include/suspend_interface.h index 50728ee..1a39141 100644 --- a/include/suspend_interface.h +++ b/include/suspend_interface.h @@ -1,10 +1,10 @@ /* 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. @@ -12,7 +12,7 @@ * 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 @@ -29,92 +29,148 @@ * SUCH DAMAGE. */ +/*! \file suspend_interface.h + \brief XENBUS SUSPEND Interface + + This interface provides primitives to handle VM suspend/resume +*/ + #ifndef _XENBUS_SUSPEND_INTERFACE_H #define _XENBUS_SUSPEND_INTERFACE_H +#ifndef _WINDLL + +/*! \enum _XENBUS_SUSPEND_CALLBACK_TYPE + \brief Suspend callback type to be registered +*/ typedef enum _XENBUS_SUSPEND_CALLBACK_TYPE { SUSPEND_CALLBACK_TYPE_INVALID = 0, - SUSPEND_CALLBACK_EARLY, - SUSPEND_CALLBACK_LATE + SUSPEND_CALLBACK_EARLY, /*!< Early */ + SUSPEND_CALLBACK_LATE /*!< Late */ } XENBUS_SUSPEND_CALLBACK_TYPE, *PXENBUS_SUSPEND_CALLBACK_TYPE; +/*! \typedef XENBUS_SUSPEND_CALLBACK + \brief Suspend callback handle +*/ typedef struct _XENBUS_SUSPEND_CALLBACK XENBUS_SUSPEND_CALLBACK, *PXENBUS_SUSPEND_CALLBACK; -#define DEFINE_SUSPEND_OPERATIONS \ - SUSPEND_OPERATION(VOID, \ - Acquire, \ - ( \ - IN PXENBUS_SUSPEND_CONTEXT Context \ - ) \ - ) \ - SUSPEND_OPERATION(VOID, \ - Release, \ - ( \ - IN PXENBUS_SUSPEND_CONTEXT Context \ - ) \ - ) \ - SUSPEND_OPERATION(NTSTATUS, \ - Register, \ - ( \ - IN PXENBUS_SUSPEND_CONTEXT Context, \ - IN XENBUS_SUSPEND_CALLBACK_TYPE Type, \ - IN VOID (*Function)(PVOID), \ - IN PVOID Argument OPTIONAL, \ - OUT PXENBUS_SUSPEND_CALLBACK *Callback \ - ) \ - ) \ - SUSPEND_OPERATION(VOID, \ - Deregister, \ - ( \ - IN PXENBUS_SUSPEND_CONTEXT Context, \ - IN PXENBUS_SUSPEND_CALLBACK Callback \ - ) \ - ) \ - SUSPEND_OPERATION(ULONG, \ - Count, \ - ( \ - IN PXENBUS_SUSPEND_CONTEXT Context \ - ) \ - ) - -typedef struct _XENBUS_SUSPEND_CONTEXT XENBUS_SUSPEND_CONTEXT, *PXENBUS_SUSPEND_CONTEXT; - -#define SUSPEND_OPERATION(_Type, _Name, _Arguments) \ - _Type (*SUSPEND_ ## _Name) _Arguments; - -typedef struct _XENBUS_SUSPEND_OPERATIONS { - DEFINE_SUSPEND_OPERATIONS -} XENBUS_SUSPEND_OPERATIONS, *PXENBUS_SUSPEND_OPERATIONS; - -#undef SUSPEND_OPERATION - -typedef struct _XENBUS_SUSPEND_INTERFACE XENBUS_SUSPEND_INTERFACE, *PXENBUS_SUSPEND_INTERFACE; - -// 104f0a14-e2d5-42b6-b10f-a669ccd410a1 - -DEFINE_GUID(GUID_SUSPEND_INTERFACE, - 0x104f0a14, - 0xe2d5, - 0x42b6, - 0xb1, - 0x0f, - 0xa6, - 0x69, - 0xcc, - 0xd4, - 0x10, - 0xa1); - -#define SUSPEND_INTERFACE_VERSION 2 - -#define SUSPEND_OPERATIONS(_Interface) \ - (PXENBUS_SUSPEND_OPERATIONS *)((ULONG_PTR)(_Interface)) - -#define SUSPEND_CONTEXT(_Interface) \ - (PXENBUS_SUSPEND_CONTEXT *)((ULONG_PTR)(_Interface) + sizeof (PVOID)) - -#define SUSPEND(_Operation, _Interface, ...) \ - (*SUSPEND_OPERATIONS(_Interface))->SUSPEND_ ## _Operation((*SUSPEND_CONTEXT(_Interface)), __VA_ARGS__) +/*! \typedef XENBUS_SUSPEND_ACQUIRE + \brief Acquire a reference to the SUSPEND interface + + \param Interface The interface header +*/ +typedef NTSTATUS +(*XENBUS_SUSPEND_ACQUIRE)( + IN PINTERFACE Interface + ); + +/*! \typedef XENBUS_SUSPEND_RELEASE + \brief Release a reference to the SUSPEND interface + + \param Interface The interface header +*/ +typedef VOID +(*XENBUS_SUSPEND_RELEASE)( + IN PINTERFACE Interface + ); + +/*! \typedef XENBUS_SUSPEND_FUNCTION + \brief Suspend callback function + + \param Argument Context \a Argument supplied to \a XENBUS_SUSPEND_REGISTER + + Suspend callback functions are always invoked on one vCPU with all other + vCPUs corralled at the same IRQL as the callback. \a Early callback + functions are always invoked with IRQL == HIGH_LEVEL and \a Late callback + functions are always invoked with IRQL == DISPATCH_LEVEL +*/ +typedef VOID +(*XENBUS_SUSPEND_FUNCTION)( + IN PVOID Argument + ); + +/*! \typedef XENBUS_SUSPEND_REGISTER + \brief Register a suspend callback function + + \param Interface The interface header + \param Type The type of callback function to register + \param Function The callback function + \param Argument An optional context argument passed to the callback + \param Callback A pointer to a callback handle to be initialized +*/ +typedef NTSTATUS +(*XENBUS_SUSPEND_REGISTER)( + IN PINTERFACE Interface, + IN XENBUS_SUSPEND_CALLBACK_TYPE Type, + IN XENBUS_SUSPEND_FUNCTION Function, + IN PVOID Argument OPTIONAL, + OUT PXENBUS_SUSPEND_CALLBACK *Callback + ); + +/*! \typedef XENBUS_SUSPEND_DEREGISTER + \brief Deregister a suspend callback function + + \param Interface The interface header + \param Callback The callback handle +*/ +typedef VOID +(*XENBUS_SUSPEND_DEREGISTER)( + IN PINTERFACE Interface, + IN PXENBUS_SUSPEND_CALLBACK Callback + ); + +/*! \typedef XENBUS_SUSPEND_TRIGGER + \brief Trigger a VM suspend + + \param Interface The interface header + + This method must always be invoked with IRQL == PASSIVE_LEVEL +*/ +typedef VOID +(*XENBUS_SUSPEND_TRIGGER)( + IN PINTERFACE Interface + ); + +/*! \typedef XENBUS_SUSPEND_GET_COUNT + \brief Get the number of VM suspends that have occurred since boot + + \param Interface The interface header + \return The number of VM suspends +*/ +typedef ULONG +(*XENBUS_SUSPEND_GET_COUNT)( + IN PINTERFACE Interface + ); + +// {0554F2AF-B510-4C71-AC03-1C503E394238} +DEFINE_GUID(GUID_XENBUS_SUSPEND_INTERFACE, +0x554f2af, 0xb510, 0x4c71, 0xac, 0x3, 0x1c, 0x50, 0x3e, 0x39, 0x42, 0x38); + +/*! \struct _XENBUS_SUSPEND_INTERFACE_V1 + \brief SUSPEND interface version 1 +*/ +struct _XENBUS_SUSPEND_INTERFACE_V1 { + INTERFACE Interface; + XENBUS_SUSPEND_ACQUIRE Acquire; + XENBUS_SUSPEND_RELEASE Release; + XENBUS_SUSPEND_REGISTER Register; + XENBUS_SUSPEND_DEREGISTER Deregister; + XENBUS_SUSPEND_TRIGGER Trigger; + XENBUS_SUSPEND_GET_COUNT GetCount; +}; + +typedef struct _XENBUS_SUSPEND_INTERFACE_V1 XENBUS_SUSPEND_INTERFACE, *PXENBUS_SUSPEND_INTERFACE; + +/*! \def XENBUS_SUSPEND + \brief Macro at assist in method invocation +*/ +#define XENBUS_SUSPEND(_Method, _Interface, ...) \ + (_Interface)-> ## _Method((PINTERFACE)(_Interface), __VA_ARGS__) + +#endif // _WINDLL + +#define XENBUS_SUSPEND_INTERFACE_VERSION_MIN 1 +#define XENBUS_SUSPEND_INTERFACE_VERSION_MAX 1 #endif // _XENBUS_SUSPEND_INTERFACE_H diff --git a/include/util.h b/include/util.h index 723123b..a05fb34 100644 --- a/include/util.h +++ b/include/util.h @@ -276,4 +276,42 @@ __FreePage( MmFreePagesFromMdl(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 != L'\0' && + strchr(Delimiter, *Token) != NULL) + Token++; + + if (*Token == L'\0') + return NULL; + + End = Token + 1; + while (*End != L'\0' && + strchr(Delimiter, *End) == NULL) + End++; + + if (*End != L'\0') + *End++ = L'\0'; + + *Context = End; + + return Token; +} + #endif // _UTIL_H diff --git a/proj/configs.props b/proj/configs.props new file mode 100644 index 0000000..2567bcf --- /dev/null +++ b/proj/configs.props @@ -0,0 +1,53 @@ + + + + + Windows 8 Debug + Win32 + + + Windows 7 Debug + Win32 + + + Windows Vista Debug + Win32 + + + Windows 8 Release + Win32 + + + Windows 7 Release + Win32 + + + Windows Vista Release + Win32 + + + Windows8 Debug + x64 + + + Windows 7 Debug + x64 + + + Windows Vista Debug + x64 + + + Windows 8 Release + x64 + + + Windows 7 Release + x64 + + + Windows Vista Release + x64 + + + \ No newline at end of file diff --git a/proj/package/package.vcxproj b/proj/package/package.vcxproj index 2a96fd9..94f273a 100644 --- a/proj/package/package.vcxproj +++ b/proj/package/package.vcxproj @@ -1,168 +1,55 @@ - - - - - Windows Developer Preview Debug - Win32 - - - Windows Developer Preview Release - Win32 - - - Windows 7 Debug - Win32 - - - Windows 7 Release - Win32 - - - Windows Vista Debug - Win32 - - - Windows Vista Release - Win32 - - - Windows Developer Preview Debug - x64 - - - Windows Developer Preview Release - x64 - - - Windows 7 Debug - x64 - - - Windows 7 Release - x64 - - - Windows Vista Debug - x64 - - - Windows Vista Release - x64 - - - - {9B071A35-897C-477A-AEB7-95F77618A21D} - v4.5 - 11.0 - - - WindowsKernelModeDriver8.0 - Utility - Package - Windows Developer Preview Debug - true - - - - Windows8 - true - - - Windows8 - false - - - Windows7 - true - - - Windows7 - false - - - Vista - true - - - Vista - false - - - Windows8 - true - - - Windows8 - false - - - Windows7 - true - - - Windows7 - false - - - Vista - true - - - Vista - false - - - - - - - - - - true - Vista_x64;7_x64;Server2008_x64;Server2008R2_x64;Server8_x64 - Vista_x86;7_x86;Server2008_x86;8_x86 - - - DbgengKernelDebugger - False - False - None - - - - - - %PathToInf% - False - False - True - - 133563 - ..\..\xeniface\$(DDKPlatform) - - - - - - - - - - - - - - - - {22166290-65D8-49D2-BB88-33201797C7D8} - - - - - - - - - + + + + + + WindowsKernelModeDriver8.0 + Utility + Package + true + + + Windows Vista Debug + Win32 + DbgengKernelDebugger + + + + + + {9B071A35-897C-477A-AEB7-95F77618A21D} + + + + + + + true + Vista_x64;7_x64;Server2008_x64;Server2008R2_x64;Server8_x64 + Vista_x86;7_x86;Server2008_x86;8_x86 + DbgengKernelDebugger + False + False + None + %PathToInf% + False + False + True + 133563 + ..\$(ProjectName)\$(ConfigurationName)\$(Platform)\ + ..\$(ConfigurationName)\$(Platform)\ + ..\..\xeniface\$(DDKPlatform) + + + + {22166290-65D8-49D2-BB88-33201797C7D8} + + + + + + + + + \ No newline at end of file diff --git a/proj/targets.props b/proj/targets.props new file mode 100644 index 0000000..c8aba92 --- /dev/null +++ b/proj/targets.props @@ -0,0 +1,51 @@ + + + + Windows8 + true + + + Windows8 + false + + + Windows8 + true + + + Windows8 + false + + + Windows7 + true + + + Windows7 + false + + + Windows7 + true + + + Windows7 + false + + + Vista + true + + + Vista + false + + + Vista + true + + + Vista + false + + diff --git a/proj/xeniface.sln b/proj/xeniface.sln index 12c4895..1913a5b 100644 --- a/proj/xeniface.sln +++ b/proj/xeniface.sln @@ -2,13 +2,14 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2012 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xeniface", "xeniface\xeniface.vcxproj", "{22166290-65D8-49D2-BB88-33201797C7D8}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LiteAgent", "liteagent\LiteAgent.vcxproj", "{2E61D2CC-865E-442C-8C83-B8DAFD7BBD3B}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "package", "package\package.vcxproj", "{9B071A35-897C-477A-AEB7-95F77618A21D}" ProjectSection(ProjectDependencies) = postProject + {22166290-65D8-49D2-BB88-33201797C7D8} = {22166290-65D8-49D2-BB88-33201797C7D8} {2E61D2CC-865E-442C-8C83-B8DAFD7BBD3B} = {2E61D2CC-865E-442C-8C83-B8DAFD7BBD3B} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LiteAgent", "liteagent\LiteAgent.vcxproj", "{2E61D2CC-865E-442C-8C83-B8DAFD7BBD3B}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 diff --git a/proj/xeniface/xeniface.vcxproj b/proj/xeniface/xeniface.vcxproj index b9222ed..e4898a6 100644 --- a/proj/xeniface/xeniface.vcxproj +++ b/proj/xeniface/xeniface.vcxproj @@ -1,230 +1,100 @@ - + - - - Windows Developer Preview Debug - Win32 - - - Windows Developer Preview Release - Win32 - - - Windows 8 Debug - Win32 - - - Windows 8 Release - Win32 - - - Windows 7 Debug - Win32 - - - Windows 7 Release - Win32 - - - Windows Vista Debug - Win32 - - - Windows Vista Release - Win32 - - - Windows Developer Preview Debug - x64 - - - Windows Developer Preview Release - x64 - - - Windows 8 Debug - x64 - - - Windows 8 Release - x64 - - - Windows 7 Debug - x64 - - - Windows 7 Release - x64 - - - Windows Vista Debug - x64 - - - Windows Vista Release - x64 - - - - {22166290-65D8-49D2-BB88-33201797C7D8} - v4.5 - 11.0 - xeniface - - - WindowsKernelModeDriver8.0 - Driver - WDM - Windows Developer Preview Debug - - - - Windows8 - true - - - Windows8 - false - - - Windows7 - true - - - Windows7 - false - - - Vista - true - - - Vista - false - - - Windows8 - true - - - Windows8 - false - - - Windows7 - true - - - Windows7 - false - - - Vista - true - - - Vista - false - - - - - - - - - - ..\..\include;$(IncludePath) - true - false - - - - $(SolutionDir)..\include;$(SolutionDir)\liteagent;%(AdditionalIncludeDirectories) - __i386__;%(PreprocessorDefinitions) - true - - - $(DDK_LIB_PATH)\ntstrsafe.lib;%(AdditionalDependencies) - false - - - $(SolutionDir)..\include;%(AdditionalIncludeDirectories) - - - true - x86 - true - $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION).$(BUILD_NUMBER) - true - - - - - $(SolutionDir)..\include;%(AdditionalIncludeDirectories) - __x86_64__;__MODULE__="XENIFACE";%(PreprocessorDefinitions) - true - - - $(DDK_LIB_PATH)\ntstrsafe.lib;%(AdditionalDependencies) - - - $(SolutionDir)..\include;%(AdditionalIncludeDirectories) - - - true - amd64 - true - $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION).$(BUILD_NUMBER) - true - - - - - - - - - - - - - - - - - $(IntDir)/wmi.bmf - - - - - ..\..\src\xeniface\wmi_generated.h - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + WindowsKernelModeDriver8.0 + Driver + WDM + + + Windows Vista Debug + Win32 + DbgengKernelDebugger + + + + + + {22166290-65D8-49D2-BB88-33201797C7D8} + + + + + + + ..\..\include;$(IncludePath) + true + false + ..\$(ProjectName)\$(ConfigurationName)\$(Platform)\ + ..\$(ConfigurationName)\$(Platform)\ + + + + + __MODULE__="XENIFACE";POOL_NX_OPTIN=1;%(PreprocessorDefinitions) + EnableAllWarnings + 4711;4548;4820;4668;4255;6001;6054;%(DisableSpecificWarnings) + true + true + + + false + $(DDK_LIB_PATH)\ntstrsafe.lib;%(AdditionalDependencies) + false + + + true + true + $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION).$(BUILD_NUMBER) + true + + + + + __i386__;%(PreprocessorDefinitions) + + + x86 + + + + + __x86_64__;%(PreprocessorDefinitions) + + + amd64 + + + + + + + + + + + + + + + + + + + $(IntDir)/wmi.bmf + + + + + ..\..\src\xeniface\wmi_generated.h + + + + + + + + + + \ No newline at end of file diff --git a/proj/xeniface/xeniface.vcxproj.user b/proj/xeniface/xeniface.vcxproj.user index 5abd8fd..f82be50 100644 --- a/proj/xeniface/xeniface.vcxproj.user +++ b/proj/xeniface/xeniface.vcxproj.user @@ -1,8 +1,8 @@ - - - - TestSign - ..\xeniface.pfx - http://timestamp.verisign.com/scripts/timstamp.dll - + + + + TestSign + ..\xeniface.pfx + http://timestamp.verisign.com/scripts/timstamp.dll + \ No newline at end of file diff --git a/src/xeniface/fdo.c b/src/xeniface/fdo.c index 0c388dd..20fe167 100644 --- a/src/xeniface/fdo.c +++ b/src/xeniface/fdo.c @@ -41,6 +41,7 @@ #include "driver.h" +#include "registry.h" #include "fdo.h" #include "thread.h" #include "mutex.h" @@ -70,7 +71,12 @@ FdoInitialiseXSRegistryEntries( char *value; NTSTATUS status; NT_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); - status = STORE(Read, Fdo->StoreInterface, NULL, NULL, "/mh/boot-time/management-mac-address", &value); + status = XENBUS_STORE(Read, + &Fdo->StoreInterface, + NULL, + NULL, + "/mh/boot-time/management-mac-address", + &value); if (!NT_SUCCESS(status)){ XenIfaceDebugPrint(ERROR, "no such xenstore key\n"); goto failXS; @@ -109,7 +115,7 @@ FdoInitialiseXSRegistryEntries( ZwClose(RegHandle); RtlFreeUnicodeString(&UnicodeValue); - STORE(Free, Fdo->StoreInterface, value); + XENBUS_STORE(Free, &Fdo->StoreInterface, value); return; @@ -122,7 +128,8 @@ failWrite: failReg: XenIfaceDebugPrint(ERROR, "Fail : Reg\n"); - STORE(Free, Fdo->StoreInterface, value); + XENBUS_STORE(Free, &Fdo->StoreInterface, value); + failXS: XenIfaceDebugPrint(ERROR, "Failed to initialise registry (%08x)\n", status); return; @@ -151,11 +158,9 @@ static NTSTATUS FdoRegistryThreadHandler(IN PXENIFACE_THREAD Self, status = KeWaitForMultipleObjects(REGISTRY_EVENTS, (PVOID *)threadevents, WaitAny, Executive, KernelMode, TRUE, NULL, NULL); if ((status>=STATUS_WAIT_0) && (status < STATUS_WAIT_0+REGISTRY_EVENTS)) { if (status == STATUS_WAIT_0+REGISTRY_WRITE_EVENT) { - if (Fdo->StoreInterface) { - XenIfaceDebugPrint(ERROR,"WriteRegistry\n"); - FdoInitialiseXSRegistryEntries(Fdo); - KeClearEvent(threadevents[REGISTRY_WRITE_EVENT]); - } + XenIfaceDebugPrint(ERROR,"WriteRegistry\n"); + FdoInitialiseXSRegistryEntries(Fdo); + KeClearEvent(threadevents[REGISTRY_WRITE_EVENT]); } if (status == STATUS_WAIT_0+REGISTRY_THREAD_END_EVENT) { if (ThreadIsAlerted(Self)) @@ -642,40 +647,24 @@ FdoParseResources( } } - -PXENBUS_STORE_INTERFACE -FdoGetStoreInterface( - IN PXENIFACE_FDO Fdo - ) -{ - return Fdo->StoreInterface; -} - - -PXENBUS_SUSPEND_INTERFACE -FdoGetSuspendInterface( - IN PXENIFACE_FDO Fdo - ) -{ - return Fdo->SuspendInterface; -} - - static FORCEINLINE NTSTATUS __FdoD3ToD0( IN PXENIFACE_FDO Fdo ) { POWER_STATE PowerState; + NTSTATUS status; Trace("====>\n"); ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL); ASSERT3U(__FdoGetDevicePowerState(Fdo), ==, PowerDeviceD3); - __FdoSetDevicePowerState(Fdo, PowerDeviceD0); + status = XENBUS_STORE(Acquire, &Fdo->StoreInterface); + if (!NT_SUCCESS(status)) + goto fail1; - STORE(Acquire, Fdo->StoreInterface); + __FdoSetDevicePowerState(Fdo, PowerDeviceD0); PowerState.DeviceState = PowerDeviceD0; PoSetPowerState(Fdo->Dx->DeviceObject, @@ -685,6 +674,11 @@ __FdoD3ToD0( Trace("<====\n"); return STATUS_SUCCESS; + +fail1: + Error("fail1 (%08x)\n", status); + + return status; } static FORCEINLINE VOID @@ -706,7 +700,7 @@ __FdoD0ToD3( __FdoSetDevicePowerState(Fdo, PowerDeviceD3); - STORE(Release, Fdo->StoreInterface); + XENBUS_STORE(Release, &Fdo->StoreInterface); Trace("<====\n"); } @@ -741,31 +735,40 @@ FdoD3ToD0( if (!NT_SUCCESS(status)) goto fail1; - SUSPEND(Acquire, Fdo->SuspendInterface); - SHARED_INFO(Acquire, Fdo->SharedInfoInterface); + status = XENBUS_SUSPEND(Acquire, &Fdo->SuspendInterface); + if (!NT_SUCCESS(status)) + goto fail2; - + status = XENBUS_SHARED_INFO(Acquire, &Fdo->SharedInfoInterface); + if (!NT_SUCCESS(status)) + goto fail3; - status = SUSPEND(Register, - Fdo->SuspendInterface, - SUSPEND_CALLBACK_LATE, - FireSuspendEvent, - Fdo, - &Fdo->SuspendCallbackLate); + status = XENBUS_SUSPEND(Register, + &Fdo->SuspendInterface, + SUSPEND_CALLBACK_LATE, + FireSuspendEvent, + Fdo, + &Fdo->SuspendCallbackLate); if (!NT_SUCCESS(status)) - goto fail2; + goto fail4; + Fdo->InterfacesAcquired = TRUE; KeLowerIrql(Irql); - - - return STATUS_SUCCESS; +fail4: + Error("fail4\n"); + + XENBUS_SHARED_INFO(Release, &Fdo->SharedInfoInterface); + +fail3: + Error("fail3\n"); + + XENBUS_SUSPEND(Release, &Fdo->SuspendInterface); + fail2: Error("fail2\n"); - SHARED_INFO(Release, Fdo->SharedInfoInterface); - SUSPEND(Release, Fdo->SuspendInterface); __FdoD0ToD3(Fdo); @@ -788,13 +791,14 @@ FdoD0ToD3( Fdo->InterfacesAcquired = FALSE; KeRaiseIrql(DISPATCH_LEVEL, &Irql); - SUSPEND(Deregister, - Fdo->SuspendInterface, - Fdo->SuspendCallbackLate); + XENBUS_SUSPEND(Deregister, + &Fdo->SuspendInterface, + Fdo->SuspendCallbackLate); Fdo->SuspendCallbackLate = NULL; - SHARED_INFO(Release, Fdo->SharedInfoInterface); - SUSPEND(Release, Fdo->SuspendInterface); + XENBUS_SHARED_INFO(Release, &Fdo->SharedInfoInterface); + + XENBUS_SUSPEND(Release, &Fdo->SuspendInterface); __FdoD0ToD3(Fdo); @@ -2105,98 +2109,65 @@ FdoDispatch( return status; } +#define SERVICES_KEY L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services" -static NTSTATUS -FdoQueryStoreInterface( - IN PXENIFACE_FDO Fdo - ) -{ +static FORCEINLINE NTSTATUS +__FdoQueryInterface( + IN PXENIFACE_FDO Fdo, + IN const WCHAR *ProviderName, + IN const CHAR *InterfaceName, + IN const GUID *Guid, + IN ULONG Version, + OUT PINTERFACE Interface, + IN ULONG Size, + IN BOOLEAN Optional + ) +{ + UNICODE_STRING Unicode; + HANDLE InterfacesKey; + HANDLE SubscriberKey; KEVENT Event; IO_STATUS_BLOCK StatusBlock; PIRP Irp; PIO_STACK_LOCATION StackLocation; - INTERFACE Interface; NTSTATUS status; ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); - KeInitializeEvent(&Event, NotificationEvent, FALSE); - RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK)); - RtlZeroMemory(&Interface, sizeof(INTERFACE)); + Unicode.MaximumLength = (USHORT)((wcslen(SERVICES_KEY) + + 1 + + wcslen(ProviderName) + + 1 + + wcslen(L"Interfaces") + + 1) * sizeof (WCHAR)); - Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, - Fdo->LowerDeviceObject, - NULL, - 0, - NULL, - &Event, - &StatusBlock); + Unicode.Buffer = __FdoAllocate(Unicode.MaximumLength); - status = STATUS_UNSUCCESSFUL; - if (Irp == NULL) + status = STATUS_NO_MEMORY; + if (Unicode.Buffer == NULL) goto fail1; - StackLocation = IoGetNextIrpStackLocation(Irp); - StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE; - - StackLocation->Parameters.QueryInterface.InterfaceType = &GUID_STORE_INTERFACE; - StackLocation->Parameters.QueryInterface.Size = sizeof (INTERFACE); - StackLocation->Parameters.QueryInterface.Version = STORE_INTERFACE_VERSION; - StackLocation->Parameters.QueryInterface.Interface = &Interface; - - Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + status = RtlStringCbPrintfW(Unicode.Buffer, + Unicode.MaximumLength, + SERVICES_KEY L"\\%ws\\Interfaces", + ProviderName); + ASSERT(NT_SUCCESS(status)); - status = IoCallDriver(Fdo->LowerDeviceObject, Irp); - if (status == STATUS_PENDING) { - (VOID) KeWaitForSingleObject(&Event, - Executive, - KernelMode, - FALSE, - NULL); - status = StatusBlock.Status; - } + Unicode.Length = (USHORT)(wcslen(Unicode.Buffer) * sizeof (WCHAR)); + status = RegistryOpenKey(NULL, &Unicode, KEY_READ, &InterfacesKey); if (!NT_SUCCESS(status)) goto fail2; - status = STATUS_INVALID_PARAMETER; - if (Interface.Version != STORE_INTERFACE_VERSION) + status = RegistryCreateSubKey(InterfacesKey, + "XENIFACE", + REG_OPTION_NON_VOLATILE, + &SubscriberKey); + if (!NT_SUCCESS(status)) goto fail3; - - Fdo->StoreInterface = (PXENBUS_STORE_INTERFACE)Interface.Context; - - return STATUS_SUCCESS; - -fail3: - Error("fail3\n"); - -fail2: - Error("fail2\n"); - -fail1: - Error("fail1 (%08x)\n", status); - - return status; -} - - -static NTSTATUS -FdoQuerySuspendInterface( - IN PXENIFACE_FDO Fdo - ) -{ - KEVENT Event; - IO_STATUS_BLOCK StatusBlock; - PIRP Irp; - PIO_STACK_LOCATION StackLocation; - INTERFACE Interface; - NTSTATUS status; - - ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); - + KeInitializeEvent(&Event, NotificationEvent, FALSE); RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK)); - RtlZeroMemory(&Interface, sizeof(INTERFACE)); Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, Fdo->LowerDeviceObject, @@ -2208,15 +2179,15 @@ FdoQuerySuspendInterface( status = STATUS_UNSUCCESSFUL; if (Irp == NULL) - goto fail1; + goto fail4; StackLocation = IoGetNextIrpStackLocation(Irp); StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE; - StackLocation->Parameters.QueryInterface.InterfaceType = &GUID_SUSPEND_INTERFACE; - StackLocation->Parameters.QueryInterface.Size = sizeof (INTERFACE); - StackLocation->Parameters.QueryInterface.Version = SUSPEND_INTERFACE_VERSION; - StackLocation->Parameters.QueryInterface.Interface = &Interface; + StackLocation->Parameters.QueryInterface.InterfaceType = Guid; + StackLocation->Parameters.QueryInterface.Size = (USHORT)Size; + StackLocation->Parameters.QueryInterface.Version = (USHORT)Version; + StackLocation->Parameters.QueryInterface.Interface = Interface; Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; @@ -2230,101 +2201,72 @@ FdoQuerySuspendInterface( status = StatusBlock.Status; } - if (!NT_SUCCESS(status)) - goto fail2; - - status = STATUS_INVALID_PARAMETER; - if (Interface.Version != SUSPEND_INTERFACE_VERSION) - goto fail3; - - Fdo->SuspendInterface = (PXENBUS_SUSPEND_INTERFACE)Interface.Context; - - return STATUS_SUCCESS; - -fail3: - Error("fail3\n"); - -fail2: - Error("fail2\n"); - -fail1: - Error("fail1 (%08x)\n", status); - - return status; -} - -static NTSTATUS -FdoQuerySharedInfoInterface( - IN PXENIFACE_FDO Fdo - ) -{ - KEVENT Event; - IO_STATUS_BLOCK StatusBlock; - PIRP Irp; - PIO_STACK_LOCATION StackLocation; - INTERFACE Interface; - NTSTATUS status; - - ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); + if (!NT_SUCCESS(status)) { + if (status == STATUS_NOT_SUPPORTED && Optional) + goto done; - KeInitializeEvent(&Event, NotificationEvent, FALSE); - RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK)); - RtlZeroMemory(&Interface, sizeof(INTERFACE)); + goto fail5; + } - Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, - Fdo->LowerDeviceObject, - NULL, - 0, - NULL, - &Event, - &StatusBlock); + status = RegistryUpdateDwordValue(SubscriberKey, + (PCHAR)InterfaceName, + Version); + if (!NT_SUCCESS(status)) + goto fail6; - status = STATUS_UNSUCCESSFUL; - if (Irp == NULL) - goto fail1; +done: + RegistryCloseKey(SubscriberKey); - StackLocation = IoGetNextIrpStackLocation(Irp); - StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE; + RegistryCloseKey(InterfacesKey); - StackLocation->Parameters.QueryInterface.InterfaceType = &GUID_SHARED_INFO_INTERFACE; - StackLocation->Parameters.QueryInterface.Size = sizeof (INTERFACE); - StackLocation->Parameters.QueryInterface.Version = SHARED_INFO_INTERFACE_VERSION; - StackLocation->Parameters.QueryInterface.Interface = &Interface; - - Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + __FdoFree(Unicode.Buffer); - status = IoCallDriver(Fdo->LowerDeviceObject, Irp); - if (status == STATUS_PENDING) { - (VOID) KeWaitForSingleObject(&Event, - Executive, - KernelMode, - FALSE, - NULL); - status = StatusBlock.Status; - } + return STATUS_SUCCESS; - if (!NT_SUCCESS(status)) - goto fail2; +fail6: + Error("fail6\n"); - status = STATUS_INVALID_PARAMETER; - if (Interface.Version != SHARED_INFO_INTERFACE_VERSION) - goto fail3; +fail5: + Error("fail5\n"); - Fdo->SharedInfoInterface = (PXENBUS_SHARED_INFO_INTERFACE)Interface.Context; +fail4: + Error("fail4\n"); - return STATUS_SUCCESS; + RegistryCloseKey(SubscriberKey); fail3: Error("fail3\n"); + RegistryCloseKey(InterfacesKey); + fail2: Error("fail2\n"); + __FdoFree(Unicode.Buffer); + fail1: Error("fail1 (%08x)\n", status); return status; } + +#define FDO_QUERY_INTERFACE( \ + _Fdo, \ + _ProviderName, \ + _InterfaceName, \ + _Version, \ + _Interface, \ + _Size, \ + _Optional) \ + __FdoQueryInterface((_Fdo), \ + L ## #_ProviderName, \ + #_InterfaceName, \ + &GUID_ ## _ProviderName ## _ ## _InterfaceName ## _INTERFACE, \ + (_Version), \ + (_Interface), \ + (_Size), \ + (_Optional)) + NTSTATUS FdoCreate( IN PDEVICE_OBJECT PhysicalDeviceObject @@ -2399,17 +2341,35 @@ FdoCreate( if (!NT_SUCCESS(status)) goto fail7; - status = FdoQueryStoreInterface(Fdo); + status = FDO_QUERY_INTERFACE(Fdo, + XENBUS, + SUSPEND, + XENBUS_SUSPEND_INTERFACE_VERSION_MAX, + (PINTERFACE)&Fdo->SuspendInterface, + sizeof (Fdo->SuspendInterface), + FALSE); if (!NT_SUCCESS(status)) goto fail8; - status = FdoQuerySuspendInterface(Fdo); + status = FDO_QUERY_INTERFACE(Fdo, + XENBUS, + SHARED_INFO, + XENBUS_SHARED_INFO_INTERFACE_VERSION_MAX, + (PINTERFACE)&Fdo->SharedInfoInterface, + sizeof (Fdo->SharedInfoInterface), + FALSE); if (!NT_SUCCESS(status)) goto fail9; - status = FdoQuerySharedInfoInterface(Fdo); - if (!NT_SUCCESS(status)) - goto fail10; + status = FDO_QUERY_INTERFACE(Fdo, + XENBUS, + STORE, + XENBUS_STORE_INTERFACE_VERSION_MAX, + (PINTERFACE)&Fdo->StoreInterface, + sizeof (Fdo->StoreInterface), + FALSE); + if (!NT_SUCCESS(status)) + goto fail10; InitializeMutex(&Fdo->Mutex); InitializeListHead(&Dx->ListEntry); @@ -2435,16 +2395,21 @@ FdoCreate( fail11: Error("fail11\n"); - Fdo->SharedInfoInterface = NULL; + + RtlZeroMemory(&Fdo->StoreInterface, + sizeof (XENBUS_STORE_INTERFACE)); fail10: Error("fail10\n"); - Fdo->SuspendInterface = NULL; + + RtlZeroMemory(&Fdo->SharedInfoInterface, + sizeof (XENBUS_SHARED_INFO_INTERFACE)); fail9: Error("fail8\n"); - Fdo->StoreInterface = NULL; + RtlZeroMemory(&Fdo->SuspendInterface, + sizeof (XENBUS_SUSPEND_INTERFACE)); fail8: Error("fail8\n"); @@ -2521,9 +2486,15 @@ FdoDestroy( RtlZeroMemory(&Fdo->Mutex, sizeof (XENIFACE_MUTEX)); Fdo->InterfacesAcquired = FALSE; - Fdo->SuspendInterface = NULL; - Fdo->StoreInterface = NULL; - Fdo->SharedInfoInterface = NULL; + + RtlZeroMemory(&Fdo->StoreInterface, + sizeof (XENBUS_STORE_INTERFACE)); + + RtlZeroMemory(&Fdo->SharedInfoInterface, + sizeof (XENBUS_SHARED_INFO_INTERFACE)); + + RtlZeroMemory(&Fdo->SuspendInterface, + sizeof (XENBUS_SUSPEND_INTERFACE)); ThreadAlert(Fdo->registryThread); ThreadJoin(Fdo->registryThread); diff --git a/src/xeniface/fdo.h b/src/xeniface/fdo.h index 272aeb9..32f6bb1 100644 --- a/src/xeniface/fdo.h +++ b/src/xeniface/fdo.h @@ -56,49 +56,49 @@ typedef struct _FDO_RESOURCE { typedef struct _XENIFACE_FDO { - struct _XENIFACE_DX *Dx; - PDEVICE_OBJECT LowerDeviceObject; - PDEVICE_OBJECT PhysicalDeviceObject; - DEVICE_CAPABILITIES LowerDeviceCapabilities; - ULONG Usage[DeviceUsageTypeDumpFile + 1]; - BOOLEAN NotDisableable; + struct _XENIFACE_DX *Dx; + PDEVICE_OBJECT LowerDeviceObject; + PDEVICE_OBJECT PhysicalDeviceObject; + DEVICE_CAPABILITIES LowerDeviceCapabilities; + ULONG Usage[DeviceUsageTypeDumpFile + 1]; + BOOLEAN NotDisableable; - PXENIFACE_THREAD SystemPowerThread; - PIRP SystemPowerIrp; - PXENIFACE_THREAD DevicePowerThread; - PIRP DevicePowerIrp; + PXENIFACE_THREAD SystemPowerThread; + PIRP SystemPowerIrp; + PXENIFACE_THREAD DevicePowerThread; + PIRP DevicePowerIrp; - XENIFACE_MUTEX Mutex; - ULONG References; + XENIFACE_MUTEX Mutex; + ULONG References; - FDO_RESOURCE Resource[RESOURCE_COUNT]; + FDO_RESOURCE Resource[RESOURCE_COUNT]; - PXENBUS_STORE_INTERFACE StoreInterface; + XENBUS_STORE_INTERFACE StoreInterface; - PXENBUS_SUSPEND_INTERFACE SuspendInterface; + XENBUS_SUSPEND_INTERFACE SuspendInterface; - PXENBUS_SHARED_INFO_INTERFACE SharedInfoInterface; + XENBUS_SHARED_INFO_INTERFACE SharedInfoInterface; - PXENBUS_SUSPEND_CALLBACK SuspendCallbackLate; + PXENBUS_SUSPEND_CALLBACK SuspendCallbackLate; - BOOLEAN InterfacesAcquired; + BOOLEAN InterfacesAcquired; #define MAX_SESSIONS (65536) - int WmiReady; + int WmiReady; - USHORT Sessions; - FAST_MUTEX SessionLock; - LIST_ENTRY SessionHead; + USHORT Sessions; + FAST_MUTEX SessionLock; + LIST_ENTRY SessionHead; - PXENIFACE_THREAD registryThread; - KEVENT registryWriteEvent; + PXENIFACE_THREAD registryThread; + KEVENT registryWriteEvent; - UNICODE_STRING SuggestedInstanceName; + UNICODE_STRING SuggestedInstanceName; - UNICODE_STRING InterfaceName; + UNICODE_STRING InterfaceName; } XENIFACE_FDO, *PXENIFACE_FDO; diff --git a/src/xeniface/ioctls.c b/src/xeniface/ioctls.c index 928dfed..3bef9ea 100644 --- a/src/xeniface/ioctls.c +++ b/src/xeniface/ioctls.c @@ -103,7 +103,7 @@ IoctlRead( if (!__IsValidStr(Buffer, InLen)) goto fail2; - status = STORE(Read, Fdo->StoreInterface, NULL, NULL, Buffer, &Value); + status = XENBUS_STORE(Read, &Fdo->StoreInterface, NULL, NULL, Buffer, &Value); if (!NT_SUCCESS(status)) goto fail3; @@ -127,12 +127,12 @@ IoctlRead( done: *Info = (ULONG_PTR)Length; - STORE(Free, Fdo->StoreInterface, Value); + XENBUS_STORE(Free, &Fdo->StoreInterface, Value); return status; fail4: XenIfaceDebugPrint(ERROR, "|%s: Fail4 (\"%s\")=(%d < %d)\n", __FUNCTION__, Buffer, OutLen, Length); - STORE(Free, Fdo->StoreInterface, Value); + XENBUS_STORE(Free, &Fdo->StoreInterface, Value); fail3: XenIfaceDebugPrint(ERROR, "|%s: Fail3 (\"%s\")\n", __FUNCTION__, Buffer); fail2: @@ -168,7 +168,7 @@ IoctlWrite( if (!__IsValidStr(Value, InLen - Length)) goto fail3; - status = STORE(Write, Fdo->StoreInterface, NULL, NULL, Buffer, Value); + status = XENBUS_STORE(Printf, &Fdo->StoreInterface, NULL, NULL, Buffer, Value); if (!NT_SUCCESS(status)) goto fail4; @@ -208,7 +208,7 @@ IoctlDirectory( if (!__IsValidStr(Buffer, InLen)) goto fail2; - status = STORE(Directory, Fdo->StoreInterface, NULL, NULL, Buffer, &Value); + status = XENBUS_STORE(Directory, &Fdo->StoreInterface, NULL, NULL, Buffer, &Value); if (!NT_SUCCESS(status)) goto fail3; @@ -236,12 +236,12 @@ IoctlDirectory( done: *Info = (ULONG_PTR)Length; - STORE(Free, Fdo->StoreInterface, Value); + XENBUS_STORE(Free, &Fdo->StoreInterface, Value); return status; fail4: XenIfaceDebugPrint(ERROR, "|%s: Fail4 (\"%s\")=(%d < %d)\n", __FUNCTION__, Buffer, OutLen, Length); - STORE(Free, Fdo->StoreInterface, Value); + XENBUS_STORE(Free, &Fdo->StoreInterface, Value); fail3: XenIfaceDebugPrint(ERROR, "|%s: Fail3 (\"%s\")\n", __FUNCTION__, Buffer); fail2: @@ -269,7 +269,7 @@ IoctlRemove( if (!__IsValidStr(Buffer, InLen)) goto fail2; - status = STORE(Remove, Fdo->StoreInterface, NULL, NULL, Buffer); + status = XENBUS_STORE(Remove, &Fdo->StoreInterface, NULL, NULL, Buffer); if (!NT_SUCCESS(status)) goto fail3; @@ -298,9 +298,6 @@ XenIFaceIoctl( ULONG OutLen = Stack->Parameters.DeviceIoControl.OutputBufferLength; status = STATUS_DEVICE_NOT_READY; - if (Fdo->StoreInterface == NULL) - goto done; - if (Fdo->InterfacesAcquired == FALSE) goto done; diff --git a/src/xeniface/registry.c b/src/xeniface/registry.c new file mode 100644 index 0000000..5843ef5 --- /dev/null +++ b/src/xeniface/registry.c @@ -0,0 +1,1200 @@ +/* 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 +#include + +#include "registry.h" +#include "assert.h" + +#define REGISTRY_POOL 'GERX' + +static UNICODE_STRING RegistryPath; + +static FORCEINLINE PVOID +__RegistryAllocate( + IN ULONG Length + ) +{ + return __AllocateNonPagedPoolWithTag(Length, REGISTRY_POOL); +} + +static FORCEINLINE VOID +__RegistryFree( + IN PVOID Buffer + ) +{ + __FreePoolWithTag(Buffer, REGISTRY_POOL); +} + +NTSTATUS +RegistryInitialize( + IN PUNICODE_STRING Path + ) +{ + NTSTATUS status; + + ASSERT3P(RegistryPath.Buffer, ==, NULL); + + status = RtlUpcaseUnicodeString(&RegistryPath, Path, TRUE); + if (!NT_SUCCESS(status)) + goto fail1; + + return STATUS_SUCCESS; + +fail1: + Error("fail1 (%08x)\n", status); + + return status; +} + +VOID +RegistryTeardown( + VOID + ) +{ + RtlFreeUnicodeString(&RegistryPath); + RegistryPath.Buffer = NULL; + RegistryPath.MaximumLength = RegistryPath.Length = 0; +} + +NTSTATUS +RegistryOpenKey( + IN HANDLE Parent, + IN PUNICODE_STRING Path, + IN ACCESS_MASK DesiredAccess, + OUT PHANDLE Key + ) +{ + OBJECT_ATTRIBUTES Attributes; + NTSTATUS status; + + InitializeObjectAttributes(&Attributes, + Path, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + Parent, + NULL); + + status = ZwOpenKey(Key, + DesiredAccess, + &Attributes); + if (!NT_SUCCESS(status)) + goto fail1; + + return STATUS_SUCCESS; + +fail1: + return status; +} + +NTSTATUS +RegistryOpenServiceKey( + IN ACCESS_MASK DesiredAccess, + OUT PHANDLE Key + ) +{ + return RegistryOpenKey(NULL, &RegistryPath, DesiredAccess, Key); +} + +NTSTATUS +RegistryOpenSoftwareKey( + IN PDEVICE_OBJECT DeviceObject, + IN ACCESS_MASK DesiredAccess, + OUT PHANDLE Key + ) +{ + NTSTATUS status; + + status = IoOpenDeviceRegistryKey(DeviceObject, + PLUGPLAY_REGKEY_DRIVER, + DesiredAccess, + Key); + if (!NT_SUCCESS(status)) + goto fail1; + + return STATUS_SUCCESS; + +fail1: + return status; +} + +NTSTATUS +RegistryOpenHardwareKey( + IN PDEVICE_OBJECT DeviceObject, + IN ACCESS_MASK DesiredAccess, + OUT PHANDLE Key + ) +{ + HANDLE SubKey; + ULONG Length; + PKEY_NAME_INFORMATION Info; + PWCHAR Cursor; + UNICODE_STRING Unicode; + NTSTATUS status; + + status = IoOpenDeviceRegistryKey(DeviceObject, + PLUGPLAY_REGKEY_DEVICE, + KEY_READ, + &SubKey); + if (!NT_SUCCESS(status)) + goto fail1; + + Length = 0; + (VOID) ZwQueryKey(SubKey, + KeyNameInformation, + NULL, + 0, + &Length); + + status = STATUS_INVALID_PARAMETER; + if (Length == 0) + goto fail2; + + Info = __RegistryAllocate(Length + sizeof (WCHAR)); + + status = STATUS_NO_MEMORY; + if (Info == NULL) + goto fail3; + + status = ZwQueryKey(SubKey, + KeyNameInformation, + Info, + Length, + &Length); + if (!NT_SUCCESS(status)) + goto fail4; + + Info->Name[Info->NameLength / sizeof (WCHAR)] = '\0'; + + Cursor = wcsrchr(Info->Name, L'\\'); + ASSERT(Cursor != NULL); + + *Cursor = L'\0'; + + RtlInitUnicodeString(&Unicode, Info->Name); + + status = RegistryOpenKey(NULL, &Unicode, DesiredAccess, Key); + if (!NT_SUCCESS(status)) + goto fail5; + + __RegistryFree(Info); + + RegistryCloseKey(SubKey); + + return STATUS_SUCCESS; + +fail5: +fail4: + __RegistryFree(Info); + +fail3: +fail2: + RegistryCloseKey(SubKey); + +fail1: + return status; +} + +NTSTATUS +RegistryOpenSubKey( + IN PHANDLE Key, + IN PCHAR Name, + IN ACCESS_MASK DesiredAccess, + OUT PHANDLE SubKey + ) +{ + ANSI_STRING Ansi; + UNICODE_STRING Unicode; + NTSTATUS status; + + RtlInitAnsiString(&Ansi, Name); + + status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE); + if (!NT_SUCCESS(status)) + goto fail1; + + status = RegistryOpenKey(Key, &Unicode, DesiredAccess, SubKey); + if (!NT_SUCCESS(status)) + goto fail2; + + RtlFreeUnicodeString(&Unicode); + + return STATUS_SUCCESS; + +fail2: + RtlFreeUnicodeString(&Unicode); + +fail1: + return status; +} + +NTSTATUS +RegistryCreateSubKey( + IN PHANDLE Key, + IN PCHAR Name, + IN ULONG Options, + OUT PHANDLE SubKey + ) +{ + ANSI_STRING Ansi; + UNICODE_STRING Unicode; + OBJECT_ATTRIBUTES Attributes; + NTSTATUS status; + + RtlInitAnsiString(&Ansi, Name); + + status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE); + if (!NT_SUCCESS(status)) + goto fail1; + + InitializeObjectAttributes(&Attributes, + &Unicode, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + Key, + NULL); + + status = ZwCreateKey(SubKey, + KEY_ALL_ACCESS, + &Attributes, + 0, + NULL, + Options, + NULL + ); + if (!NT_SUCCESS(status)) + goto fail2; + + RtlFreeUnicodeString(&Unicode); + + return STATUS_SUCCESS; + +fail2: + RtlFreeUnicodeString(&Unicode); + +fail1: + return status; +} + +NTSTATUS +RegistryDeleteSubKey( + IN PHANDLE Key, + IN PCHAR Name + ) +{ + ANSI_STRING Ansi; + UNICODE_STRING Unicode; + HANDLE SubKey; + NTSTATUS status; + + RtlInitAnsiString(&Ansi, Name); + + status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE); + if (!NT_SUCCESS(status)) + goto fail1; + + status = RegistryOpenKey(Key, &Unicode, KEY_ALL_ACCESS, &SubKey); + if (!NT_SUCCESS(status)) + goto fail2; + + status = ZwDeleteKey(SubKey); + if (!NT_SUCCESS(status)) + goto fail3; + + ZwClose(SubKey); + + RtlFreeUnicodeString(&Unicode); + + return STATUS_SUCCESS; + +fail3: + ZwClose(SubKey); + +fail2: + RtlFreeUnicodeString(&Unicode); + +fail1: + return status; +} + +NTSTATUS +RegistryEnumerateSubKeys( + IN HANDLE Key, + IN NTSTATUS (*Callback)(PVOID, HANDLE, PCHAR), + IN PVOID Context + ) +{ + ULONG Size; + NTSTATUS status; + PKEY_FULL_INFORMATION Full; + PKEY_BASIC_INFORMATION Basic; + ULONG Index; + + status = ZwQueryKey(Key, + KeyFullInformation, + NULL, + 0, + &Size); + if (status != STATUS_BUFFER_TOO_SMALL) + goto fail1; + + Full = __RegistryAllocate(Size); + + status = STATUS_NO_MEMORY; + if (Full == NULL) + goto fail2; + + status = ZwQueryKey(Key, + KeyFullInformation, + Full, + Size, + &Size); + if (!NT_SUCCESS(status)) + goto fail3; + + Size = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name) + + Full->MaxNameLen; + + Basic = __RegistryAllocate(Size); + status = STATUS_NO_MEMORY; + if (Basic == NULL) + goto fail4; + + for (Index = 0; Index < Full->SubKeys; Index++) { + UNICODE_STRING Unicode; + ANSI_STRING Ansi; + + status = ZwEnumerateKey(Key, + Index, + KeyBasicInformation, + Basic, + Size, + &Size); + if (!NT_SUCCESS(status)) + goto fail5; + + Unicode.MaximumLength = (USHORT)Basic->NameLength; + Unicode.Buffer = Basic->Name; + Unicode.Length = (USHORT)Basic->NameLength; + + Ansi.MaximumLength = (USHORT)((Basic->NameLength / sizeof (WCHAR)) + sizeof (CHAR)); + Ansi.Buffer = __RegistryAllocate(Ansi.MaximumLength); + + status = STATUS_NO_MEMORY; + if (Ansi.Buffer == NULL) + goto fail6; + + status = RtlUnicodeStringToAnsiString(&Ansi, &Unicode, FALSE); + ASSERT(NT_SUCCESS(status)); + + Ansi.Length = (USHORT)(strlen(Ansi.Buffer) * sizeof (CHAR)); + + status = Callback(Context, Key, Ansi.Buffer); + + __RegistryFree(Ansi.Buffer); + Ansi.Buffer = NULL; + + if (!NT_SUCCESS(status)) + goto fail7; + } + + __RegistryFree(Basic); + + __RegistryFree(Full); + + return STATUS_SUCCESS; + +fail7: +fail6: +fail5: + __RegistryFree(Basic); + +fail4: +fail3: + __RegistryFree(Full); + +fail2: +fail1: + return status; +} + +NTSTATUS +RegistryEnumerateValues( + IN HANDLE Key, + IN NTSTATUS (*Callback)(PVOID, HANDLE, PCHAR), + IN PVOID Context + ) +{ + ULONG Size; + NTSTATUS status; + PKEY_FULL_INFORMATION Full; + PKEY_VALUE_BASIC_INFORMATION Basic; + ULONG Index; + + status = ZwQueryKey(Key, + KeyFullInformation, + NULL, + 0, + &Size); + if (status != STATUS_BUFFER_TOO_SMALL) + goto fail1; + + Full = __RegistryAllocate(Size); + + status = STATUS_NO_MEMORY; + if (Full == NULL) + goto fail2; + + status = ZwQueryKey(Key, + KeyFullInformation, + Full, + Size, + &Size); + if (!NT_SUCCESS(status)) + goto fail3; + + Size = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name) + + Full->MaxValueNameLen; + + Basic = __RegistryAllocate(Size); + status = STATUS_NO_MEMORY; + if (Basic == NULL) + goto fail4; + + for (Index = 0; Index < Full->Values; Index++) { + UNICODE_STRING Unicode; + ANSI_STRING Ansi; + + status = ZwEnumerateValueKey(Key, + Index, + KeyValueBasicInformation, + Basic, + Size, + &Size); + if (!NT_SUCCESS(status)) + goto fail5; + + Unicode.MaximumLength = (USHORT)Basic->NameLength; + Unicode.Buffer = Basic->Name; + Unicode.Length = (USHORT)Basic->NameLength; + + Ansi.MaximumLength = (USHORT)((Basic->NameLength / sizeof (WCHAR)) + sizeof (CHAR)); + Ansi.Buffer = __RegistryAllocate(Ansi.MaximumLength); + + status = RtlUnicodeStringToAnsiString(&Ansi, &Unicode, FALSE); + ASSERT(NT_SUCCESS(status)); + + Ansi.Length = (USHORT)(strlen(Ansi.Buffer) * sizeof (CHAR)); + + status = Callback(Context, Key, Ansi.Buffer); + + __RegistryFree(Ansi.Buffer); + + if (!NT_SUCCESS(status)) + goto fail6; + } + + __RegistryFree(Basic); + + __RegistryFree(Full); + + return STATUS_SUCCESS; + +fail6: +fail5: + __RegistryFree(Basic); + +fail4: +fail3: + __RegistryFree(Full); + +fail2: +fail1: + return status; +} + +NTSTATUS +RegistryDeleteValue( + IN PHANDLE Key, + IN PCHAR Name + ) +{ + ANSI_STRING Ansi; + UNICODE_STRING Unicode; + NTSTATUS status; + + RtlInitAnsiString(&Ansi, Name); + + status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE); + if (!NT_SUCCESS(status)) + goto fail1; + + status = ZwDeleteValueKey(Key, &Unicode); + if (!NT_SUCCESS(status)) + goto fail2; + + RtlFreeUnicodeString(&Unicode); + + return STATUS_SUCCESS; + +fail2: + RtlFreeUnicodeString(&Unicode); + +fail1: + return status; +} + +NTSTATUS +RegistryQueryDwordValue( + IN HANDLE Key, + IN PCHAR Name, + OUT PULONG Value + ) +{ + ANSI_STRING Ansi; + UNICODE_STRING Unicode; + PKEY_VALUE_PARTIAL_INFORMATION Partial; + ULONG Size; + NTSTATUS status; + + RtlInitAnsiString(&Ansi, Name); + + status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE); + if (!NT_SUCCESS(status)) + goto fail1; + + status = ZwQueryValueKey(Key, + &Unicode, + KeyValuePartialInformation, + NULL, + 0, + &Size); + if (status != STATUS_BUFFER_TOO_SMALL) + goto fail2; + + Partial = __RegistryAllocate(Size); + + status = STATUS_NO_MEMORY; + if (Partial == NULL) + goto fail3; + + status = ZwQueryValueKey(Key, + &Unicode, + KeyValuePartialInformation, + Partial, + Size, + &Size); + if (!NT_SUCCESS(status)) + goto fail4; + + status = STATUS_INVALID_PARAMETER; + if (Partial->Type != REG_DWORD || + Partial->DataLength != sizeof (ULONG)) + goto fail5; + + *Value = *(PULONG)Partial->Data; + + __RegistryFree(Partial); + + RtlFreeUnicodeString(&Unicode); + + return STATUS_SUCCESS; + +fail5: +fail4: + __RegistryFree(Partial); + +fail3: +fail2: + RtlFreeUnicodeString(&Unicode); + +fail1: + return status; +} + +NTSTATUS +RegistryUpdateDwordValue( + IN HANDLE Key, + IN PCHAR Name, + IN ULONG Value + ) +{ + ANSI_STRING Ansi; + UNICODE_STRING Unicode; + PKEY_VALUE_PARTIAL_INFORMATION Partial; + NTSTATUS status; + + RtlInitAnsiString(&Ansi, Name); + + status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE); + if (!NT_SUCCESS(status)) + goto fail1; + + Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + + sizeof (ULONG)); + + status = STATUS_NO_MEMORY; + if (Partial == NULL) + goto fail2; + + Partial->TitleIndex = 0; + Partial->Type = REG_DWORD; + Partial->DataLength = sizeof (ULONG); + *(PULONG)Partial->Data = Value; + + status = ZwSetValueKey(Key, + &Unicode, + Partial->TitleIndex, + Partial->Type, + Partial->Data, + Partial->DataLength); + if (!NT_SUCCESS(status)) + goto fail3; + + __RegistryFree(Partial); + + RtlFreeUnicodeString(&Unicode); + + return STATUS_SUCCESS; + +fail3: + __RegistryFree(Partial); + +fail2: + RtlFreeUnicodeString(&Unicode); + +fail1: + + return status; +} + +static PANSI_STRING +RegistrySzToAnsi( + IN PWCHAR Buffer + ) +{ + PANSI_STRING Ansi; + ULONG Length; + UNICODE_STRING Unicode; + NTSTATUS status; + + Ansi = __RegistryAllocate(sizeof (ANSI_STRING) * 2); + + status = STATUS_NO_MEMORY; + if (Ansi == NULL) + goto fail1; + + Length = (ULONG)wcslen(Buffer); + Ansi[0].MaximumLength = (USHORT)(Length + 1) * sizeof (CHAR); + Ansi[0].Buffer = __RegistryAllocate(Ansi[0].MaximumLength); + + status = STATUS_NO_MEMORY; + if (Ansi[0].Buffer == NULL) + goto fail2; + + RtlInitUnicodeString(&Unicode, Buffer); + status = RtlUnicodeStringToAnsiString(&Ansi[0], &Unicode, FALSE); + ASSERT(NT_SUCCESS(status)); + + Ansi[0].Length = (USHORT)Length * sizeof (CHAR); + + return Ansi; + +fail2: + __RegistryFree(Ansi); + +fail1: + return NULL; +} + +static PANSI_STRING +RegistryMultiSzToAnsi( + IN PWCHAR Buffer + ) +{ + PANSI_STRING Ansi; + LONG Index; + LONG Count; + NTSTATUS status; + + Index = 0; + Count = 0; + for (;;) { + ULONG Length; + + Length = (ULONG)wcslen(&Buffer[Index]); + if (Length == 0) + break; + + Index += Length + 1; + Count++; + } + + Ansi = __RegistryAllocate(sizeof (ANSI_STRING) * (Count + 1)); + + status = STATUS_NO_MEMORY; + if (Ansi == NULL) + goto fail1; + + for (Index = 0; Index < Count; Index++) { + ULONG Length; + UNICODE_STRING Unicode; + + Length = (ULONG)wcslen(Buffer); + Ansi[Index].MaximumLength = (USHORT)(Length + 1) * sizeof (CHAR); + Ansi[Index].Buffer = __RegistryAllocate(Ansi[Index].MaximumLength); + + status = STATUS_NO_MEMORY; + if (Ansi[Index].Buffer == NULL) + goto fail2; + + RtlInitUnicodeString(&Unicode, Buffer); + + status = RtlUnicodeStringToAnsiString(&Ansi[Index], &Unicode, FALSE); + ASSERT(NT_SUCCESS(status)); + + Ansi[Index].Length = (USHORT)Length * sizeof (CHAR); + Buffer += Length + 1; + } + + return Ansi; + +fail2: + while (--Index >= 0) + __RegistryFree(Ansi[Index].Buffer); + + __RegistryFree(Ansi); + +fail1: + return NULL; +} + +NTSTATUS +RegistryQuerySzValue( + IN HANDLE Key, + IN PCHAR Name, + OUT PANSI_STRING *Array + ) +{ + ANSI_STRING Ansi; + UNICODE_STRING Unicode; + PKEY_VALUE_PARTIAL_INFORMATION Value; + ULONG Size; + NTSTATUS status; + + RtlInitAnsiString(&Ansi, Name); + + status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE); + if (!NT_SUCCESS(status)) + goto fail1; + + status = ZwQueryValueKey(Key, + &Unicode, + KeyValuePartialInformation, + NULL, + 0, + &Size); + if (status != STATUS_BUFFER_TOO_SMALL) + goto fail2; + + Value = __RegistryAllocate(Size); + + status = STATUS_NO_MEMORY; + if (Value == NULL) + goto fail3; + + status = ZwQueryValueKey(Key, + &Unicode, + KeyValuePartialInformation, + Value, + Size, + &Size); + if (!NT_SUCCESS(status)) + goto fail4; + + switch (Value->Type) { + case REG_SZ: + status = STATUS_NO_MEMORY; + *Array = RegistrySzToAnsi((PWCHAR)Value->Data); + break; + + case REG_MULTI_SZ: + status = STATUS_NO_MEMORY; + *Array = RegistryMultiSzToAnsi((PWCHAR)Value->Data); + break; + + default: + status = STATUS_INVALID_PARAMETER; + *Array = NULL; + break; + } + + if (*Array == NULL) + goto fail5; + + __RegistryFree(Value); + + RtlFreeUnicodeString(&Unicode); + + return STATUS_SUCCESS; + +fail5: +fail4: + __RegistryFree(Value); + +fail3: +fail2: + RtlFreeUnicodeString(&Unicode); + +fail1: + return status; +} + +NTSTATUS +RegistryQueryKeyName( + IN HANDLE Key, + OUT PANSI_STRING *Array + ) +{ + PKEY_NAME_INFORMATION Value; + ULONG Size; + NTSTATUS status; + + status = ZwQueryKey(Key, + KeyNameInformation, + NULL, + 0, + &Size); + if (status != STATUS_BUFFER_TOO_SMALL) + goto fail1; + + // Name information is not intrinsically NULL terminated + Value = __RegistryAllocate(Size + sizeof (WCHAR)); + + status = STATUS_NO_MEMORY; + if (Value == NULL) + goto fail2; + + status = ZwQueryKey(Key, + KeyNameInformation, + Value, + Size, + &Size); + if (!NT_SUCCESS(status)) + goto fail3; + + Value->Name[Value->NameLength / sizeof (WCHAR)] = L'\0'; + *Array = RegistrySzToAnsi((PWCHAR)Value->Name); + + status = STATUS_NO_MEMORY; + if (*Array == NULL) + goto fail4; + + __RegistryFree(Value); + + return STATUS_SUCCESS; + +fail4: +fail3: + __RegistryFree(Value); + +fail2: +fail1: + return status; +} + +NTSTATUS +RegistryQuerySystemStartOption( + IN PCHAR Prefix, + OUT PANSI_STRING *Value + ) +{ + UNICODE_STRING Unicode; + HANDLE Key; + PANSI_STRING Ansi; + ULONG Length; + PCHAR Option; + PCHAR Context; + NTSTATUS status; + + RtlInitUnicodeString(&Unicode, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control"); + + status = RegistryOpenKey(NULL, &Unicode, KEY_READ, &Key); + if (!NT_SUCCESS(status)) + goto fail1; + + status = RegistryQuerySzValue(Key, "SystemStartOptions", &Ansi); + if (!NT_SUCCESS(status)) + goto fail2; + + // SystemStartOptions is a space separated list of options. + // Scan it looking for the one we want. + Length = (ULONG)strlen(Prefix); + + Option = __strtok_r(Ansi[0].Buffer, " ", &Context); + if (strncmp(Prefix, Option, Length) == 0) + goto found; + + while ((Option = __strtok_r(NULL, " ", &Context)) != NULL) + if (strncmp(Prefix, Option, Length) == 0) + goto found; + + status = STATUS_OBJECT_NAME_NOT_FOUND; + goto fail3; + +found: + *Value = __RegistryAllocate(sizeof (ANSI_STRING) * 2); + + status = STATUS_NO_MEMORY; + if (*Value == NULL) + goto fail4; + + Length = (ULONG)strlen(Option); + (*Value)[0].MaximumLength = (USHORT)(Length + 1) * sizeof (CHAR); + (*Value)[0].Buffer = __RegistryAllocate((*Value)[0].MaximumLength); + + status = STATUS_NO_MEMORY; + if ((*Value)[0].Buffer == NULL) + goto fail5; + + RtlCopyMemory((*Value)[0].Buffer, Option, Length * sizeof (CHAR)); + + (*Value)[0].Length = (USHORT)Length * sizeof (CHAR); + + RegistryFreeSzValue(Ansi); + + ZwClose(Key); + + return STATUS_SUCCESS; + +fail5: + __RegistryFree(*Value); + +fail4: +fail3: + RegistryFreeSzValue(Ansi); + +fail2: + ZwClose(Key); + +fail1: + return status; +} + +static PKEY_VALUE_PARTIAL_INFORMATION +RegistryAnsiToSz( + PANSI_STRING Ansi + ) +{ + ULONG Length; + PKEY_VALUE_PARTIAL_INFORMATION Partial; + UNICODE_STRING Unicode; + NTSTATUS status; + + Length = Ansi->Length + 1; + Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + + Length * sizeof (WCHAR)); + + status = STATUS_NO_MEMORY; + if (Partial == NULL) + goto fail1; + + Partial->TitleIndex = 0; + Partial->Type = REG_SZ; + Partial->DataLength = Length * sizeof (WCHAR); + + Unicode.MaximumLength = (UCHAR)Partial->DataLength; + Unicode.Buffer = (PWCHAR)Partial->Data; + Unicode.Length = 0; + + status = RtlAnsiStringToUnicodeString(&Unicode, Ansi, FALSE); + if (!NT_SUCCESS(status)) + goto fail2; + + return Partial; + +fail2: + __RegistryFree(Partial); + +fail1: + return NULL; +} + +static PKEY_VALUE_PARTIAL_INFORMATION +RegistryAnsiToMultiSz( + PANSI_STRING Ansi + ) +{ + ULONG Length; + ULONG Index; + PKEY_VALUE_PARTIAL_INFORMATION Partial; + UNICODE_STRING Unicode; + NTSTATUS status; + + Length = 1; + for (Index = 0; Ansi[Index].Buffer != NULL; Index++) + Length += Ansi[Index].Length + 1; + + Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + + Length * sizeof (WCHAR)); + + status = STATUS_NO_MEMORY; + if (Partial == NULL) + goto fail1; + + Partial->TitleIndex = 0; + Partial->Type = REG_MULTI_SZ; + Partial->DataLength = Length * sizeof (WCHAR); + + Unicode.MaximumLength = (USHORT)Partial->DataLength; + Unicode.Buffer = (PWCHAR)Partial->Data; + Unicode.Length = 0; + + for (Index = 0; Ansi[Index].Buffer != NULL; Index++) { + status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi[Index], FALSE); + if (!NT_SUCCESS(status)) + goto fail2; + + Length = Unicode.Length / sizeof (WCHAR); + + ASSERT3U(Unicode.MaximumLength, >=, (Length + 1) * sizeof (WCHAR)); + Unicode.MaximumLength -= (USHORT)((Length + 1) * sizeof (WCHAR)); + Unicode.Buffer += Length + 1; + Unicode.Length = 0; + } + *Unicode.Buffer = L'\0'; + + return Partial; + +fail2: + __RegistryFree(Partial); + +fail1: + return NULL; +} + +NTSTATUS +RegistryUpdateSzValue( + IN HANDLE Key, + IN PCHAR Name, + IN ULONG Type, + ... + ) +{ + ANSI_STRING Ansi; + UNICODE_STRING Unicode; + va_list Arguments; + PKEY_VALUE_PARTIAL_INFORMATION Partial; + NTSTATUS status; + + RtlInitAnsiString(&Ansi, Name); + + status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE); + if (!NT_SUCCESS(status)) + goto fail1; + + va_start(Arguments, Type); + switch (Type) { + case REG_SZ: { + PANSI_STRING Argument; + + Argument = va_arg(Arguments, PANSI_STRING); + + status = STATUS_NO_MEMORY; + Partial = RegistryAnsiToSz(Argument); + break; + } + case REG_MULTI_SZ: { + PANSI_STRING Argument; + + Argument = va_arg(Arguments, PANSI_STRING); + + status = STATUS_NO_MEMORY; + Partial = RegistryAnsiToMultiSz(Argument); + break; + } + default: + status = STATUS_INVALID_PARAMETER; + Partial = NULL; + break; + } + va_end(Arguments); + + if (Partial == NULL) + goto fail2; + + status = ZwSetValueKey(Key, + &Unicode, + Partial->TitleIndex, + Partial->Type, + Partial->Data, + Partial->DataLength); + if (!NT_SUCCESS(status)) + goto fail3; + + __RegistryFree(Partial); + + RtlFreeUnicodeString(&Unicode); + + return STATUS_SUCCESS; + +fail3: + __RegistryFree(Partial); + +fail2: + RtlFreeUnicodeString(&Unicode); + +fail1: + return status; +} + +VOID +RegistryFreeSzValue( + IN PANSI_STRING Array + ) +{ + ULONG Index; + + if (Array == NULL) + return; + + for (Index = 0; Array[Index].Buffer != NULL; Index++) + __RegistryFree(Array[Index].Buffer); + + __RegistryFree(Array); +} + +VOID +RegistryCloseKey( + IN HANDLE Key + ) +{ + ZwClose(Key); +} diff --git a/src/xeniface/registry.h b/src/xeniface/registry.h new file mode 100644 index 0000000..7a89804 --- /dev/null +++ b/src/xeniface/registry.h @@ -0,0 +1,168 @@ +/* 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 _XENIFACE_REGISTRY_H +#define _XENIFACE_REGISTRY_H + +#include + +extern NTSTATUS +RegistryInitialize( + IN PUNICODE_STRING Path + ); + +extern VOID +RegistryTeardown( + VOID + ); + +extern NTSTATUS +RegistryOpenKey( + IN HANDLE Parent, + IN PUNICODE_STRING Path, + IN ACCESS_MASK DesiredAccess, + OUT PHANDLE Key + ); + +extern NTSTATUS +RegistryOpenServiceKey( + IN ACCESS_MASK DesiredAccess, + OUT PHANDLE Key + ); + +extern NTSTATUS +RegistryOpenSoftwareKey( + IN PDEVICE_OBJECT DeviceObject, + IN ACCESS_MASK DesiredAccess, + OUT PHANDLE Key + ); + +extern NTSTATUS +RegistryOpenHardwareKey( + IN PDEVICE_OBJECT DeviceObject, + IN ACCESS_MASK DesiredAccess, + OUT PHANDLE Key + ); + +extern NTSTATUS +RegistryOpenSubKey( + IN HANDLE Key, + IN PCHAR Name, + IN ACCESS_MASK DesiredAccess, + OUT PHANDLE SubKey + ); + +extern NTSTATUS +RegistryCreateSubKey( + IN HANDLE Key, + IN PCHAR Name, + IN ULONG Options, + OUT PHANDLE SubKey + ); + +extern NTSTATUS +RegistryDeleteSubKey( + IN HANDLE Key, + IN PCHAR Name + ); + +extern NTSTATUS +RegistryEnumerateSubKeys( + IN HANDLE Key, + IN NTSTATUS (*Callback)(PVOID, HANDLE, PCHAR), + IN PVOID Context + ); + +extern NTSTATUS +RegistryEnumerateValues( + IN HANDLE Key, + IN NTSTATUS (*Callback)(PVOID, HANDLE, PCHAR), + IN PVOID Context + ); + +extern NTSTATUS +RegistryDeleteValue( + IN HANDLE Key, + IN PCHAR Name + ); + +extern NTSTATUS +RegistryQueryDwordValue( + IN HANDLE Key, + IN PCHAR Name, + OUT PULONG Value + ); + +extern NTSTATUS +RegistryUpdateDwordValue( + IN HANDLE Key, + IN PCHAR Name, + IN ULONG Value + ); + +extern NTSTATUS +RegistryQuerySzValue( + IN HANDLE Key, + IN PCHAR Name, + OUT PANSI_STRING *Array + ); + +extern NTSTATUS +RegistryQueryKeyName( + IN HANDLE Key, + OUT PANSI_STRING *Array + ); + +extern NTSTATUS +RegistryQuerySystemStartOption( + IN PCHAR Name, + OUT PANSI_STRING *Option + ); + +extern VOID +RegistryFreeSzValue( + IN PANSI_STRING Array + ); + +extern NTSTATUS +RegistryUpdateSzValue( + IN HANDLE Key, + IN PCHAR Name, + IN ULONG Type, + ... + ); + +extern VOID +RegistryCloseKey( + IN HANDLE Key + ); + +#endif // _XENIFACE_REGISTRY_H diff --git a/src/xeniface/wmi.c b/src/xeniface/wmi.c index f0180ec..5d7bce7 100644 --- a/src/xeniface/wmi.c +++ b/src/xeniface/wmi.c @@ -814,7 +814,7 @@ StartWatch(XENIFACE_FDO *fdoData, XenStoreWatch *watch) RtlZeroMemory(tmppath, ansipath.Length+1); RtlCopyBytes(tmppath,ansipath.Buffer, ansipath.Length); - status = STORE(Watch, fdoData->StoreInterface, NULL, tmppath, &watch->watchevent, &watch->watchhandle ); + status = XENBUS_STORE(WatchAdd, &fdoData->StoreInterface, NULL, tmppath, &watch->watchevent, &watch->watchhandle ); if (!NT_SUCCESS(status)) { ExFreePool(tmppath); RtlFreeAnsiString(&ansipath); @@ -871,11 +871,11 @@ VOID WatchCallbackThread(__in PVOID StartContext) { else { if (!session->suspended) { - if (watch->suspendcount !=SUSPEND(Count, watch->fdoData->SuspendInterface)) { - watch->suspendcount = SUSPEND(Count, watch->fdoData->SuspendInterface); + if (watch->suspendcount !=XENBUS_SUSPEND(GetCount, &watch->fdoData->SuspendInterface)) { + watch->suspendcount = XENBUS_SUSPEND(GetCount, &watch->fdoData->SuspendInterface); XenIfaceDebugPrint(WARNING,"SessionSuspendResumeUnwatch %p\n", watch->watchhandle); - STORE(Unwatch, watch->fdoData->StoreInterface, watch->watchhandle); + XENBUS_STORE(WatchRemove, &watch->fdoData->StoreInterface, watch->watchhandle); StartWatch(watch->fdoData, watch); } } @@ -939,7 +939,7 @@ SessionAddWatchLocked(XenStoreSession *session, - (*watch)->suspendcount = SUSPEND(Count, fdoData->SuspendInterface); + (*watch)->suspendcount = XENBUS_SUSPEND(GetCount, &fdoData->SuspendInterface); KeInitializeEvent(&(*watch)->watchevent, NotificationEvent, FALSE); @@ -979,7 +979,7 @@ void SessionRemoveWatchLocked(XenStoreSession *session, XenStoreWatch *watch) { XenIfaceDebugPrint(TRACE, "handle %p\n", watch->watchhandle); if (watch->watchhandle) { - STORE(Unwatch, watch->fdoData->StoreInterface, watch->watchhandle); + XENBUS_STORE(WatchRemove, &watch->fdoData->StoreInterface, watch->watchhandle); watch->watchhandle=NULL; watch->finished = TRUE; XenIfaceDebugPrint(TRACE, "WATCHLIST for session %p-----------\n",session); @@ -1172,7 +1172,7 @@ RemoveSessionLocked(XENIFACE_FDO *fdoData, fdoData->Sessions--; SessionRemoveWatchesLocked(session); if (session->transaction != NULL) { - STORE(TransactionEnd, fdoData->StoreInterface, session->transaction, FALSE); + XENBUS_STORE(TransactionEnd, &fdoData->StoreInterface, session->transaction, FALSE); } session->closing = TRUE; KeSetEvent(&session->SessionChangedEvent, IO_NO_INCREMENT, FALSE); @@ -1215,7 +1215,7 @@ void SessionUnwatchWatchesLocked(XenStoreSession *session) for (i=0; watch != (XenStoreWatch *)&session->watches; i++) { XenIfaceDebugPrint(TRACE,"Suspend unwatch %p\n", watch->watchhandle); - STORE(Unwatch, watch->fdoData->StoreInterface, watch->watchhandle); + XENBUS_STORE(WatchRemove, &watch->fdoData->StoreInterface, watch->watchhandle); watch = (XenStoreWatch *)watch->listentry.Flink; } XenIfaceDebugPrint(TRACE, "WATCHLIST for session %p-----------\n",session); @@ -1236,7 +1236,7 @@ void SuspendSessionLocked(XENIFACE_FDO *fdoData, if (session->transaction != NULL) { XenIfaceDebugPrint(TRACE, "End transaction %p\n",session->transaction); - STORE(TransactionEnd, fdoData->StoreInterface, session->transaction, FALSE); + XENBUS_STORE(TransactionEnd, &fdoData->StoreInterface, session->transaction, FALSE); session->transaction = NULL; } } @@ -1262,7 +1262,7 @@ void SessionRenewWatchesLocked(XenStoreSession *session) { watch = (XenStoreWatch *)session->watches.Flink; for (i=0; watch != (XenStoreWatch *)&session->watches; i++) { if (!watch->finished) { - watch->suspendcount = SUSPEND(Count, watch->fdoData->SuspendInterface); + watch->suspendcount = XENBUS_SUSPEND(GetCount, &watch->fdoData->SuspendInterface); StartWatch(watch->fdoData, watch); } watch = (XenStoreWatch *)watch->listentry.Flink; @@ -1477,7 +1477,7 @@ SessionExecuteRemoveValue(UCHAR *InBuffer, NULL){ goto fail2; } - status = STORE(Remove, fdoData->StoreInterface, session->transaction, NULL, tmpbuffer); + status = XENBUS_STORE(Remove, &fdoData->StoreInterface, session->transaction, NULL, tmpbuffer); UnlockSessions(fdoData); fail2: @@ -1662,7 +1662,7 @@ SessionExecuteSetValue(UCHAR *InBuffer, NULL){ goto fail4; } - status = STORE(Write, fdoData->StoreInterface, session->transaction, NULL, tmppath, tmpvalue); + status = XENBUS_STORE(Printf, &fdoData->StoreInterface, session->transaction, NULL, tmppath, tmpvalue); XenIfaceDebugPrint(TRACE, " Write %s to %s (%p)\n", tmpvalue, tmppath, status); UnlockSessions(fdoData); @@ -1727,7 +1727,7 @@ SessionExecuteGetFirstChild(UCHAR *InBuffer, NULL){ goto fail2; } - status = STORE(Directory,fdoData->StoreInterface, session->transaction, NULL, tmppath, &listresults); + status = XENBUS_STORE(Directory,&fdoData->StoreInterface, session->transaction, NULL, tmppath, &listresults); UnlockSessions(fdoData); if (!NT_SUCCESS(status)) { @@ -1781,7 +1781,7 @@ SessionExecuteGetFirstChild(UCHAR *InBuffer, fail4: fail3: - STORE(Free, fdoData->StoreInterface, listresults); + XENBUS_STORE(Free, &fdoData->StoreInterface, listresults); *byteswritten = RequiredSize; @@ -1874,7 +1874,7 @@ SessionExecuteGetNextSibling(UCHAR *InBuffer, } - status = STORE(Directory,fdoData->StoreInterface, session->transaction, NULL, tmppath, &listresults); + status = XENBUS_STORE(Directory,&fdoData->StoreInterface, session->transaction, NULL, tmppath, &listresults); UnlockSessions(fdoData); if (!NT_SUCCESS(status)) { @@ -1955,7 +1955,7 @@ SessionExecuteGetNextSibling(UCHAR *InBuffer, fail5: fail4: - STORE(Free, fdoData->StoreInterface, listresults); + XENBUS_STORE(Free, &fdoData->StoreInterface, listresults); fail3: ExFreePool(tmpleaf); @@ -2018,7 +2018,7 @@ SessionExecuteGetChildren(UCHAR *InBuffer, NULL){ goto fail2; } - status = STORE(Directory,fdoData->StoreInterface,session->transaction,NULL, tmppath, &listresults); + status = XENBUS_STORE(Directory,&fdoData->StoreInterface,session->transaction,NULL, tmppath, &listresults); UnlockSessions(fdoData); if (!NT_SUCCESS(status)) { @@ -2079,7 +2079,7 @@ SessionExecuteGetChildren(UCHAR *InBuffer, fail4: fail3: - STORE(Free, fdoData->StoreInterface, listresults); + XENBUS_STORE(Free, &fdoData->StoreInterface, listresults); fail2: ExFreePool(tmppath); @@ -2149,7 +2149,7 @@ SessionExecuteStartTransaction(UCHAR *InBuffer, goto failtransactionactive; } - STORE(TransactionStart, fdoData->StoreInterface, &session->transaction); + XENBUS_STORE(TransactionStart, &fdoData->StoreInterface, &session->transaction); failtransactionactive: @@ -2188,7 +2188,7 @@ SessionExecuteCommitTransaction(UCHAR *InBuffer, goto failtransactionnotactive; } - status = STORE(TransactionEnd,fdoData->StoreInterface, session->transaction, TRUE); + status = XENBUS_STORE(TransactionEnd,&fdoData->StoreInterface, session->transaction, TRUE); session->transaction = NULL; @@ -2228,7 +2228,7 @@ SessionExecuteAbortTransaction(UCHAR *InBuffer, goto failtransactionnotactive; } - status = STORE(TransactionEnd, fdoData->StoreInterface, session->transaction, FALSE); + status = XENBUS_STORE(TransactionEnd, &fdoData->StoreInterface, session->transaction, FALSE); session->transaction = NULL; @@ -2287,7 +2287,7 @@ SessionExecuteGetValue(UCHAR *InBuffer, NULL){ goto fail2; } - status = STORE(Read, fdoData->StoreInterface, session->transaction, NULL, tmppath, &value); + status = XENBUS_STORE(Read, &fdoData->StoreInterface, session->transaction, NULL, tmppath, &value); UnlockSessions(fdoData); if (!NT_SUCCESS(status)) @@ -2303,7 +2303,7 @@ SessionExecuteGetValue(UCHAR *InBuffer, WriteCountedUTF8String(value, valuepos); fail3: - STORE(Free, fdoData->StoreInterface, value); + XENBUS_STORE(Free, &fdoData->StoreInterface, value); *byteswritten = RequiredSize; fail2: @@ -2714,7 +2714,7 @@ GenerateBaseBlock( XENIFACE_FDO *fdoData, WNODE_FLAG_FIXED_INSTANCE_SIZE | WNODE_FLAG_PDO_INSTANCE_NAMES; if (fdoData->InterfacesAcquired) { - *time = SHARED_INFO(GetTime, fdoData->SharedInfoInterface).QuadPart; + *time = XENBUS_SHARED_INFO(GetTime, &fdoData->SharedInfoInterface).QuadPart; } else { *time = 0; @@ -2758,7 +2758,7 @@ GenerateBaseInstance( return STATUS_WMI_ITEMID_NOT_FOUND; } if (fdoData->InterfacesAcquired) { - *time = SHARED_INFO(GetTime, fdoData->SharedInfoInterface).QuadPart; + *time = XENBUS_SHARED_INFO(GetTime, &fdoData->SharedInfoInterface).QuadPart; } else { *time = 0;