# Cscope/Tags
-cscope.files
-cscope.out
-tags
+/cscope.files
+/cscope.out
+/tags
# Output
-xeniface
+/xeniface
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
-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
=================
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
=============
#!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
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')
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:
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]),
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])):
file.close()
return expired
+
+
def get_configuration(release, debug):
configuration = release
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):
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)
cwd = os.getcwd()
- msbuild(platform, configuration, 'Build', name+'.sln', '', 'proj')
+ msbuild(platform, configuration, 'Build', name + '.sln', '', 'proj')
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))
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')
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')
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']
os.environ['MICRO_VERSION'],
os.environ['BUILD_NUMBER']])
- os.chdir(target_path)
command=['"' + symstore + '"']
command.append('add')
command.append('/s')
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]
return output.decode('utf-8')
+
def archive(filename, files, tgz=False):
access='w'
if tgz:
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'
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'])
/* 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.
* 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
* 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
/* 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.
* 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
* 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
/* 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.
* 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
* 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
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
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Windows 8 Debug|Win32">
+ <Configuration>Windows 8 Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows 7 Debug|Win32">
+ <Configuration>Windows 7 Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Vista Debug|Win32">
+ <Configuration>Windows Vista Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows 8 Release|Win32">
+ <Configuration>Windows 8 Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows 7 Release|Win32">
+ <Configuration>Windows 7 Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Vista Release|Win32">
+ <Configuration>Windows Vista Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows 8 Debug|x64">
+ <Configuration>Windows8 Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows 7 Debug|x64">
+ <Configuration>Windows 7 Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Vista Debug|x64">
+ <Configuration>Windows Vista Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows 8 Release|x64">
+ <Configuration>Windows 8 Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows 7 Release|x64">
+ <Configuration>Windows 7 Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Vista Release|x64">
+ <Configuration>Windows Vista Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+</Project>
\ No newline at end of file
-<?xml version="1.0" encoding="utf-8"?>\r
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
- <ItemGroup Label="ProjectConfigurations">\r
- <ProjectConfiguration Include="Windows Developer Preview Debug|Win32">\r
- <Configuration>Windows Developer Preview Debug</Configuration>\r
- <Platform>Win32</Platform>\r
- </ProjectConfiguration>\r
- <ProjectConfiguration Include="Windows Developer Preview Release|Win32">\r
- <Configuration>Windows Developer Preview Release</Configuration>\r
- <Platform>Win32</Platform>\r
- </ProjectConfiguration>\r
- <ProjectConfiguration Include="Windows 7 Debug|Win32">\r
- <Configuration>Windows 7 Debug</Configuration>\r
- <Platform>Win32</Platform>\r
- </ProjectConfiguration>\r
- <ProjectConfiguration Include="Windows 7 Release|Win32">\r
- <Configuration>Windows 7 Release</Configuration>\r
- <Platform>Win32</Platform>\r
- </ProjectConfiguration>\r
- <ProjectConfiguration Include="Windows Vista Debug|Win32">\r
- <Configuration>Windows Vista Debug</Configuration>\r
- <Platform>Win32</Platform>\r
- </ProjectConfiguration>\r
- <ProjectConfiguration Include="Windows Vista Release|Win32">\r
- <Configuration>Windows Vista Release</Configuration>\r
- <Platform>Win32</Platform>\r
- </ProjectConfiguration>\r
- <ProjectConfiguration Include="Windows Developer Preview Debug|x64">\r
- <Configuration>Windows Developer Preview Debug</Configuration>\r
- <Platform>x64</Platform>\r
- </ProjectConfiguration>\r
- <ProjectConfiguration Include="Windows Developer Preview Release|x64">\r
- <Configuration>Windows Developer Preview Release</Configuration>\r
- <Platform>x64</Platform>\r
- </ProjectConfiguration>\r
- <ProjectConfiguration Include="Windows 7 Debug|x64">\r
- <Configuration>Windows 7 Debug</Configuration>\r
- <Platform>x64</Platform>\r
- </ProjectConfiguration>\r
- <ProjectConfiguration Include="Windows 7 Release|x64">\r
- <Configuration>Windows 7 Release</Configuration>\r
- <Platform>x64</Platform>\r
- </ProjectConfiguration>\r
- <ProjectConfiguration Include="Windows Vista Debug|x64">\r
- <Configuration>Windows Vista Debug</Configuration>\r
- <Platform>x64</Platform>\r
- </ProjectConfiguration>\r
- <ProjectConfiguration Include="Windows Vista Release|x64">\r
- <Configuration>Windows Vista Release</Configuration>\r
- <Platform>x64</Platform>\r
- </ProjectConfiguration>\r
- </ItemGroup>\r
- <PropertyGroup Label="Globals">\r
- <ProjectGuid>{9B071A35-897C-477A-AEB7-95F77618A21D}</ProjectGuid>\r
- <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>\r
- <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>\r
- </PropertyGroup>\r
- <PropertyGroup Label="PropertySheets">\r
- <PlatformToolset>WindowsKernelModeDriver8.0</PlatformToolset>\r
- <ConfigurationType>Utility</ConfigurationType>\r
- <DriverType>Package</DriverType>\r
- <Configuration>Windows Developer Preview Debug</Configuration>\r
- <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>\r
- </PropertyGroup>\r
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Developer Preview Debug|Win32'" Label="Configuration">\r
- <TargetVersion>Windows8</TargetVersion>\r
- <UseDebugLibraries>true</UseDebugLibraries>\r
- </PropertyGroup>\r
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Developer Preview Release|Win32'" Label="Configuration">\r
- <TargetVersion>Windows8</TargetVersion>\r
- <UseDebugLibraries>false</UseDebugLibraries>\r
- </PropertyGroup>\r
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows 7 Debug|Win32'" Label="Configuration">\r
- <TargetVersion>Windows7</TargetVersion>\r
- <UseDebugLibraries>true</UseDebugLibraries>\r
- </PropertyGroup>\r
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows 7 Release|Win32'" Label="Configuration">\r
- <TargetVersion>Windows7</TargetVersion>\r
- <UseDebugLibraries>false</UseDebugLibraries>\r
- </PropertyGroup>\r
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Vista Debug|Win32'" Label="Configuration">\r
- <TargetVersion>Vista</TargetVersion>\r
- <UseDebugLibraries>true</UseDebugLibraries>\r
- </PropertyGroup>\r
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Vista Release|Win32'" Label="Configuration">\r
- <TargetVersion>Vista</TargetVersion>\r
- <UseDebugLibraries>false</UseDebugLibraries>\r
- </PropertyGroup>\r
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Developer Preview Debug|x64'" Label="Configuration">\r
- <TargetVersion>Windows8</TargetVersion>\r
- <UseDebugLibraries>true</UseDebugLibraries>\r
- </PropertyGroup>\r
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Developer Preview Release|x64'" Label="Configuration">\r
- <TargetVersion>Windows8</TargetVersion>\r
- <UseDebugLibraries>false</UseDebugLibraries>\r
- </PropertyGroup>\r
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows 7 Debug|x64'" Label="Configuration">\r
- <TargetVersion>Windows7</TargetVersion>\r
- <UseDebugLibraries>true</UseDebugLibraries>\r
- </PropertyGroup>\r
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows 7 Release|x64'" Label="Configuration">\r
- <TargetVersion>Windows7</TargetVersion>\r
- <UseDebugLibraries>false</UseDebugLibraries>\r
- </PropertyGroup>\r
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Vista Debug|x64'" Label="Configuration">\r
- <TargetVersion>Vista</TargetVersion>\r
- <UseDebugLibraries>true</UseDebugLibraries>\r
- </PropertyGroup>\r
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Vista Release|x64'" Label="Configuration">\r
- <TargetVersion>Vista</TargetVersion>\r
- <UseDebugLibraries>false</UseDebugLibraries>\r
- </PropertyGroup>\r
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
- <ImportGroup Label="ExtensionSettings">\r
- </ImportGroup>\r
- <ImportGroup Label="PropertySheets">\r
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
- </ImportGroup>\r
- <PropertyGroup Label="UserMacros" />\r
- <PropertyGroup>\r
- <EnableInf2cat>true</EnableInf2cat>\r
- <Inf2CatWindowsVersionList Condition="'$(Platform)'=='x64'">Vista_x64;7_x64;Server2008_x64;Server2008R2_x64;Server8_x64</Inf2CatWindowsVersionList>\r
- <Inf2CatWindowsVersionList Condition="'$(Platform)'=='Win32'">Vista_x86;7_x86;Server2008_x86;8_x86</Inf2CatWindowsVersionList>\r
- </PropertyGroup>\r
- <PropertyGroup>\r
- <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>\r
- <EnableDeployment>False</EnableDeployment>\r
- <ImportToStore>False</ImportToStore>\r
- <InstallMode>None</InstallMode>\r
- <HardwareIdString />\r
- <CommandLine />\r
- <ScriptPath />\r
- <DeployFiles />\r
- <ScriptName />\r
- <ScriptDeviceQuery>%PathToInf%</ScriptDeviceQuery>\r
- <EnableVerifier>False</EnableVerifier>\r
- <AllDrivers>False</AllDrivers>\r
- <VerifyProjectOutput>True</VerifyProjectOutput>\r
- <VerifyDrivers />\r
- <VerifyFlags>133563</VerifyFlags>\r
- <PackageDir>..\..\xeniface\$(DDKPlatform)</PackageDir>\r
- </PropertyGroup>\r
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Windows Vista Debug|Win32'">\r
- <CustomBuild>\r
- <AdditionalInputs>\r
- </AdditionalInputs>\r
- </CustomBuild>\r
- </ItemDefinitionGroup>\r
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Windows Vista Release|Win32'">\r
- <CustomBuild>\r
- <AdditionalInputs>\r
- </AdditionalInputs>\r
- </CustomBuild>\r
- </ItemDefinitionGroup>\r
- <ItemGroup>\r
- <ProjectReference Include="..\xeniface\xeniface.vcxproj">\r
- <Project>{22166290-65D8-49D2-BB88-33201797C7D8}</Project>\r
- </ProjectReference>\r
- </ItemGroup>\r
- <ItemGroup>\r
- <FilesToPackage Include="$(KIT)\Redist\DIFx\dpinst\EngMui\x86\dpinst.exe" Condition="'$(Platform)'=='Win32'" />\r
- <FilesToPackage Include="$(KIT)\Redist\DIFx\dpinst\EngMui\x64\dpinst.exe" Condition="'$(Platform)'=='x64'" />\r
- </ItemGroup>\r
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
- <ImportGroup Label="ExtensionTargets">\r
- </ImportGroup>\r
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="..\configs.props" />
+
+ <PropertyGroup Label="PropertySheets">
+ <PlatformToolset>WindowsKernelModeDriver8.0</PlatformToolset>
+ <ConfigurationType>Utility</ConfigurationType>
+ <DriverType>Package</DriverType>
+ <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
+ </PropertyGroup>
+ <PropertyGroup Label="Globals">
+ <Configuration>Windows Vista Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ </PropertyGroup>
+
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{9B071A35-897C-477A-AEB7-95F77618A21D}</ProjectGuid>
+ </PropertyGroup>
+
+ <Import Project="..\targets.props" />
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+
+ <PropertyGroup>
+ <EnableInf2cat>true</EnableInf2cat>
+ <Inf2CatWindowsVersionList Condition="'$(Platform)'=='x64'">Vista_x64;7_x64;Server2008_x64;Server2008R2_x64;Server8_x64</Inf2CatWindowsVersionList>
+ <Inf2CatWindowsVersionList Condition="'$(Platform)'=='Win32'">Vista_x86;7_x86;Server2008_x86;8_x86</Inf2CatWindowsVersionList>
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ <EnableDeployment>False</EnableDeployment>
+ <ImportToStore>False</ImportToStore>
+ <InstallMode>None</InstallMode>
+ <ScriptDeviceQuery>%PathToInf%</ScriptDeviceQuery>
+ <EnableVerifier>False</EnableVerifier>
+ <AllDrivers>False</AllDrivers>
+ <VerifyProjectOutput>True</VerifyProjectOutput>
+ <VerifyFlags>133563</VerifyFlags>
+ <IntDir>..\$(ProjectName)\$(ConfigurationName)\$(Platform)\</IntDir>
+ <OutDir>..\$(ConfigurationName)\$(Platform)\</OutDir>
+ <PackageDir>..\..\xeniface\$(DDKPlatform)</PackageDir>
+ </PropertyGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\xeniface\xeniface.vcxproj">
+ <Project>{22166290-65D8-49D2-BB88-33201797C7D8}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <FilesToPackage Include="$(KIT)\Redist\DIFx\dpinst\EngMui\x86\dpinst.exe" Condition="'$(Platform)'=='Win32'" />
+ <FilesToPackage Include="$(KIT)\Redist\DIFx\dpinst\EngMui\x64\dpinst.exe" Condition="'$(Platform)'=='x64'" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
</Project>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 8 Debug|Win32'">
+ <TargetVersion>Windows8</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 8 Release|Win32'">
+ <TargetVersion>Windows8</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 8 Debug|x64'">
+ <TargetVersion>Windows8</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 8 Release|x64'">
+ <TargetVersion>Windows8</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 7 Debug|Win32'">
+ <TargetVersion>Windows7</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 7 Release|Win32'">
+ <TargetVersion>Windows7</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 7 Debug|x64'">
+ <TargetVersion>Windows7</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 7 Release|x64'">
+ <TargetVersion>Windows7</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows Vista Debug|Win32'">
+ <TargetVersion>Vista</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows Vista Release|Win32'">
+ <TargetVersion>Vista</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows Vista Debug|x64'">
+ <TargetVersion>Vista</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows Vista Release|x64'">
+ <TargetVersion>Vista</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+</Project>
# 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
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Windows Developer Preview Debug|Win32">
- <Configuration>Windows Developer Preview Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Windows Developer Preview Release|Win32">
- <Configuration>Windows Developer Preview Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Windows 8 Debug|Win32">
- <Configuration>Windows 8 Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Windows 8 Release|Win32">
- <Configuration>Windows 8 Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Windows 7 Debug|Win32">
- <Configuration>Windows 7 Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Windows 7 Release|Win32">
- <Configuration>Windows 7 Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Windows Vista Debug|Win32">
- <Configuration>Windows Vista Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Windows Vista Release|Win32">
- <Configuration>Windows Vista Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Windows Developer Preview Debug|x64">
- <Configuration>Windows Developer Preview Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Windows Developer Preview Release|x64">
- <Configuration>Windows Developer Preview Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Windows 8 Debug|x64">
- <Configuration>Windows 8 Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Windows 8 Release|x64">
- <Configuration>Windows 8 Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Windows 7 Debug|x64">
- <Configuration>Windows 7 Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Windows 7 Release|x64">
- <Configuration>Windows 7 Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Windows Vista Debug|x64">
- <Configuration>Windows Vista Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Windows Vista Release|x64">
- <Configuration>Windows Vista Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <ProjectGuid>{22166290-65D8-49D2-BB88-33201797C7D8}</ProjectGuid>
- <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
- <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
- <ProjectName>xeniface</ProjectName>
- </PropertyGroup>
- <PropertyGroup Label="PropertySheets">
- <PlatformToolset>WindowsKernelModeDriver8.0</PlatformToolset>
- <ConfigurationType>Driver</ConfigurationType>
- <DriverType>WDM</DriverType>
- <Configuration>Windows Developer Preview Debug</Configuration>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Developer Preview Debug|Win32'" Label="Configuration">
- <TargetVersion>Windows8</TargetVersion>
- <UseDebugLibraries>true</UseDebugLibraries>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Developer Preview Release|Win32'" Label="Configuration">
- <TargetVersion>Windows8</TargetVersion>
- <UseDebugLibraries>false</UseDebugLibraries>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows 7 Debug|Win32'" Label="Configuration">
- <TargetVersion>Windows7</TargetVersion>
- <UseDebugLibraries>true</UseDebugLibraries>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows 7 Release|Win32'" Label="Configuration">
- <TargetVersion>Windows7</TargetVersion>
- <UseDebugLibraries>false</UseDebugLibraries>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Vista Debug|Win32'" Label="Configuration">
- <TargetVersion>Vista</TargetVersion>
- <UseDebugLibraries>true</UseDebugLibraries>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Vista Release|Win32'" Label="Configuration">
- <TargetVersion>Vista</TargetVersion>
- <UseDebugLibraries>false</UseDebugLibraries>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Developer Preview Debug|x64'" Label="Configuration">
- <TargetVersion>Windows8</TargetVersion>
- <UseDebugLibraries>true</UseDebugLibraries>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Developer Preview Release|x64'" Label="Configuration">
- <TargetVersion>Windows8</TargetVersion>
- <UseDebugLibraries>false</UseDebugLibraries>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows 7 Debug|x64'" Label="Configuration">
- <TargetVersion>Windows7</TargetVersion>
- <UseDebugLibraries>true</UseDebugLibraries>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows 7 Release|x64'" Label="Configuration">
- <TargetVersion>Windows7</TargetVersion>
- <UseDebugLibraries>false</UseDebugLibraries>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Vista Debug|x64'" Label="Configuration">
- <TargetVersion>Vista</TargetVersion>
- <UseDebugLibraries>true</UseDebugLibraries>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Vista Release|x64'" Label="Configuration">
- <TargetVersion>Vista</TargetVersion>
- <UseDebugLibraries>false</UseDebugLibraries>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup>
- <IncludePath>..\..\include;$(IncludePath)</IncludePath>
- <RunCodeAnalysis>true</RunCodeAnalysis>
- <EnableInf2cat>false</EnableInf2cat>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
- <ClCompile>
- <AdditionalIncludeDirectories>$(SolutionDir)..\include;$(SolutionDir)\liteagent;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>__i386__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <EnablePREfast>true</EnablePREfast>
- </ClCompile>
- <Link>
- <AdditionalDependencies>$(DDK_LIB_PATH)\ntstrsafe.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
- </Link>
- <ResourceCompile>
- <AdditionalIncludeDirectories>$(SolutionDir)..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Inf>
- <SpecifyArchitecture>true</SpecifyArchitecture>
- <Architecture>x86</Architecture>
- <SpecifyDriverVerDirectiveVersion>true</SpecifyDriverVerDirectiveVersion>
- <TimeStamp>$(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION).$(BUILD_NUMBER)</TimeStamp>
- <EnableVerbose>true</EnableVerbose>
- </Inf>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Platform)'=='x64'">
- <ClCompile>
- <AdditionalIncludeDirectories>$(SolutionDir)..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>__x86_64__;__MODULE__="XENIFACE";%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <EnablePREfast>true</EnablePREfast>
- </ClCompile>
- <Link>
- <AdditionalDependencies>$(DDK_LIB_PATH)\ntstrsafe.lib;%(AdditionalDependencies)</AdditionalDependencies>
- </Link>
- <ResourceCompile>
- <AdditionalIncludeDirectories>$(SolutionDir)..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Inf>
- <SpecifyArchitecture>true</SpecifyArchitecture>
- <Architecture>amd64</Architecture>
- <SpecifyDriverVerDirectiveVersion>true</SpecifyDriverVerDirectiveVersion>
- <TimeStamp>$(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION).$(BUILD_NUMBER)</TimeStamp>
- <EnableVerbose>true</EnableVerbose>
- </Inf>
- </ItemDefinitionGroup>
- <ItemGroup>
- <FilesToPackage Include="$(TargetPath)" />
- <FilesToPackage Include="$(OutDir)$(TargetName).pdb" />
- <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
- </ItemGroup>
- <ItemGroup>
- <ClCompile Include="../../src/xeniface/ioctls.c" />
- <ClCompile Include="../../src/xeniface/wmi.c" />
- <ClCompile Include="..\..\src\xeniface\driver.c" />
- <ClCompile Include="..\..\src\xeniface\fdo.c" />
- <ClCompile Include="..\..\src\xeniface\thread.c" />
- </ItemGroup>
- <ItemGroup>
- <Mofcomp Include="../../src/xeniface/wmi.mof">
- <CreateBinaryMofFile>$(IntDir)/wmi.bmf</CreateBinaryMofFile>
- </Mofcomp>
- </ItemGroup>
- <ItemGroup>
- <Wmimofck Include="$(IntDir)\wmi.bmf">
- <HeaderOutputFile>..\..\src\xeniface\wmi_generated.h</HeaderOutputFile>
- </Wmimofck>
- </ItemGroup>
- <ItemGroup>
- <ResourceCompile Include="..\..\src\xeniface\xeniface.rc" />
- </ItemGroup>
- <ItemGroup>
- <Inf Include="..\..\src\xeniface.inf" />
- </ItemGroup>
- <ItemGroup>
- <None Include="..\package\package.vcxproj" />
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="..\..\include\util.h" />
- <ClInclude Include="..\..\src\xeniface\assert.h" />
- <ClInclude Include="..\..\src\xeniface\driver.h" />
- <ClInclude Include="..\..\src\xeniface\fdo.h" />
- <ClInclude Include="..\..\src\xeniface\ioctls.h" />
- <ClInclude Include="..\..\src\xeniface\log.h" />
- <ClInclude Include="..\..\src\xeniface\mutex.h" />
- <ClInclude Include="..\..\src\xeniface\names.h" />
- <ClInclude Include="..\..\src\xeniface\thread.h" />
- <ClInclude Include="..\..\src\xeniface\types.h" />
- <ClInclude Include="..\..\src\xeniface\wmi.h" />
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
-</Project>
+ <Import Project="..\configs.props" />
+
+ <PropertyGroup Label="PropertySheets">
+ <PlatformToolset>WindowsKernelModeDriver8.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ <DriverType>WDM</DriverType>
+ </PropertyGroup>
+ <PropertyGroup Label="Globals">
+ <Configuration>Windows Vista Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ </PropertyGroup>
+
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{22166290-65D8-49D2-BB88-33201797C7D8}</ProjectGuid>
+ </PropertyGroup>
+
+ <Import Project="..\targets.props" />
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+
+ <PropertyGroup>
+ <IncludePath>..\..\include;$(IncludePath)</IncludePath>
+ <RunCodeAnalysis>true</RunCodeAnalysis>
+ <EnableInf2cat>false</EnableInf2cat>
+ <IntDir>..\$(ProjectName)\$(ConfigurationName)\$(Platform)\</IntDir>
+ <OutDir>..\$(ConfigurationName)\$(Platform)\</OutDir>
+ </PropertyGroup>
+
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <PreprocessorDefinitions>__MODULE__="XENIFACE";POOL_NX_OPTIN=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>4711;4548;4820;4668;4255;6001;6054;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <EnablePREfast>true</EnablePREfast>
+ </ClCompile>
+ <Link>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <AdditionalDependencies>$(DDK_LIB_PATH)\ntstrsafe.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <EnableCOMDATFolding>false</EnableCOMDATFolding>
+ </Link>
+ <Inf>
+ <SpecifyArchitecture>true</SpecifyArchitecture>
+ <SpecifyDriverVerDirectiveVersion>true</SpecifyDriverVerDirectiveVersion>
+ <TimeStamp>$(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION).$(BUILD_NUMBER)</TimeStamp>
+ <EnableVerbose>true</EnableVerbose>
+ </Inf>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>__i386__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Inf>
+ <Architecture>x86</Architecture>
+ </Inf>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Platform)'=='x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>__x86_64__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Inf>
+ <Architecture>amd64</Architecture>
+ </Inf>
+ </ItemDefinitionGroup>
+
+ <ItemGroup>
+ <FilesToPackage Include="$(TargetPath)" />
+ <FilesToPackage Include="$(OutDir)$(TargetName).pdb" />
+ <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="../../src/xeniface/ioctls.c" />
+ <ClCompile Include="../../src/xeniface/wmi.c" />
+ <ClCompile Include="../../src/xeniface/driver.c" />
+ <ClCompile Include="../../src/xeniface/fdo.c" />
+ <ClCompile Include="../../src/xeniface/registry.c" />
+ <ClCompile Include="../../src\xeniface/thread.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <Mofcomp Include="../../src/xeniface/wmi.mof">
+ <CreateBinaryMofFile>$(IntDir)/wmi.bmf</CreateBinaryMofFile>
+ </Mofcomp>
+ </ItemGroup>
+ <ItemGroup>
+ <Wmimofck Include="$(IntDir)\wmi.bmf">
+ <HeaderOutputFile>..\..\src\xeniface\wmi_generated.h</HeaderOutputFile>
+ </Wmimofck>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="..\..\src\xeniface\xeniface.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Include="..\xeniface.inf" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
\ No newline at end of file
-<?xml version="1.0" encoding="utf-8"?>\r
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
- <PropertyGroup>\r
- <SignMode>TestSign</SignMode>\r
- <TestCertificate>..\xeniface.pfx</TestCertificate>\r
- <TimeStampServer>http://timestamp.verisign.com/scripts/timstamp.dll</TimeStampServer>\r
- </PropertyGroup>\r
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <SignMode>TestSign</SignMode>
+ <TestCertificate>..\xeniface.pfx</TestCertificate>
+ <TimeStampServer>http://timestamp.verisign.com/scripts/timstamp.dll</TimeStampServer>
+ </PropertyGroup>
</Project>
\ No newline at end of file
#include "driver.h"
+#include "registry.h"
#include "fdo.h"
#include "thread.h"
#include "mutex.h"
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;
ZwClose(RegHandle);
RtlFreeUnicodeString(&UnicodeValue);
- STORE(Free, Fdo->StoreInterface, value);
+ XENBUS_STORE(Free, &Fdo->StoreInterface, value);
return;
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;
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))
}
}
-
-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,
Trace("<====\n");
return STATUS_SUCCESS;
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return status;
}
static FORCEINLINE VOID
__FdoSetDevicePowerState(Fdo, PowerDeviceD3);
- STORE(Release, Fdo->StoreInterface);
+ XENBUS_STORE(Release, &Fdo->StoreInterface);
Trace("<====\n");
}
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);
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);
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,
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;
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
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);
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");
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);
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;
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;
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:
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;
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;
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:
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;
ULONG OutLen = Stack->Parameters.DeviceIoControl.OutputBufferLength;
status = STATUS_DEVICE_NOT_READY;
- if (Fdo->StoreInterface == NULL)
- goto done;
-
if (Fdo->InterfacesAcquired == FALSE)
goto done;
--- /dev/null
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <ntddk.h>
+#include <util.h>
+
+#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);
+}
--- /dev/null
+/* 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 <ntddk.h>
+
+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
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);
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);
}
}
- (*watch)->suspendcount = SUSPEND(Count, fdoData->SuspendInterface);
+ (*watch)->suspendcount = XENBUS_SUSPEND(GetCount, &fdoData->SuspendInterface);
KeInitializeEvent(&(*watch)->watchevent, NotificationEvent, FALSE);
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);
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);
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);
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;
}
}
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;
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:
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);
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)) {
fail4:
fail3:
- STORE(Free, fdoData->StoreInterface, listresults);
+ XENBUS_STORE(Free, &fdoData->StoreInterface, listresults);
*byteswritten = RequiredSize;
}
- 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)) {
fail5:
fail4:
- STORE(Free, fdoData->StoreInterface, listresults);
+ XENBUS_STORE(Free, &fdoData->StoreInterface, listresults);
fail3:
ExFreePool(tmpleaf);
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)) {
fail4:
fail3:
- STORE(Free, fdoData->StoreInterface, listresults);
+ XENBUS_STORE(Free, &fdoData->StoreInterface, listresults);
fail2:
ExFreePool(tmppath);
goto failtransactionactive;
}
- STORE(TransactionStart, fdoData->StoreInterface, &session->transaction);
+ XENBUS_STORE(TransactionStart, &fdoData->StoreInterface, &session->transaction);
failtransactionactive:
goto failtransactionnotactive;
}
- status = STORE(TransactionEnd,fdoData->StoreInterface, session->transaction, TRUE);
+ status = XENBUS_STORE(TransactionEnd,&fdoData->StoreInterface, session->transaction, TRUE);
session->transaction = NULL;
goto failtransactionnotactive;
}
- status = STORE(TransactionEnd, fdoData->StoreInterface, session->transaction, FALSE);
+ status = XENBUS_STORE(TransactionEnd, &fdoData->StoreInterface, session->transaction, FALSE);
session->transaction = NULL;
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))
WriteCountedUTF8String(value, valuepos);
fail3:
- STORE(Free, fdoData->StoreInterface, value);
+ XENBUS_STORE(Free, &fdoData->StoreInterface, value);
*byteswritten = RequiredSize;
fail2:
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;
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;