]> xenbits.xensource.com Git - people/pauldu/xenbus.git/commitdiff
Re-factoring for use with upstream Xen.
authorPaul Durrant <paul.durrant@citrix.com>
Thu, 22 Aug 2013 14:23:14 +0000 (15:23 +0100)
committerPaul Durrant <paul.durrant@citrix.com>
Fri, 23 Aug 2013 16:11:12 +0000 (17:11 +0100)
Strip out XenServer specific parts of the drivers and enable them
to cope with multiple bindings.
Also, refine some of the source, add a common source area to reduce
code duplication, and change the PDO names to reflect the PV driver
vendor and also use a format that should work with Windows Update.

Note that XENFILT is pretty useless at this point. It binds to devices
correctly but all the unplug code is gone, to be replaced with code that
is not reliant upon XenServer-specific patches to QEMU.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
78 files changed:
build.py
include/emulated_interface.h [deleted file]
include/get_xen_headers.sh [deleted file]
include/util.h [deleted file]
include/xen.h
proj/xen/xen.vcxproj
proj/xenbus/xenbus.vcxproj
proj/xenfilt/xenfilt.vcxproj
src/coinst/coinst.c
src/common/assert.h [new file with mode: 0644]
src/common/dbg_print.h [new file with mode: 0644]
src/common/high.h [new file with mode: 0644]
src/common/mutex.h [new file with mode: 0644]
src/common/names.h [new file with mode: 0644]
src/common/registry.c [new file with mode: 0644]
src/common/registry.h [new file with mode: 0644]
src/common/util.h [new file with mode: 0644]
src/xen/assert.h [deleted file]
src/xen/bug_check.c [new file with mode: 0644]
src/xen/bug_check.h [new file with mode: 0644]
src/xen/debug.c [deleted file]
src/xen/debug.h [deleted file]
src/xen/driver.c
src/xen/dump.c [deleted file]
src/xen/dump.h [deleted file]
src/xen/event_channel.c
src/xen/grant_table.c
src/xen/high.h [deleted file]
src/xen/hvm.c
src/xen/hypercall.c
src/xen/log.c
src/xen/log.h
src/xen/memory.c
src/xen/module.c
src/xen/process.c
src/xen/sched.c
src/xen/system.c
src/xen/unplug.c [deleted file]
src/xen/unplug.h [deleted file]
src/xenbus.inf
src/xenbus/assert.h [deleted file]
src/xenbus/balloon.c
src/xenbus/bus.c
src/xenbus/debug.c
src/xenbus/dma.c
src/xenbus/driver.c
src/xenbus/driver.h
src/xenbus/evtchn.c
src/xenbus/fdo.c
src/xenbus/fdo.h
src/xenbus/gnttab.c
src/xenbus/high.h [deleted file]
src/xenbus/log.h [deleted file]
src/xenbus/mutex.h [deleted file]
src/xenbus/names.h [deleted file]
src/xenbus/pdo.c
src/xenbus/range_set.c
src/xenbus/registry.c [deleted file]
src/xenbus/registry.h [deleted file]
src/xenbus/shared_info.c
src/xenbus/store.c
src/xenbus/suspend.c
src/xenbus/sync.c
src/xenbus/thread.c
src/xenfilt/assert.h [deleted file]
src/xenfilt/driver.c
src/xenfilt/driver.h
src/xenfilt/emulated.c [deleted file]
src/xenfilt/emulated.h [deleted file]
src/xenfilt/fdo.c
src/xenfilt/fdo.h
src/xenfilt/log.h [deleted file]
src/xenfilt/mutex.h [deleted file]
src/xenfilt/names.h [deleted file]
src/xenfilt/pdo.c
src/xenfilt/registry.c [deleted file]
src/xenfilt/registry.h [deleted file]
src/xenfilt/thread.c

index e016829dbf81b7c024a6cdc1dc880cb96044f5bf..66f6ed9066c72a70a54c656fe7e65d27e5a30060 100644 (file)
--- a/build.py
+++ b/build.py
@@ -54,22 +54,6 @@ def make_version_header():
     file.close()
 
 
-def make_binding_header():
-    now = datetime.datetime.now()
-
-    file = open('include\\binding.h', 'w')
-    file.write('#define PCI_VENDOR_ID\t' + '0x' + os.environ['PCI_VENDOR_ID'] + '\n')
-    file.write('\n')
-
-    file.write('#define PCI_DEVICE_ID\t' + '0x' + os.environ['PCI_DEVICE_ID'] + '\n')
-    file.write('\n')
-
-    file.write('#define PCI_REVISION\t' + '0x' + os.environ['PCI_REVISION'] + '\n')
-    file.write('\n')
-
-    file.close()
-
-
 def copy_inf(name):
     src = open('src\\%s.inf' % name, 'r')
     dst = open('proj\\%s.inf' % name, 'w')
@@ -79,9 +63,6 @@ def copy_inf(name):
         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('@PCI_VENDOR_ID@', os.environ['PCI_VENDOR_ID'], line)
-        line = re.sub('@PCI_DEVICE_ID@', os.environ['PCI_DEVICE_ID'], line)
-        line = re.sub('@PCI_REVISION@', os.environ['PCI_REVISION'], line)
         dst.write(line)
 
     dst.close()
@@ -304,12 +285,6 @@ if __name__ == '__main__':
 
     make_version_header()
 
-    os.environ['PCI_VENDOR_ID'] = '5853'
-    os.environ['PCI_DEVICE_ID'] = '0002'
-    os.environ['PCI_REVISION'] = '02'
-
-    make_binding_header()
-
     copy_inf(driver)
 
     symstore_del(driver, 30)
diff --git a/include/emulated_interface.h b/include/emulated_interface.h
deleted file mode 100644 (file)
index 53cdd09..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/* 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 _XENFILT_EMULATED_INTERFACE_H
-#define _XENFILT_EMULATED_INTERFACE_H
-
-#define DEFINE_EMULATED_OPERATIONS                                  \
-        EMULATED_OPERATION(VOID,                                    \
-                           Acquire,                                 \
-                           (                                        \
-                           IN  PXENFILT_EMULATED_CONTEXT Context    \
-                           )                                        \
-                           )                                        \
-        EMULATED_OPERATION(VOID,                                    \
-                           Release,                                 \
-                           (                                        \
-                           IN  PXENFILT_EMULATED_CONTEXT Context    \
-                           )                                        \
-                           )                                        \
-        EMULATED_OPERATION(BOOLEAN,                                 \
-                           IsPresent,                               \
-                           (                                        \
-                           IN  PXENFILT_EMULATED_CONTEXT Context,   \
-                           IN  PCHAR                     Class,     \
-                           IN  PCHAR                     Device     \
-                           )                                        \
-                           )
-
-typedef struct _XENFILT_EMULATED_CONTEXT    XENFILT_EMULATED_CONTEXT, *PXENFILT_EMULATED_CONTEXT;
-
-#define EMULATED_OPERATION(_Type, _Name, _Arguments) \
-        _Type (*EMULATED_ ## _Name) _Arguments;
-
-typedef struct _XENFILT_EMULATED_OPERATIONS {
-    DEFINE_EMULATED_OPERATIONS
-} XENFILT_EMULATED_OPERATIONS, *PXENFILT_EMULATED_OPERATIONS;
-
-#undef EMULATED_OPERATION
-
-typedef struct _XENFILT_EMULATED_INTERFACE   XENFILT_EMULATED_INTERFACE, *PXENFILT_EMULATED_INTERFACE;
-
-// {062AAC96-2BF8-4A69-AD6B-154CF051E977}
-DEFINE_GUID(GUID_EMULATED_INTERFACE, 
-            0x62aac96,
-            0x2bf8,
-            0x4a69,
-            0xad,
-            0x6b,
-            0x15,
-            0x4c,
-            0xf0,
-            0x51,
-            0xe9,
-            0x77);
-
-#define EMULATED_INTERFACE_VERSION    3
-
-#define EMULATED_OPERATIONS(_Interface) \
-        (PXENFILT_EMULATED_OPERATIONS *)((ULONG_PTR)(_Interface))
-
-#define EMULATED_CONTEXT(_Interface) \
-        (PXENFILT_EMULATED_CONTEXT *)((ULONG_PTR)(_Interface) + sizeof (PVOID))
-
-#define EMULATED(_Operation, _Interface, ...) \
-        (*EMULATED_OPERATIONS(_Interface))->EMULATED_ ## _Operation((*EMULATED_CONTEXT(_Interface)), __VA_ARGS__)
-
-#endif  // _XENFILT_EMULATED_INTERFACE_H
-
diff --git a/include/get_xen_headers.sh b/include/get_xen_headers.sh
deleted file mode 100644 (file)
index 7811471..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/bin/sh -x
-
-REPO="$1"
-TAG="$2"
-
-copy()
-{
-    SRCDIR="$1"
-    DSTDIR="$2"
-    HEADER="$3"
-
-    CWD=$(pwd)
-
-    mkdir -p ${DSTDIR}
-    cd ${DSTDIR}
-
-    URL="${REPO}/raw-file/${TAG}/xen/include/${SRCDIR}/${HEADER}"
-
-    wget ${URL}
-
-    mv ${HEADER} ${HEADER}.orig
-    sed -e 's/ unsigned long/ ULONG_PTR/g' \
-        -e 's/(unsigned long/(ULONG_PTR/g' \
-        -e 's/ long/ LONG_PTR/g' \
-        -e 's/(long/(LONG_PTR/g' \
-        < ${HEADER}.orig > ${HEADER}
-
-    cd ${CWD}
-}
-
-rm -rf xen
-mkdir -p xen
-cd xen
-
-copy public . xen.h
-copy public . xen-compat.h
-copy public . trace.h
-copy public . memory.h
-copy public . sched.h
-copy public . event_channel.h
-copy public . grant_table.h
-copy xen . errno.h
-
-copy public/arch-x86 arch-x86 xen.h
-copy public/arch-x86 arch-x86 xen-x86_32.h
-copy public/arch-x86 arch-x86 xen-x86_64.h
-     
-copy public/hvm hvm hvm_op.h
-copy public/hvm hvm params.h
-
-copy public/io io xs_wire.h
-
-
diff --git a/include/util.h b/include/util.h
deleted file mode 100644 (file)
index 5057a66..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-/* 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 _UTIL_H
-#define _UTIL_H
-
-#include <ntddk.h>
-
-#include "assert.h"
-
-#define        P2ROUNDUP(_x, _a)   \
-        (-(-(_x) & -(_a)))
-
-static FORCEINLINE LONG
-__ffs(
-    IN  unsigned long long  mask
-    )
-{
-    unsigned char           *array = (unsigned char *)&mask;
-    unsigned int            byte;
-    unsigned int            bit;
-    unsigned char           val;
-
-    val = 0;
-
-    byte = 0;
-    while (byte < 8) {
-        val = array[byte];
-
-        if (val != 0)
-            break;
-
-        byte++;
-    }
-    if (byte == 8)
-        return -1;
-
-    bit = 0;
-    while (bit < 8) {
-        if (val & 0x01)
-            break;
-
-        val >>= 1;
-        bit++;
-    }
-
-    return (byte * 8) + bit;
-}
-
-#define __ffu(_mask)  \
-        __ffs(~(_mask))
-
-static FORCEINLINE LONG
-__InterlockedAdd(
-    IN  LONG    *Value,
-    IN  LONG    Delta
-    )
-{
-    LONG        New;
-    LONG        Old;
-
-    do {
-        Old = *Value;
-        New = Old + Delta;
-    } while (InterlockedCompareExchange(Value, New, Old) != Old);
-
-    return New;
-}
-
-static FORCEINLINE LONG
-__InterlockedSubtract(
-    IN  LONG    *Value,
-    IN  LONG    Delta
-    )
-{
-    LONG        New;
-    LONG        Old;
-
-    do {
-        Old = *Value;
-        New = Old - Delta;
-    } while (InterlockedCompareExchange(Value, New, Old) != Old);
-
-    return New;
-}
-
-typedef struct _NON_PAGED_BUFFER_HEADER {
-    SIZE_T  Length;
-    ULONG   Tag;
-} NON_PAGED_BUFFER_HEADER, *PNON_PAGED_BUFFER_HEADER;
-
-typedef struct _NON_PAGED_BUFFER_TRAILER {
-    ULONG   Tag;
-} NON_PAGED_BUFFER_TRAILER, *PNON_PAGED_BUFFER_TRAILER;
-
-static FORCEINLINE PVOID
-__AllocateNonPagedPoolWithTag(
-    IN  SIZE_T                  Length,
-    IN  ULONG                   Tag
-    )
-{
-    PUCHAR                      Buffer;
-    PNON_PAGED_BUFFER_HEADER    Header;
-    PNON_PAGED_BUFFER_TRAILER   Trailer;
-
-    ASSERT(Length != 0);
-
-    Buffer = ExAllocatePoolWithTag(NonPagedPool,
-                                   sizeof (NON_PAGED_BUFFER_HEADER) +
-                                   Length +
-                                   sizeof (NON_PAGED_BUFFER_TRAILER),
-                                   Tag);
-    if (Buffer == NULL)
-        goto done;
-
-    RtlZeroMemory(Buffer, 
-                  sizeof (NON_PAGED_BUFFER_HEADER) +
-                  Length +
-                  sizeof (NON_PAGED_BUFFER_TRAILER));
-
-    Header = (PNON_PAGED_BUFFER_HEADER)Buffer;
-    Header->Length = Length;
-    Header->Tag = Tag;
-
-    Buffer += sizeof (NON_PAGED_BUFFER_HEADER);
-
-    Trailer = (PNON_PAGED_BUFFER_TRAILER)(Buffer + Length);
-    Trailer->Tag = Tag;
-
-done:
-    return Buffer;
-}
-
-static FORCEINLINE VOID
-__FreePoolWithTag(
-    IN  PVOID                   _Buffer,
-    IN  ULONG                   Tag
-    )
-{
-    PUCHAR                      Buffer = _Buffer;
-    SIZE_T                      Length;
-    PNON_PAGED_BUFFER_HEADER    Header;
-    PNON_PAGED_BUFFER_TRAILER   Trailer;
-
-    ASSERT(Buffer != NULL);
-
-    Buffer -= sizeof (NON_PAGED_BUFFER_HEADER);
-
-    Header = (PNON_PAGED_BUFFER_HEADER)Buffer;
-    ASSERT3U(Tag, ==, Header->Tag);
-    Length = Header->Length;
-
-    Buffer += sizeof (NON_PAGED_BUFFER_HEADER);
-
-    Trailer = (PNON_PAGED_BUFFER_TRAILER)(Buffer + Length);
-    ASSERT3U(Tag, ==, Trailer->Tag);
-
-    Buffer -= sizeof (NON_PAGED_BUFFER_HEADER);
-
-    RtlFillMemory(Buffer, 
-                  sizeof (NON_PAGED_BUFFER_HEADER) +
-                  Length +
-                  sizeof (NON_PAGED_BUFFER_TRAILER),
-                  0xAA);
-
-    ExFreePoolWithTag(Buffer, Tag);
-}
-     
-#endif  // _UTIL_H
index 348e7927b56f9e7be848786d2ca2422a8e545f2d..2907606f428733b1cca764cf51fe6eedf7df85a1 100644 (file)
@@ -195,49 +195,48 @@ SchedYield(
     VOID
     );
 
-// LOG
+// MODULE
 
 XEN_API
 VOID
-LogXenCchVPrintf(
-    IN  ULONG       Count,
-    IN  const CHAR  *Format,
-    IN  va_list     Arguments
+ModuleLookup(
+    IN  ULONG_PTR   Address,
+    OUT PCHAR       *Name,
+    OUT PULONG_PTR  Offset
     );
 
-XEN_API
-VOID
-LogXenCchPrintf(
-    IN  ULONG       Count,
-    IN  const CHAR  *Format,
-    ...
-    );
+// LOG
 
-XEN_API
-VOID
-LogXenVPrintf(
-    IN  const CHAR  *Format,
-    IN  va_list     Arguments
-    );
+typedef enum _LOG_LEVEL {
+    LOG_LEVEL_INVALID = 0,
+    LOG_LEVEL_TRACE = 1 << DPFLTR_TRACE_LEVEL,
+    LOG_LEVEL_INFO = 1 << DPFLTR_INFO_LEVEL,
+    LOG_LEVEL_WARNING = 1 << DPFLTR_WARNING_LEVEL,
+    LOG_LEVEL_ERROR = 1 << DPFLTR_ERROR_LEVEL,
+    LOG_LEVEL_CRITICAL = 0x80000000
+} LOG_LEVEL, *PLOG_LEVEL;
 
 XEN_API
 VOID
-LogXenPrintf(
+LogCchVPrintf(
+    IN  LOG_LEVEL   Level,
+    IN  ULONG       Count,
     IN  const CHAR  *Format,
-    ...
+    IN  va_list     Arguments
     );
 
 XEN_API
 VOID
-LogQemuCchVPrintf(
-    IN  ULONG       Count,
+LogVPrintf(
+    IN  LOG_LEVEL   Level,
     IN  const CHAR  *Format,
     IN  va_list     Arguments
     );
 
 XEN_API
 VOID
-LogQemuCchPrintf(
+LogCchPrintf(
+    IN  LOG_LEVEL   Level,
     IN  ULONG       Count,
     IN  const CHAR  *Format,
     ...
@@ -245,65 +244,10 @@ LogQemuCchPrintf(
 
 XEN_API
 VOID
-LogQemuVPrintf(
-    IN  const CHAR  *Format,
-    IN  va_list     Arguments
-    );
-
-XEN_API
-VOID
-LogQemuPrintf(
+LogPrintf(
+    IN  LOG_LEVEL   Level,
     IN  const CHAR  *Format,
     ...
     );
 
-XEN_API
-VOID
-LogEnable(
-    VOID
-    );
-
-XEN_API
-VOID
-LogDisable(
-    VOID
-    );
-
-// UNPLUG
-
-XEN_API
-NTSTATUS
-UnplugReference(
-    VOID
-    );
-
-XEN_API
-VOID
-UnplugDereference(
-    VOID
-    );
-
-XEN_API
-NTSTATUS
-UnplugDevice(
-    PCHAR   Class,
-    PCHAR   Device
-    );
-
-XEN_API
-VOID
-UnplugReplay(
-    VOID
-    );
-
-// MODULE
-
-XEN_API
-VOID
-ModuleLookup(
-    IN  ULONG_PTR   Address,
-    OUT PCHAR       *Name,
-    OUT PULONG_PTR  Offset
-    );
-
 #endif  // _XEN_H
index 6a1ab27e76de5cd4055152ec59721dfe0eac1833..8de5d9a13ea202121fbe7cf8f42c94d8595e4fd9 100644 (file)
@@ -1,4 +1,4 @@
-<?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">
        <Import Project="..\configs.props" />
        
@@ -24,7 +24,7 @@
        <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> 
 
        <PropertyGroup>
-               <IncludePath>..\..\include;$(IncludePath)</IncludePath>
+               <IncludePath>..\..\include;..\..\src\common;$(IncludePath)</IncludePath>
                <RunCodeAnalysis>true</RunCodeAnalysis>
                <EnableInf2cat>false</EnableInf2cat>
                <IntDir>..\$(ProjectName)\$(ConfigurationName)\$(Platform)\</IntDir>
                <ClCompile Include="..\..\src\xen\memory.c" />
                <ClCompile Include="..\..\src\xen\sched.c" />
                <ClCompile Include="..\..\src\xen\log.c" />
-               <ClCompile Include="..\..\src\xen\debug.c" />
-               <ClCompile Include="..\..\src\xen\dump.c" />
+               <ClCompile Include="..\..\src\xen\bug_check.c" />
                <ClCompile Include="..\..\src\xen\module.c" />
                <ClCompile Include="..\..\src\xen\process.c" />
-               <ClCompile Include="..\..\src\xen\unplug.c" />
                <ClCompile Include="..\..\src\xen\system.c" />
        </ItemGroup>
        <ItemGroup>
index d740b044164f67bcbdcc153a8c18e12cdcb474e5..779d3a22898ec83f546e2f151cf8a0fd54201ff6 100644 (file)
@@ -24,7 +24,7 @@
        <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> 
 
        <PropertyGroup>
-               <IncludePath>..\..\include;$(IncludePath)</IncludePath>
+               <IncludePath>..\..\include;..\..\src\common;$(IncludePath)</IncludePath>
                <RunCodeAnalysis>true</RunCodeAnalysis>
                <EnableInf2cat>false</EnableInf2cat>
                <IntDir>..\$(ProjectName)\$(ConfigurationName)\$(Platform)\</IntDir>
@@ -74,6 +74,7 @@
                <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
        </ItemGroup>
        <ItemGroup>
+               <ClCompile Include="..\..\src\common\registry.c" />
                <ClCompile Include="..\..\src\xenbus\bus.c" />
                <ClCompile Include="..\..\src\xenbus\dma.c" />
                <ClCompile Include="..\..\src\xenbus\debug.c" />
@@ -82,7 +83,6 @@
                <ClCompile Include="..\..\src\xenbus\fdo.c" />
                <ClCompile Include="..\..\src\xenbus\gnttab.c" />
                <ClCompile Include="..\..\src\xenbus\pdo.c" />
-               <ClCompile Include="..\..\src\xenbus\registry.c" />
                <ClCompile Include="..\..\src\xenbus\shared_info.c" />
                <ClCompile Include="..\..\src\xenbus\store.c" />
                <ClCompile Include="..\..\src\xenbus\suspend.c" />
index 5ca6b2481c84b72e2c61ef61f0c917d3eb2c61ea..1c60d10dc0f545c886744091076cafad2c6ec32d 100644 (file)
@@ -24,7 +24,7 @@
        <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> 
 
        <PropertyGroup>
-               <IncludePath>..\..\include;$(IncludePath)</IncludePath>
+               <IncludePath>..\..\include;..\..\src\common;$(IncludePath)</IncludePath>
                <RunCodeAnalysis>true</RunCodeAnalysis>
                <EnableInf2cat>false</EnableInf2cat>
                <IntDir>..\$(ProjectName)\$(ConfigurationName)\$(Platform)\</IntDir>
                <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
        </ItemGroup>
        <ItemGroup>
+               <ClCompile Include="../../src/common/registry.c" />
                <ClCompile Include="../../src/xenfilt/driver.c" />
                <ClCompile Include="../../src/xenfilt/fdo.c" />
-               <ClCompile Include="../../src/xenfilt/emulated.c" />
                <ClCompile Include="../../src/xenfilt/pdo.c" />
-               <ClCompile Include="../../src/xenfilt/registry.c" />
                <ClCompile Include="../../src/xenfilt/thread.c" />
        </ItemGroup>
        <ItemGroup>
index ae2f522d3d0a75b230e6891c94ed0c877e1cf85d..0b1720ad05fd8096137c4e257a3c89da5a346a9e 100644 (file)
@@ -37,6 +37,7 @@
 #include <stdlib.h>
 #include <strsafe.h>
 #include <malloc.h>
+#include <assert.h>
 
 #include <version.h>
 
@@ -44,6 +45,13 @@ __user_code;
 
 #define MAXIMUM_BUFFER_SIZE 1024
 
+#define ENUM_KEY    "SYSTEM\\CurrentControlSet\\Enum"
+
+#define CLASS_KEY   "SYSTEM\\CurrentControlSet\\Control\\Class"
+
+#define SERVICE_KEY(_Name)   "SYSTEM\\CurrentControlSet\\Services\\" ## _Name
+#define PARAMETERS_KEY(_Name)   SERVICE_KEY(_Name) ## "\\Parameters"
+
 static VOID
 #pragma prefast(suppress:6262) // Function uses '1036' bytes of stack: exceeds /analyze:stacksize'1024'
 __Log(
@@ -74,102 +82,1146 @@ __Log(
     Category = TXTLOG_VENDOR;
     Flags = TXTLOG_DETAILS;
 
-    SetupWriteTextLog(LogToken, Category, Flags, Buffer);
-    Length = __min(MAXIMUM_BUFFER_SIZE - 1, Length + 2);
+    SetupWriteTextLog(LogToken, Category, Flags, Buffer);
+    Length = __min(MAXIMUM_BUFFER_SIZE - 1, Length + 2);
+
+    __analysis_assume(Length < MAXIMUM_BUFFER_SIZE);
+    __analysis_assume(Length >= 2);
+    Buffer[Length] = '\0';
+    Buffer[Length - 1] = '\n';
+    Buffer[Length - 2] = '\r';
+
+    OutputDebugString(Buffer);
+}
+
+#define Log(_Format, ...) \
+        __Log(__MODULE__ "|" __FUNCTION__ ": " _Format, __VA_ARGS__)
+
+static PTCHAR
+GetErrorMessage(
+    IN  DWORD   Error
+    )
+{
+    PTCHAR      Message;
+    ULONG       Index;
+
+    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
+                  FORMAT_MESSAGE_FROM_SYSTEM |
+                  FORMAT_MESSAGE_IGNORE_INSERTS,
+                  NULL,
+                  Error,
+                  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                  (LPTSTR)&Message,
+                  0,
+                  NULL);
+
+    for (Index = 0; Message[Index] != '\0'; Index++) {
+        if (Message[Index] == '\r' || Message[Index] == '\n') {
+            Message[Index] = '\0';
+            break;
+        }
+    }
+
+    return Message;
+}
+
+static const CHAR *
+FunctionName(
+    IN  DI_FUNCTION Function
+    )
+{
+#define _NAME(_Function)        \
+        case DIF_ ## _Function: \
+            return #_Function;
+
+    switch (Function) {
+    _NAME(INSTALLDEVICE);
+    _NAME(REMOVE);
+    _NAME(SELECTDEVICE);
+    _NAME(ASSIGNRESOURCES);
+    _NAME(PROPERTIES);
+    _NAME(FIRSTTIMESETUP);
+    _NAME(FOUNDDEVICE);
+    _NAME(SELECTCLASSDRIVERS);
+    _NAME(VALIDATECLASSDRIVERS);
+    _NAME(INSTALLCLASSDRIVERS);
+    _NAME(CALCDISKSPACE);
+    _NAME(DESTROYPRIVATEDATA);
+    _NAME(VALIDATEDRIVER);
+    _NAME(MOVEDEVICE);
+    _NAME(DETECT);
+    _NAME(INSTALLWIZARD);
+    _NAME(DESTROYWIZARDDATA);
+    _NAME(PROPERTYCHANGE);
+    _NAME(ENABLECLASS);
+    _NAME(DETECTVERIFY);
+    _NAME(INSTALLDEVICEFILES);
+    _NAME(ALLOW_INSTALL);
+    _NAME(SELECTBESTCOMPATDRV);
+    _NAME(REGISTERDEVICE);
+    _NAME(NEWDEVICEWIZARD_PRESELECT);
+    _NAME(NEWDEVICEWIZARD_SELECT);
+    _NAME(NEWDEVICEWIZARD_PREANALYZE);
+    _NAME(NEWDEVICEWIZARD_POSTANALYZE);
+    _NAME(NEWDEVICEWIZARD_FINISHINSTALL);
+    _NAME(INSTALLINTERFACES);
+    _NAME(DETECTCANCEL);
+    _NAME(REGISTER_COINSTALLERS);
+    _NAME(ADDPROPERTYPAGE_ADVANCED);
+    _NAME(ADDPROPERTYPAGE_BASIC);
+    _NAME(TROUBLESHOOTER);
+    _NAME(POWERMESSAGEWAKE);
+    default:
+        break;
+    }
+
+    return "UNKNOWN";
+
+#undef  _NAME
+}
+
+static DECLSPEC_NOINLINE BOOLEAN
+OpenEnumKey(
+    OUT PHKEY   Key
+    )
+{
+    HRESULT     Error;
+
+    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                         ENUM_KEY,
+                         0,
+                         KEY_READ,
+                         Key);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail1;
+    }
+
+    return TRUE;
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static DECLSPEC_NOINLINE BOOLEAN
+OpenPciKey(
+    OUT PHKEY   Key
+    )
+{
+    BOOLEAN     Success;
+    HKEY        EnumKey;
+    HRESULT     Error;
+
+    Success = OpenEnumKey(&EnumKey);
+    if (!Success)
+        goto fail1;
+
+    Error = RegOpenKeyEx(EnumKey,
+                         "PCI",
+                         0,
+                         KEY_READ,
+                         Key);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail2;
+    }
+
+    RegCloseKey(EnumKey);
+
+    return TRUE;
+
+fail2:
+    Log("fail2");
+
+    RegCloseKey(EnumKey);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static DECLSPEC_NOINLINE BOOLEAN
+GetDeviceKeyName(
+    IN  PTCHAR  Prefix,
+    OUT PTCHAR  *Name
+    )
+{
+    BOOLEAN     Success;
+    HKEY        PciKey;
+    HRESULT     Error;
+    DWORD       SubKeys;
+    DWORD       MaxSubKeyLength;
+    DWORD       SubKeyLength;
+    PTCHAR      SubKeyName;
+    DWORD       Index;
+
+    Success = OpenPciKey(&PciKey);
+    if (!Success)
+        goto fail1;
+
+    Error = RegQueryInfoKey(PciKey,
+                            NULL,
+                            NULL,
+                            NULL,
+                            &SubKeys,
+                            &MaxSubKeyLength,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail2;
+    }
+
+    SubKeyLength = MaxSubKeyLength + sizeof (TCHAR);
+
+    SubKeyName = malloc(SubKeyLength);
+    if (SubKeyName == NULL)
+        goto fail3;
+
+    for (Index = 0; Index < SubKeys; Index++) {
+        SubKeyLength = MaxSubKeyLength + sizeof (TCHAR);
+        memset(SubKeyName, 0, SubKeyLength);
+
+        Error = RegEnumKeyEx(PciKey,
+                             Index,
+                             (LPTSTR)SubKeyName,
+                             &SubKeyLength,
+                             NULL,
+                             NULL,
+                             NULL,
+                             NULL);
+        if (Error != ERROR_SUCCESS) {
+            SetLastError(Error);
+            goto fail4;
+        }
+
+        if (strncmp(SubKeyName, Prefix, strlen(Prefix)) == 0)
+            goto found;
+    }
+
+    free(SubKeyName);
+    SubKeyName = NULL;
+
+found:
+    RegCloseKey(PciKey);
+
+    Log("%s", (SubKeyName != NULL) ? SubKeyName : "none found");
+
+    *Name = SubKeyName;
+    return TRUE;
+
+fail4:
+    Log("fail4");
+
+    free(SubKeyName);
+
+fail3:
+    Log("fail3");
+
+fail2:
+    Log("fail2");
+
+    RegCloseKey(PciKey);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+#define PLATFORM_DEVICE_0001_NAME       "VEN_5853&DEV_0001"
+#define PLATFORM_DEVICE_0002_NAME       "VEN_5853&DEV_0002"
+
+#define XENSERVER_VENDOR_DEVICE_NAME    "VEN_5853&DEV_C000"
+
+static DECLSPEC_NOINLINE BOOLEAN
+OpenDeviceKey(
+    IN  PTCHAR  Name,           
+    OUT PHKEY   Key
+    )
+{
+    BOOLEAN     Success;
+    HKEY        PciKey;
+    HRESULT     Error;
+
+    Success = OpenPciKey(&PciKey);
+    if (!Success)
+        goto fail1;
+
+    Error = RegOpenKeyEx(PciKey,
+                         Name,
+                         0,
+                         KEY_READ,
+                         Key);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail2;
+    }
+
+    RegCloseKey(PciKey);
+
+    return TRUE;
+
+fail2:
+    Log("fail2");
+
+    RegCloseKey(PciKey);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+
+static DECLSPEC_NOINLINE BOOLEAN
+GetDriverKeyName(
+    IN  HKEY    DeviceKey,
+    OUT PTCHAR  *Name
+    )
+{
+    HRESULT     Error;
+    DWORD       SubKeys;
+    DWORD       MaxSubKeyLength;
+    DWORD       SubKeyLength;
+    PTCHAR      SubKeyName;
+    DWORD       Index;
+    HKEY        SubKey;
+    PTCHAR      DriverKeyName;
+
+    Error = RegQueryInfoKey(DeviceKey,
+                            NULL,
+                            NULL,
+                            NULL,
+                            &SubKeys,
+                            &MaxSubKeyLength,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail1;
+    }
+
+    SubKeyLength = MaxSubKeyLength + sizeof (TCHAR);
+
+    SubKeyName = malloc(SubKeyLength);
+    if (SubKeyName == NULL)
+        goto fail2;
+
+    SubKey = NULL;
+    DriverKeyName = NULL;
+
+    for (Index = 0; Index < SubKeys; Index++) {
+        DWORD       MaxValueLength;
+        DWORD       DriverKeyNameLength;
+        DWORD       Type;
+
+        SubKeyLength = MaxSubKeyLength + sizeof (TCHAR);
+        memset(SubKeyName, 0, SubKeyLength);
+
+        Error = RegEnumKeyEx(DeviceKey,
+                             Index,
+                             (LPTSTR)SubKeyName,
+                             &SubKeyLength,
+                             NULL,
+                             NULL,
+                             NULL,
+                             NULL);
+        if (Error != ERROR_SUCCESS) {
+            SetLastError(Error);
+            goto fail3;
+        }
+
+        Error = RegOpenKeyEx(DeviceKey,
+                             SubKeyName,
+                             0,
+                             KEY_READ,
+                             &SubKey);
+        if (Error != ERROR_SUCCESS)
+            continue;
+
+        Error = RegQueryInfoKey(SubKey,
+                                NULL,
+                                NULL,
+                                NULL,    
+                                NULL,
+                                NULL,
+                                NULL,
+                                NULL,
+                                NULL,
+                                &MaxValueLength,
+                                NULL,
+                                NULL);
+        if (Error != ERROR_SUCCESS) {
+            SetLastError(Error);
+            goto fail4;
+        }
+
+        DriverKeyNameLength = MaxValueLength + sizeof (TCHAR);
+
+        DriverKeyName = malloc(DriverKeyNameLength);
+        if (DriverKeyName == NULL)
+            goto fail5;
+
+        Error = RegQueryValueEx(SubKey,
+                                "Driver",
+                                NULL,
+                                &Type,
+                                (LPBYTE)DriverKeyName,
+                                &DriverKeyNameLength);
+        if (Error == ERROR_SUCCESS &&
+            Type == REG_SZ)
+            break;
+
+        free(DriverKeyName);
+        DriverKeyName = NULL;
+
+        RegCloseKey(SubKey);
+        SubKey = NULL;
+    }
+
+    Log("%s", (DriverKeyName != NULL) ? DriverKeyName : "none found");
+
+    if (SubKey != NULL)
+        RegCloseKey(SubKey);
+
+    free(SubKeyName);
+
+    *Name = DriverKeyName;
+    return TRUE;
+
+fail5:
+    Log("fail5");
+
+fail4:
+    Log("fail4");
+
+    if (SubKey != NULL)
+        RegCloseKey(SubKey);
+
+fail3:
+    Log("fail3");
+
+    free(SubKeyName);
+
+fail2:
+    Log("fail2");
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static DECLSPEC_NOINLINE BOOLEAN
+OpenClassKey(
+    OUT PHKEY   Key
+    )
+{
+    HRESULT     Error;
+
+    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                         CLASS_KEY,
+                         0,
+                         KEY_READ,
+                         Key);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail1;
+    }
+
+    return TRUE;
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static DECLSPEC_NOINLINE BOOLEAN
+OpenDriverKey(
+    IN  PTCHAR  Name,           
+    OUT PHKEY   Key
+    )
+{
+    BOOLEAN     Success;
+    HKEY        ClassKey;
+    HRESULT     Error;
+
+    Success = OpenClassKey(&ClassKey);
+    if (!Success)
+        goto fail1;
+
+    Error = RegOpenKeyEx(ClassKey,
+                         Name,
+                         0,
+                         KEY_READ,
+                         Key);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail2;
+    }
+
+    RegCloseKey(ClassKey);
+
+    return TRUE;
+
+fail2:
+    Log("fail2");
+
+    RegCloseKey(ClassKey);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static PTCHAR
+GetDeviceInstance(
+    IN  HDEVINFO            DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA    DeviceInfoData
+    )
+{
+    DWORD                   DeviceInstanceLength;
+    PTCHAR                  DeviceInstance;
+    DWORD                   Index;
+    HRESULT                 Error;
+
+    if (!SetupDiGetDeviceInstanceId(DeviceInfoSet,
+                                    DeviceInfoData,
+                                    NULL,
+                                    0,
+                                    &DeviceInstanceLength)) {
+        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+            goto fail1;
+    }
+
+    DeviceInstanceLength += sizeof (TCHAR);
+
+    DeviceInstance = malloc(DeviceInstanceLength);
+    if (DeviceInstance == NULL)
+        goto fail2;
+
+    memset(DeviceInstance, 0, DeviceInstanceLength);
+
+    if (!SetupDiGetDeviceInstanceId(DeviceInfoSet,
+                                    DeviceInfoData,
+                                    DeviceInstance,
+                                    DeviceInstanceLength,
+                                    NULL))
+        goto fail3;
+
+    for (Index = 0; Index < strlen(DeviceInstance); Index++)
+        DeviceInstance[Index] = (CHAR)toupper(DeviceInstance[Index]);
+
+    Log("%s", DeviceInstance);
+
+    return DeviceInstance;
+
+fail3:
+    Log("fail3");
+
+    free(DeviceInstance);
+
+fail2:
+    Log("fail2");
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return NULL;
+}
+
+static BOOLEAN
+GetActiveDeviceInstance(
+    OUT PTCHAR  *DeviceInstance
+    )
+{
+    HKEY        ParametersKey;
+    DWORD       MaxValueLength;
+    DWORD       ActiveDeviceInstanceLength;
+    PTCHAR      ActiveDeviceInstance;
+    DWORD       Type;
+    HRESULT     Error;
+
+    Error = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
+                           PARAMETERS_KEY("XENBUS"),
+                           0,
+                           NULL,
+                           REG_OPTION_NON_VOLATILE,
+                           KEY_ALL_ACCESS,
+                           NULL,
+                           &ParametersKey,
+                           NULL);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail1;
+    }
+
+    Error = RegQueryInfoKey(ParametersKey,
+                            NULL,
+                            NULL,
+                            NULL,    
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            &MaxValueLength,
+                            NULL,
+                            NULL);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail2;
+    }
+       
+    ActiveDeviceInstanceLength = MaxValueLength + sizeof (TCHAR);
+
+    ActiveDeviceInstance = malloc(ActiveDeviceInstanceLength);
+    if (ActiveDeviceInstance == NULL)
+        goto fail3;
+
+    memset(ActiveDeviceInstance, 0, ActiveDeviceInstanceLength);
+
+    Error = RegQueryValueEx(ParametersKey,
+                            "ActiveDeviceInstance",
+                            NULL,
+                            &Type,
+                            (LPBYTE)ActiveDeviceInstance,
+                            &ActiveDeviceInstanceLength);
+    if (Error == ERROR_SUCCESS &&
+        Type == REG_SZ)
+        goto found;
+
+    free(ActiveDeviceInstance);
+    ActiveDeviceInstance = NULL;
+
+found:
+    Log("%s", (ActiveDeviceInstance != NULL) ? ActiveDeviceInstance : "none found");
+
+    RegCloseKey(ParametersKey);
+
+    *DeviceInstance = ActiveDeviceInstance;
+    return TRUE;
+
+fail3:
+    Log("fail3");
+
+fail2:
+    Log("fail2");
+
+    RegCloseKey(ParametersKey);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+SetActiveDeviceInstance(
+    IN PTCHAR   DeviceInstance
+    )
+{
+    PTCHAR      DeviceName;
+    BOOLEAN     Success;
+    HKEY        ParametersKey;
+    HRESULT     Error;
+
+    Log("%s", DeviceInstance);
+
+    DeviceName = strchr(DeviceInstance, '\\');
+    assert(DeviceName != NULL);
+    DeviceName++;
+
+    // Check whether we are binding to the XenServer vendor device
+    if (strncmp(DeviceName,
+                XENSERVER_VENDOR_DEVICE_NAME,
+                strlen(XENSERVER_VENDOR_DEVICE_NAME)) != 0) {
+        PTCHAR  DeviceKeyName;
+
+        // We are binding to a legacy platform device so only make it
+        // active if there is no XenServer vendor device
+        Success = GetDeviceKeyName(XENSERVER_VENDOR_DEVICE_NAME,
+                                   &DeviceKeyName);
+        if (!Success)
+            goto fail1;
+
+        if (DeviceKeyName != NULL) {
+            Log("ignoring");
+            free(DeviceKeyName);
+            goto done;
+        }
+    }
+
+    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                         PARAMETERS_KEY("XENBUS"),
+                         0,
+                         KEY_ALL_ACCESS,
+                         &ParametersKey);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail2;
+    }
+
+    Error = RegSetValueEx(ParametersKey,
+                          "ActiveDeviceInstance",
+                          0,
+                          REG_SZ,
+                          (LPBYTE)DeviceInstance,
+                          (DWORD)(strlen(DeviceInstance) + sizeof (TCHAR)));
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail3;
+    }
+
+    RegCloseKey(ParametersKey);
+
+done:
+    return TRUE;
+
+fail3:
+    Log("fail3");
+
+    RegCloseKey(ParametersKey);
+
+fail2:
+    Log("fail2");
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+ClearActiveDeviceInstance(
+    VOID
+    )
+{
+    HKEY        ParametersKey;
+    HRESULT     Error;
+
+    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                         PARAMETERS_KEY("XENBUS"),
+                         0,
+                         KEY_ALL_ACCESS,
+                         &ParametersKey);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail1;
+    }
+
+    Error = RegDeleteValue(ParametersKey,
+                           "ActiveDeviceInstance");
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail2;
+    }
+
+    RegCloseKey(ParametersKey);
+
+    return TRUE;
+
+fail2:
+    Log("fail2");
+
+    RegCloseKey(ParametersKey);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static PTCHAR
+GetProperty(
+    IN  HDEVINFO            DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA    DeviceInfoData,
+    IN  DWORD               Index
+    )
+{
+    DWORD                   Type;
+    DWORD                   PropertyLength;
+    PTCHAR                  Property;
+    HRESULT                 Error;
+
+    if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
+                                          DeviceInfoData,
+                                          Index,
+                                          &Type,
+                                          NULL,
+                                          0,
+                                          &PropertyLength)) {
+        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+            goto fail1;
+    }
+
+    if (Type != REG_SZ) {
+        SetLastError(ERROR_BAD_FORMAT);
+        goto fail2;
+    }
+
+    PropertyLength += sizeof (TCHAR);
+
+    Property = malloc(PropertyLength);
+    if (Property == NULL)
+        goto fail3;
+
+    memset(Property, 0, PropertyLength);
+
+    if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
+                                          DeviceInfoData,
+                                          Index,
+                                          NULL,
+                                          (PBYTE)Property,
+                                          PropertyLength,
+                                          NULL))
+        goto fail4;
+
+    return Property;
+
+fail4:
+    Log("fail4");
+
+    free(Property);
+
+fail3:
+    Log("fail3");
+
+fail2:
+    Log("fail2");
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return NULL;
+}
+
+static BOOLEAN
+SetFriendlyName(
+    IN  HDEVINFO            DeviceInfoSet,
+    IN  PSP_DEVINFO_DATA    DeviceInfoData,
+    IN  WORD                DeviceId,
+    IN  BOOLEAN             Active
+    )
+{
+    TCHAR                   FriendlyName[MAX_PATH];
+    DWORD                   FriendlyNameLength;
+    HRESULT                 Result;
+    HRESULT                 Error;
+
+    Result = StringCbPrintf(FriendlyName,
+                            MAX_PATH,
+                            "XenServer PV Bus (%04X) %s",
+                            DeviceId,
+                            (Active)? "[ACTIVE]" : "");
+    if (!SUCCEEDED(Result))
+        goto fail1;
+
+    Log("%s", FriendlyName);
+
+    FriendlyNameLength = (DWORD)(strlen(FriendlyName) + sizeof (TCHAR));
+
+    if (!SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
+                                          DeviceInfoData,
+                                          SPDRP_FRIENDLYNAME,
+                                          (PBYTE)FriendlyName,
+                                          FriendlyNameLength))
+        goto fail2;
+
+    return TRUE;
+
+fail2:
+    Log("fail2");
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+static BOOLEAN
+AllowInstall(
+    VOID
+    )
+{
+    BOOLEAN Success;
+    PTCHAR  DeviceKeyName = NULL;
+    HKEY    DeviceKey = NULL;
+    PTCHAR  DriverKeyName = NULL;
+    HKEY    DriverKey = NULL;
+    HRESULT Error;
+    DWORD   MaxValueLength;
+    DWORD   DriverDescLength;
+    PTCHAR  DriverDesc = NULL;
+    DWORD   Type;
+
+    // Look for a legacy platform device
+    Success = GetDeviceKeyName(PLATFORM_DEVICE_0001_NAME,
+                               &DeviceKeyName);
+    if (!Success)
+        goto fail1;
+
+    if (DeviceKeyName != NULL)
+        goto found;
+
+    Success = GetDeviceKeyName(PLATFORM_DEVICE_0002_NAME,
+                               &DeviceKeyName);
+    if (!Success)
+        goto fail2;
+
+    if (DeviceKeyName != NULL)
+        goto found;
+
+    // No legacy platform device
+    goto done;
+
+found:
+    Success = OpenDeviceKey(DeviceKeyName, &DeviceKey);
+    if (!Success)
+        goto fail3;
+
+    // Check for a bound driver
+    Success = GetDriverKeyName(DeviceKey, &DriverKeyName);
+    if (!Success)
+        goto fail4;
+
+    if (DriverKeyName == NULL)
+        goto done;
+
+    Success = OpenDriverKey(DriverKeyName, &DriverKey);
+    if (!Success)
+        goto fail5;
+
+    Error = RegQueryInfoKey(DriverKey,
+                            NULL,
+                            NULL,
+                            NULL,    
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            &MaxValueLength,
+                            NULL,
+                            NULL);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail6;
+    }
+
+    DriverDescLength = MaxValueLength + sizeof (TCHAR);
+
+    DriverDesc = malloc(DriverDescLength);
+    if (DriverDesc == NULL)
+        goto fail7;
+
+    memset(DriverDesc, 0, DriverDescLength);
+
+    Error = RegQueryValueEx(DriverKey,
+                            "DriverDesc",
+                            NULL,
+                            &Type,
+                            (LPBYTE)DriverDesc,
+                            &DriverDescLength);
+    if (Error != ERROR_SUCCESS) {
+        if (Error == ERROR_FILE_NOT_FOUND)
+            goto done;
+
+        SetLastError(Error);
+        goto fail8;
+    }
+
+    if (Type != REG_SZ) {
+        SetLastError(ERROR_BAD_FORMAT);
+        goto fail9;
+    }
+
+    if (strcmp(DriverDesc, "XenServer PV Bus") != 0) {
+        SetLastError(ERROR_INSTALL_FAILURE);
+        goto fail10;
+    }
+
+done:
+    if (DriverDesc != NULL) {
+        free(DriverDesc);
+        RegCloseKey(DriverKey);
+    }
+
+    if (DriverKeyName != NULL) {
+        free(DriverKeyName);
+        RegCloseKey(DeviceKey);
+    }
+
+    if (DeviceKeyName != NULL)
+        free(DeviceKeyName);
+
+    return TRUE;
+
+fail10:
+    Log("fail10");
+
+fail9:
+    Log("fail9");
+
+fail8:
+    Log("fail8");
+
+    free(DriverDesc);
+
+fail7:
+    Log("fail7");
+
+fail6:
+    Log("fail6");
+
+    RegCloseKey(DriverKey);
+
+fail5:
+    Log("fail5");
 
-    __analysis_assume(Length < MAXIMUM_BUFFER_SIZE);
-    __analysis_assume(Length >= 2);
-    Buffer[Length] = '\0';
-    Buffer[Length - 1] = '\n';
-    Buffer[Length - 2] = '\r';
+    free(DriverKeyName);
 
-    OutputDebugString(Buffer);
-}
+fail4:
+    Log("fail4");
 
-#define Log(_Format, ...) \
-        __Log(__MODULE__ "|" __FUNCTION__ ": " _Format, __VA_ARGS__)
+    RegCloseKey(DeviceKey);
 
-static PTCHAR
-GetErrorMessage(
-    IN  DWORD   Error
-    )
-{
-    PTCHAR      Message;
-    ULONG       Index;
+fail3:
+    Log("fail3");
 
-    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
-                  FORMAT_MESSAGE_FROM_SYSTEM |
-                  FORMAT_MESSAGE_IGNORE_INSERTS,
-                  NULL,
-                  Error,
-                  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-                  (LPTSTR)&Message,
-                  0,
-                  NULL);
+    free(DeviceKeyName);
 
-    for (Index = 0; Message[Index] != '\0'; Index++) {
-        if (Message[Index] == '\r' || Message[Index] == '\n') {
-            Message[Index] = '\0';
-            break;
-        }
-    }
+fail2:
+    Log("fail2");
 
-    return Message;
-}
+fail1:
+    Error = GetLastError();
 
-static const CHAR *
-FunctionName(
-    IN  DI_FUNCTION Function
-    )
-{
-#define _NAME(_Function)        \
-        case DIF_ ## _Function: \
-            return #_Function;
+    {
+        PTCHAR  Message;
 
-    switch (Function) {
-    _NAME(INSTALLDEVICE);
-    _NAME(REMOVE);
-    _NAME(SELECTDEVICE);
-    _NAME(ASSIGNRESOURCES);
-    _NAME(PROPERTIES);
-    _NAME(FIRSTTIMESETUP);
-    _NAME(FOUNDDEVICE);
-    _NAME(SELECTCLASSDRIVERS);
-    _NAME(VALIDATECLASSDRIVERS);
-    _NAME(INSTALLCLASSDRIVERS);
-    _NAME(CALCDISKSPACE);
-    _NAME(DESTROYPRIVATEDATA);
-    _NAME(VALIDATEDRIVER);
-    _NAME(MOVEDEVICE);
-    _NAME(DETECT);
-    _NAME(INSTALLWIZARD);
-    _NAME(DESTROYWIZARDDATA);
-    _NAME(PROPERTYCHANGE);
-    _NAME(ENABLECLASS);
-    _NAME(DETECTVERIFY);
-    _NAME(INSTALLDEVICEFILES);
-    _NAME(ALLOW_INSTALL);
-    _NAME(SELECTBESTCOMPATDRV);
-    _NAME(REGISTERDEVICE);
-    _NAME(NEWDEVICEWIZARD_PRESELECT);
-    _NAME(NEWDEVICEWIZARD_SELECT);
-    _NAME(NEWDEVICEWIZARD_PREANALYZE);
-    _NAME(NEWDEVICEWIZARD_POSTANALYZE);
-    _NAME(NEWDEVICEWIZARD_FINISHINSTALL);
-    _NAME(INSTALLINTERFACES);
-    _NAME(DETECTCANCEL);
-    _NAME(REGISTER_COINSTALLERS);
-    _NAME(ADDPROPERTYPAGE_ADVANCED);
-    _NAME(ADDPROPERTYPAGE_BASIC);
-    _NAME(TROUBLESHOOTER);
-    _NAME(POWERMESSAGEWAKE);
-    default:
-        break;
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
     }
 
-    return "UNKNOWN";
-
-#undef  _NAME
+    return FALSE;
 }
 
 static BOOLEAN
@@ -428,13 +1480,68 @@ __DifInstallPreProcess(
     IN  PCOINSTALLER_CONTEXT_DATA   Context
     )
 {
-    UNREFERENCED_PARAMETER(DeviceInfoSet);
-    UNREFERENCED_PARAMETER(DeviceInfoData);
+    BOOLEAN                         Success;
+    PTCHAR                          DeviceInstance;
+    PTCHAR                          ActiveDeviceInstance;
+    HRESULT                         Error;
+
     UNREFERENCED_PARAMETER(Context);
 
-    Log("<===>");
+    Log("====>");
 
-    return ERROR_DI_POSTPROCESSING_REQUIRED; 
+    Success = AllowInstall();
+    if (!Success)
+        goto fail1;
+
+    DeviceInstance = GetDeviceInstance(DeviceInfoSet, DeviceInfoData);
+    if (DeviceInstance == NULL)
+        goto fail2;
+
+    ActiveDeviceInstance = NULL;
+
+    Success = GetActiveDeviceInstance(&ActiveDeviceInstance);
+    if (!Success)
+        goto fail3;
+
+    if (ActiveDeviceInstance == NULL) {
+        Success = SetActiveDeviceInstance(DeviceInstance);
+        if (!Success)
+            goto fail4;
+    } else {
+        free(ActiveDeviceInstance);
+    }
+
+    free(DeviceInstance);
+
+    Log("<====");
+    
+    return ERROR_DI_POSTPROCESSING_REQUIRED;
+
+fail4:
+    Log("fail4");
+
+    free(ActiveDeviceInstance);
+
+fail3:
+    Log("fail3");
+
+    free(DeviceInstance);
+
+fail2:
+    Log("fail2");
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return Error;
 }
 
 static FORCEINLINE HRESULT
@@ -445,6 +1552,10 @@ __DifInstallPostProcess(
     )
 {
     HRESULT                         Error;
+    PTCHAR                          DeviceInstance;
+    PTCHAR                          ActiveDeviceInstance;
+    DWORD                           DeviceId;
+    BOOLEAN                         Active;
     BOOLEAN                         Success;
 
     Log("====>");
@@ -455,28 +1566,87 @@ __DifInstallPostProcess(
         goto fail1;
     }
 
+    DeviceInstance = GetDeviceInstance(DeviceInfoSet, DeviceInfoData);
+    if (DeviceInstance == NULL)
+        goto fail2;
+
+    ActiveDeviceInstance = NULL;
+
+    Success = GetActiveDeviceInstance(&ActiveDeviceInstance);
+    if (!Success)
+        goto fail3;
+
+    if (sscanf_s(DeviceInstance,
+                 "PCI\\VEN_5853&DEV_%x",
+                 &DeviceId) != 1) {
+        SetLastError(ERROR_BAD_FORMAT);
+        goto fail4;
+    }
+
+    Active = (ActiveDeviceInstance != NULL &&
+              strcmp(DeviceInstance, ActiveDeviceInstance) == 0) ?
+             TRUE :
+             FALSE;
+
+    Success = SetFriendlyName(DeviceInfoSet,
+                              DeviceInfoData,
+                              (WORD)DeviceId,
+                              Active);
+    if (!Success)
+        goto fail5;
+
+    if (!Active)
+        goto done;
+
     Success = InstallFilter(&GUID_SYSTEM_DEVICE, "XENFILT");
     if (!Success)
-        goto fail2;
+        goto fail6;
 
     Success = InstallFilter(&GUID_HDC_DEVICE, "XENFILT");
     if (!Success)
-        goto fail3;
+        goto fail7;
 
     Success = RequestReboot(DeviceInfoSet, DeviceInfoData);
     if (!Success)
-        goto fail4;
+        goto fail8;
+
+done:
+    if (ActiveDeviceInstance != NULL)
+        free(ActiveDeviceInstance);
+
+    free(DeviceInstance);
 
     Log("<====");
 
     return NO_ERROR;
 
+fail8:
+    Log("fail8");
+
+    (VOID) RemoveFilter(&GUID_HDC_DEVICE, "XENFILT");
+
+fail7:
+    Log("fail7");
+
+    (VOID) RemoveFilter(&GUID_SYSTEM_DEVICE, "XENFILT");
+
+fail6:
+    Log("fail6");
+
+fail5:
+    Log("fail5");
+
 fail4:
     Log("fail4");
 
+    if (ActiveDeviceInstance != NULL)
+        free(ActiveDeviceInstance);
+
 fail3:
     Log("fail3");
 
+    free(DeviceInstance);
+
 fail2:
     Log("fail2");
 
@@ -540,13 +1710,82 @@ __DifRemovePreProcess(
     IN  PCOINSTALLER_CONTEXT_DATA   Context
     )
 {
-    UNREFERENCED_PARAMETER(DeviceInfoSet);
-    UNREFERENCED_PARAMETER(DeviceInfoData);
+    BOOLEAN                         Success;
+    PTCHAR                          DeviceInstance;
+    PTCHAR                          ActiveDeviceInstance;
+    BOOLEAN                         Active;
+    HRESULT                         Error;
+
     UNREFERENCED_PARAMETER(Context);
 
-    Log("<===>");
+    Log("====>");
+
+    DeviceInstance = GetDeviceInstance(DeviceInfoSet, DeviceInfoData);
+    if (DeviceInstance == NULL)
+        goto fail3;
+
+    Success = GetActiveDeviceInstance(&ActiveDeviceInstance);
+    if (!Success)
+        goto fail4;
+
+    Active = (ActiveDeviceInstance != NULL &&
+              strcmp(DeviceInstance, ActiveDeviceInstance) == 0) ?
+             TRUE :
+             FALSE;
+
+    if (!Active)
+        goto done;
+
+    ClearActiveDeviceInstance();
+
+    Success = RemoveFilter(&GUID_HDC_DEVICE, "XENFILT");
+    if (!Success)
+        goto fail1;
+
+    Success = RemoveFilter(&GUID_SYSTEM_DEVICE, "XENFILT");
+    if (!Success)
+        goto fail2;
+
+    Success = RequestReboot(DeviceInfoSet, DeviceInfoData);
+    if (!Success)
+        goto fail5;
+
+done:
+    if (ActiveDeviceInstance != NULL)
+        free(ActiveDeviceInstance);
+
+    free(DeviceInstance);
+
+    Log("<====");
 
     return ERROR_DI_POSTPROCESSING_REQUIRED; 
+
+fail5:
+    Log("fail5");
+
+fail4:
+    Log("fail4");
+
+    free(DeviceInstance);
+
+fail3:
+    Log("fail3");
+
+fail2:
+    Log("fail2");
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return Error;
 }
 
 static FORCEINLINE HRESULT
@@ -557,7 +1796,11 @@ __DifRemovePostProcess(
     )
 {
     HRESULT                         Error;
-    BOOLEAN                         Success;
+
+    UNREFERENCED_PARAMETER(DeviceInfoSet);
+    UNREFERENCED_PARAMETER(DeviceInfoData);
+
+    Log("====>");
 
     Error = Context->InstallResult;
     if (Error != NO_ERROR) {
@@ -565,23 +1808,10 @@ __DifRemovePostProcess(
         goto fail1;
     }
 
-    Success = RemoveFilter(&GUID_HDC_DEVICE, "XENFILT");
-    if (!Success)
-        goto fail2;
-
-    Success = RemoveFilter(&GUID_SYSTEM_DEVICE, "XENFILT");
-    if (!Success)
-        goto fail3;
-
-    Success = RequestReboot(DeviceInfoSet, DeviceInfoData);
-    if (!Success)
-        goto fail4;
+    Log("<====");
 
     return NO_ERROR;
 
-fail4:
-fail3:
-fail2:
 fail1:
     Error = GetLastError();
 
@@ -649,6 +1879,15 @@ Entry(
         MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR,
         DAY_STR "/" MONTH_STR "/" YEAR_STR);
 
+    if (!Context->PostProcessing) {
+        Log("%s PreProcessing",
+            FunctionName(Function));
+    } else {
+        Log("%s PostProcessing (%08x)",
+            FunctionName(Function),
+            Context->InstallResult);
+    }
+
     switch (Function) {
     case DIF_INSTALLDEVICE: {
         SP_DRVINFO_DATA         DriverInfoData;
@@ -673,15 +1912,8 @@ Entry(
         break;
     default:
         if (!Context->PostProcessing) {
-            Log("%s PreProcessing",
-                FunctionName(Function));
-
             Error = NO_ERROR;
         } else {
-            Log("%s PostProcessing (%08x)",
-                FunctionName(Function),
-                Context->InstallResult);
-
             Error = Context->InstallResult;
         }
 
diff --git a/src/common/assert.h b/src/common/assert.h
new file mode 100644 (file)
index 0000000..05f5b85
--- /dev/null
@@ -0,0 +1,173 @@
+/* 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 _COMMON_ASSERT_H
+#define _COMMON_ASSERT_H
+
+#include <ntddk.h>
+
+#include "dbg_print.h"
+
+static FORCEINLINE VOID
+__Bug(
+    IN  ULONG       Code,
+    IN  ULONG_PTR   Parameter1,
+    IN  ULONG_PTR   Parameter2,
+    IN  ULONG_PTR   Parameter3,
+    IN  ULONG_PTR   Parameter4
+    )
+{
+#pragma prefast(suppress:28159)
+    KeBugCheckEx(Code,
+                 Parameter1,
+                 Parameter2,
+                 Parameter3,
+                 Parameter4);
+}
+
+#define ASSERTION_FAILURE   0x0000DEAD
+
+#define BUG(_TEXT)                                              \
+        do {                                                    \
+            const CHAR  *_Text = (_TEXT);                       \
+            const CHAR  *_File = __FILE__;                      \
+            ULONG       _Line = __LINE__;                       \
+                                                                \
+            Error("BUG: " _TEXT "\n");                          \
+            __Bug(ASSERTION_FAILURE,                            \
+                  (ULONG_PTR)_Text,                             \
+                  (ULONG_PTR)_File,                             \
+                  (ULONG_PTR)_Line,                             \
+                  0);                                           \
+        } while (FALSE)
+
+#define BUG_ON(_EXP)                \
+        if (_EXP) BUG(#_EXP)
+
+#if DBG
+
+#define __NT_ASSERT(_EXP)                                       \
+        ((!(_EXP)) ?                                            \
+        (Error("ASSERTION FAILED: " #_EXP "\n"),                \
+         __annotation(L"Debug", L"AssertFail", L#_EXP),         \
+         DbgRaiseAssertionFailure(), FALSE) :                   \
+        TRUE)
+
+#define __ASSERT(_EXP)  __NT_ASSERT(_EXP)
+
+#else   // DBG
+
+#define __ASSERT(_EXP)  BUG_ON(!(_EXP))
+
+#endif  // DBG
+
+#undef  ASSERT
+
+#define ASSERT(_EXP)                    \
+        do {                            \
+            __ASSERT(_EXP);             \
+            __analysis_assume(_EXP);    \
+        } while (FALSE)
+
+#define ASSERT3U(_X, _OP, _Y)                       \
+        do {                                        \
+            ULONGLONG   _Lval = (ULONGLONG)(_X);    \
+            ULONGLONG   _Rval = (ULONGLONG)(_Y);    \
+            if (!(_Lval _OP _Rval)) {               \
+                Error("%s = %llu\n", #_X, _Lval);   \
+                Error("%s = %llu\n", #_Y, _Rval);   \
+                ASSERT(_X _OP _Y);                  \
+            }                                       \
+        } while (FALSE)
+
+#define ASSERT3S(_X, _OP, _Y)                       \
+        do {                                        \
+            LONGLONG    _Lval = (LONGLONG)(_X);     \
+            LONGLONG    _Rval = (LONGLONG)(_Y);     \
+            if (!(_Lval _OP _Rval)) {               \
+                Error("%s = %lld\n", #_X, _Lval);   \
+                Error("%s = %lld\n", #_Y, _Rval);   \
+                ASSERT(_X _OP _Y);                  \
+            }                                       \
+        } while (FALSE)
+
+#define ASSERT3P(_X, _OP, _Y)                       \
+        do {                                        \
+            PVOID   _Lval = (PVOID)(_X);            \
+            PVOID   _Rval = (PVOID)(_Y);            \
+            if (!(_Lval _OP _Rval)) {               \
+                Error("%s = %p\n", #_X, _Lval);     \
+                Error("%s = %p\n", #_Y, _Rval);     \
+                ASSERT(_X _OP _Y);                  \
+            }                                       \
+        } while (FALSE)
+
+#ifndef TEST_MEMORY
+#define TEST_MEMORY DBG
+#endif
+
+#if TEST_MEMORY
+
+static __inline BOOLEAN
+_IsZeroMemory(
+    IN  const PCHAR Caller,
+    IN  const PCHAR Name,
+    IN  PVOID       Buffer,
+    IN  ULONG       Length
+    )
+{
+    ULONG           Offset;
+
+    Offset = 0;
+    while (Offset < Length) {
+        if (*((PUCHAR)Buffer + Offset) != 0) {
+            Error("%s: non-zero byte in %s (0x%p+0x%x)\n", Caller, Name, Buffer, Offset);
+            return FALSE;
+        }
+        Offset++;
+    }
+
+    return TRUE;
+}
+
+#define IsZeroMemory(_Buffer, _Length) \
+        _IsZeroMemory(__FUNCTION__, #_Buffer, (_Buffer), (_Length))
+
+#else   // TEST_MEMORY
+
+#define IsZeroMemory(_Buffer, _Length)  TRUE
+
+#endif  // TEST_MEMORY
+
+#define IMPLY(_X, _Y)   (!(_X) || (_Y))
+#define EQUIV(_X, _Y)   (IMPLY((_X), (_Y)) && IMPLY((_Y), (_X)))
+
+#endif  // _COMMON_ASSERT_H
diff --git a/src/common/dbg_print.h b/src/common/dbg_print.h
new file mode 100644 (file)
index 0000000..b9b5197
--- /dev/null
@@ -0,0 +1,159 @@
+/* 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 _COMMON_DBG_PRINT_H
+#define _COMMON_DBG_PRINT_H
+
+#include <ntddk.h>
+#include <stdarg.h>
+
+#pragma warning(disable:4127)   // conditional expression is constant
+
+static __inline VOID
+__Error(
+    IN  const CHAR  *Prefix,
+    IN  const CHAR  *Format,
+    ...
+    )
+{
+    va_list         Arguments;
+
+    va_start(Arguments, Format);
+
+#pragma prefast(suppress:6001) // Using uninitialized memory
+    vDbgPrintExWithPrefix(Prefix,
+                          DPFLTR_IHVDRIVER_ID,
+                          DPFLTR_ERROR_LEVEL,
+                          Format,
+                          Arguments);
+    va_end(Arguments);
+}
+
+#define Error(...)  \
+        __Error(__MODULE__ "|" __FUNCTION__ ": ", __VA_ARGS__)
+
+static __inline VOID
+__Warning(
+    IN  const CHAR  *Prefix,
+    IN  const CHAR  *Format,
+    ...
+    )
+{
+    va_list         Arguments;
+
+    va_start(Arguments, Format);
+
+#pragma prefast(suppress:6001) // Using uninitialized memory
+    vDbgPrintExWithPrefix(Prefix,
+                          DPFLTR_IHVDRIVER_ID,
+                          DPFLTR_WARNING_LEVEL,
+                          Format,
+                          Arguments);
+    va_end(Arguments);
+}
+
+#define Warning(...)  \
+        __Warning(__MODULE__ "|" __FUNCTION__ ": ", __VA_ARGS__)
+
+#if DBG
+static __inline VOID
+__Trace(
+    IN  const CHAR  *Prefix,
+    IN  const CHAR  *Format,
+    ...
+    )
+{
+    va_list         Arguments;
+
+    va_start(Arguments, Format);
+
+#pragma prefast(suppress:6001) // Using uninitialized memory
+    vDbgPrintExWithPrefix(Prefix,
+                          DPFLTR_IHVDRIVER_ID,
+                          DPFLTR_TRACE_LEVEL,
+                          Format,
+                          Arguments);
+    va_end(Arguments);
+}
+
+#define Trace(...)  \
+        __Trace(__MODULE__ "|" __FUNCTION__ ": ", __VA_ARGS__)
+#else   // DBG
+#define Trace(...)  (VOID)(__VA_ARGS__)
+#endif  // DBG
+
+static __inline VOID
+__Info(
+    IN  const CHAR  *Prefix,
+    IN  const CHAR  *Format,
+    ...
+    )
+{
+    va_list         Arguments;
+
+    va_start(Arguments, Format);
+
+#pragma prefast(suppress:6001) // Using uninitialized memory
+    vDbgPrintExWithPrefix(Prefix,
+                          DPFLTR_IHVDRIVER_ID,
+                          DPFLTR_INFO_LEVEL,
+                          Format,
+                          Arguments);
+    va_end(Arguments);
+}
+
+#define Info(...)  \
+        __Info(__MODULE__ "|"  __FUNCTION__ ": ", __VA_ARGS__)
+
+#define DBG_PRINT_ENABLE_FILTER(_Id, _Level)                       \
+        do {                                                        \
+            DbgSetDebugFilterState((_Id), (_Level), TRUE);          \
+        } while (FALSE)
+
+static __inline VOID
+__DbgPrintEnable(
+    VOID
+    )
+{
+    DBG_PRINT_ENABLE_FILTER(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL);
+    DBG_PRINT_ENABLE_FILTER(DPFLTR_IHVDRIVER_ID, DPFLTR_WARNING_LEVEL);
+    DBG_PRINT_ENABLE_FILTER(DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL);
+    DBG_PRINT_ENABLE_FILTER(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL);
+
+#if DBG
+    DBG_PRINT_ENABLE_FILTER(DPFLTR_DEFAULT_ID, DPFLTR_ERROR_LEVEL);
+    DBG_PRINT_ENABLE_FILTER(DPFLTR_DEFAULT_ID, DPFLTR_WARNING_LEVEL);
+    DBG_PRINT_ENABLE_FILTER(DPFLTR_DEFAULT_ID, DPFLTR_TRACE_LEVEL);
+    DBG_PRINT_ENABLE_FILTER(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL);
+#endif // DBG
+}
+
+#endif  // _COMMON_DBG_PRINT_H
diff --git a/src/common/high.h b/src/common/high.h
new file mode 100644 (file)
index 0000000..42fbcc7
--- /dev/null
@@ -0,0 +1,93 @@
+/* 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 _COMMON_HIGH_H
+#define _COMMON_HIGH_H
+
+#include <ntddk.h>
+
+#pragma warning(disable:4127)   // conditional expression is constant
+
+typedef LONG    HIGH_LOCK, *PHIGH_LOCK;
+
+#define LOCK_MAGIC  0xFEEDFACE
+
+static FORCEINLINE
+__drv_maxIRQL(HIGH_LEVEL)
+__drv_raisesIRQL(HIGH_LEVEL)
+__drv_savesIRQL
+KIRQL
+__AcquireHighLock(
+    IN  PHIGH_LOCK  Lock
+    )
+{
+    KIRQL           Irql;
+
+    KeRaiseIrql(HIGH_LEVEL, &Irql);
+
+    while (InterlockedCompareExchange(Lock, LOCK_MAGIC, 0) != 0)
+        _mm_pause();
+
+    KeMemoryBarrier();
+
+    return Irql;
+}
+
+#define AcquireHighLock(_Lock, _Irql)               \
+        do {                                        \
+            *(_Irql) = __AcquireHighLock(_Lock);    \
+        } while (FALSE)
+
+static FORCEINLINE
+__drv_maxIRQL(HIGH_LEVEL)
+__drv_requiresIRQL(HIGH_LEVEL)
+VOID
+ReleaseHighLock(
+    IN  PHIGH_LOCK                  Lock,
+    IN  __drv_restoresIRQL KIRQL    Irql
+    )
+{
+    KeMemoryBarrier();
+
+    InterlockedExchange(Lock, 0);
+    KeLowerIrql(Irql);
+}
+
+static FORCEINLINE
+VOID
+InitializeHighLock(
+    IN  PHIGH_LOCK  Lock
+    )
+{
+    RtlZeroMemory(&Lock, sizeof (HIGH_LOCK));
+}
+
+#endif  // _COMMON_HIGH_H
diff --git a/src/common/mutex.h b/src/common/mutex.h
new file mode 100644 (file)
index 0000000..54504bc
--- /dev/null
@@ -0,0 +1,82 @@
+/* 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 _COMMON_MUTEX_H
+#define _COMMON_MUTEX_H
+
+#include <ntddk.h>
+
+#include "assert.h"
+
+typedef struct _MUTEX {
+    PKTHREAD    Owner;
+    KEVENT      Event;
+} MUTEX, *PMUTEX;
+
+static FORCEINLINE VOID
+InitializeMutex(
+    IN  PMUTEX  Mutex
+    )
+{
+    RtlZeroMemory(Mutex, sizeof (MUTEX));
+
+    KeInitializeEvent(&Mutex->Event, SynchronizationEvent, TRUE);
+}
+
+static FORCEINLINE VOID
+__drv_maxIRQL(PASSIVE_LEVEL)
+AcquireMutex(
+    IN  PMUTEX  Mutex
+    )
+{
+    (VOID) KeWaitForSingleObject(&Mutex->Event,
+                                 Executive,
+                                 KernelMode,
+                                 FALSE,
+                                 NULL);
+
+    ASSERT3P(Mutex->Owner, ==, NULL);
+    Mutex->Owner = KeGetCurrentThread();
+}
+
+static FORCEINLINE VOID
+__drv_maxIRQL(PASSIVE_LEVEL)
+ReleaseMutex(
+    IN  PMUTEX  Mutex
+    )
+{
+    ASSERT3P(Mutex->Owner, ==, KeGetCurrentThread());
+    Mutex->Owner = NULL;
+
+    KeSetEvent(&Mutex->Event, IO_NO_INCREMENT, FALSE);
+}
+
+#endif  // _COMMON_MUTEX_H
diff --git a/src/common/names.h b/src/common/names.h
new file mode 100644 (file)
index 0000000..a4d64ae
--- /dev/null
@@ -0,0 +1,336 @@
+/* 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 _COMMON_NAMES_H_
+#define _COMMON_NAMES_H_
+
+#include <ntddk.h>
+
+static FORCEINLINE const CHAR *
+PowerTypeName(
+    IN  POWER_STATE_TYPE    Type
+    )
+{
+#define _POWER_TYPE_NAME(_Type) \
+        case _Type:             \
+            return #_Type;
+
+    switch (Type) {
+    _POWER_TYPE_NAME(SystemPowerState);
+    _POWER_TYPE_NAME(DevicePowerState);
+    default:
+        break;
+    }
+
+    return ("UNKNOWN");
+#undef  _POWER_ACTION_NAME
+}
+
+static FORCEINLINE const CHAR *
+PowerSystemStateName(
+    IN  SYSTEM_POWER_STATE State
+    )
+{
+#define _POWER_SYSTEM_STATE_NAME(_State)    \
+        case PowerSystem ## _State:         \
+            return #_State;
+
+    switch (State) {
+    _POWER_SYSTEM_STATE_NAME(Unspecified);
+    _POWER_SYSTEM_STATE_NAME(Working);
+    _POWER_SYSTEM_STATE_NAME(Sleeping1);
+    _POWER_SYSTEM_STATE_NAME(Sleeping2);
+    _POWER_SYSTEM_STATE_NAME(Sleeping3);
+    _POWER_SYSTEM_STATE_NAME(Hibernate);
+    _POWER_SYSTEM_STATE_NAME(Shutdown);
+    _POWER_SYSTEM_STATE_NAME(Maximum);
+    default:
+        break;
+    }
+
+    return ("UNKNOWN");
+#undef  _POWER_SYSTEM_STATE_NAME
+}
+
+static FORCEINLINE const CHAR *
+PowerDeviceStateName(
+    IN  DEVICE_POWER_STATE State
+    )
+{
+#define _POWER_DEVICE_STATE_NAME(_State)    \
+        case PowerDevice ## _State:         \
+            return #_State;
+
+    switch (State) {
+    _POWER_DEVICE_STATE_NAME(Unspecified);
+    _POWER_DEVICE_STATE_NAME(D0);
+    _POWER_DEVICE_STATE_NAME(D1);
+    _POWER_DEVICE_STATE_NAME(D2);
+    _POWER_DEVICE_STATE_NAME(D3);
+    _POWER_DEVICE_STATE_NAME(Maximum);
+    default:
+        break;
+    }
+
+    return ("UNKNOWN");
+#undef  _POWER_DEVICE_STATE_NAME
+}
+
+static FORCEINLINE const CHAR *
+PowerActionName(
+    IN  POWER_ACTION    Type
+    )
+{
+#define _POWER_ACTION_NAME(_Type)   \
+        case PowerAction ## _Type:  \
+            return #_Type;
+
+    switch (Type) {
+    _POWER_ACTION_NAME(None);
+    _POWER_ACTION_NAME(Reserved);
+    _POWER_ACTION_NAME(Sleep);
+    _POWER_ACTION_NAME(Hibernate);
+    _POWER_ACTION_NAME(Shutdown);
+    _POWER_ACTION_NAME(ShutdownReset);
+    _POWER_ACTION_NAME(ShutdownOff);
+    _POWER_ACTION_NAME(WarmEject);
+    default:
+        break;
+    }
+
+    return ("UNKNOWN");
+#undef  _POWER_ACTION_NAME
+}
+
+static FORCEINLINE const CHAR *
+PowerMinorFunctionName(
+    IN  ULONG   MinorFunction
+    )
+{
+#define _POWER_MINOR_FUNCTION_NAME(_Function)   \
+    case IRP_MN_ ## _Function:                  \
+        return #_Function;
+
+    switch (MinorFunction) {
+    _POWER_MINOR_FUNCTION_NAME(WAIT_WAKE);
+    _POWER_MINOR_FUNCTION_NAME(POWER_SEQUENCE);
+    _POWER_MINOR_FUNCTION_NAME(SET_POWER);
+    _POWER_MINOR_FUNCTION_NAME(QUERY_POWER);
+
+    default:
+        return "UNKNOWN";
+    }
+
+#undef  _POWER_MINOR_FUNCTION_NAME
+}
+
+static FORCEINLINE const CHAR *
+PnpMinorFunctionName(
+    IN  ULONG   Function
+    )
+{
+#define _PNP_MINOR_FUNCTION_NAME(_Function) \
+    case IRP_MN_ ## _Function:              \
+        return #_Function;
+
+    switch (Function) {
+    _PNP_MINOR_FUNCTION_NAME(START_DEVICE);
+    _PNP_MINOR_FUNCTION_NAME(QUERY_REMOVE_DEVICE);
+    _PNP_MINOR_FUNCTION_NAME(REMOVE_DEVICE);
+    _PNP_MINOR_FUNCTION_NAME(CANCEL_REMOVE_DEVICE);
+    _PNP_MINOR_FUNCTION_NAME(STOP_DEVICE);
+    _PNP_MINOR_FUNCTION_NAME(QUERY_STOP_DEVICE);
+    _PNP_MINOR_FUNCTION_NAME(CANCEL_STOP_DEVICE);
+    _PNP_MINOR_FUNCTION_NAME(QUERY_DEVICE_RELATIONS);
+    _PNP_MINOR_FUNCTION_NAME(QUERY_INTERFACE);
+    _PNP_MINOR_FUNCTION_NAME(QUERY_CAPABILITIES);
+    _PNP_MINOR_FUNCTION_NAME(QUERY_RESOURCES);
+    _PNP_MINOR_FUNCTION_NAME(QUERY_RESOURCE_REQUIREMENTS);
+    _PNP_MINOR_FUNCTION_NAME(QUERY_DEVICE_TEXT);
+    _PNP_MINOR_FUNCTION_NAME(FILTER_RESOURCE_REQUIREMENTS);
+    _PNP_MINOR_FUNCTION_NAME(READ_CONFIG);
+    _PNP_MINOR_FUNCTION_NAME(WRITE_CONFIG);
+    _PNP_MINOR_FUNCTION_NAME(EJECT);
+    _PNP_MINOR_FUNCTION_NAME(SET_LOCK);
+    _PNP_MINOR_FUNCTION_NAME(QUERY_ID);
+    _PNP_MINOR_FUNCTION_NAME(QUERY_PNP_DEVICE_STATE);
+    _PNP_MINOR_FUNCTION_NAME(QUERY_BUS_INFORMATION);
+    _PNP_MINOR_FUNCTION_NAME(DEVICE_USAGE_NOTIFICATION);
+    _PNP_MINOR_FUNCTION_NAME(SURPRISE_REMOVAL);
+    _PNP_MINOR_FUNCTION_NAME(QUERY_LEGACY_BUS_INFORMATION);
+    default:
+        break;
+    }
+
+    return "UNKNOWN";
+
+#undef  _PNP_MINOR_FUNCTION_NAME
+}
+
+static FORCEINLINE const CHAR *
+PartialResourceDescriptorTypeName(
+    IN  UCHAR   Type
+    )
+{
+#define _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(_Type)   \
+    case CmResourceType ## _Type:                       \
+        return #_Type;
+
+    switch (Type) {
+    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Null);
+    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Port);
+    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Interrupt);
+    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Memory);
+    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Dma);
+    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(DeviceSpecific);
+    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(BusNumber);
+    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(MemoryLarge);
+    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(ConfigData);
+    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(DevicePrivate);
+    default:
+        break;
+    }
+
+    return "UNKNOWN";
+
+#undef  _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME
+}
+
+static FORCEINLINE const CHAR *
+DeviceUsageTypeName(
+    IN  DEVICE_USAGE_NOTIFICATION_TYPE  Type
+    )
+{
+#define _DEVICE_USAGE_TYPE_NAME(_Type)  \
+    case DeviceUsageType ## _Type:      \
+        return #_Type;
+
+    switch (Type) {
+    _DEVICE_USAGE_TYPE_NAME(Paging);
+    _DEVICE_USAGE_TYPE_NAME(Hibernation);
+    _DEVICE_USAGE_TYPE_NAME(DumpFile);
+    default:
+        break;
+    }
+
+    return "UNKNOWN";
+
+#undef  _DEVICE_USAGE_TYPE_NAME
+}
+
+static FORCEINLINE const CHAR *
+InterfaceTypeName(
+    IN  INTERFACE_TYPE  Type
+    )
+{
+#define _INTERFACE_TYPE_NAME(_Type) \
+    case _Type:                     \
+        return #_Type;
+
+    switch (Type) {
+    _INTERFACE_TYPE_NAME(InterfaceTypeUndefined);
+    _INTERFACE_TYPE_NAME(Internal);
+    _INTERFACE_TYPE_NAME(Isa);
+    _INTERFACE_TYPE_NAME(Eisa);
+    _INTERFACE_TYPE_NAME(MicroChannel);
+    _INTERFACE_TYPE_NAME(TurboChannel);
+    _INTERFACE_TYPE_NAME(PCIBus);
+    _INTERFACE_TYPE_NAME(VMEBus);
+    _INTERFACE_TYPE_NAME(NuBus);
+    _INTERFACE_TYPE_NAME(PCMCIABus);
+    _INTERFACE_TYPE_NAME(CBus);
+    _INTERFACE_TYPE_NAME(MPIBus);
+    _INTERFACE_TYPE_NAME(MPSABus);
+    _INTERFACE_TYPE_NAME(ProcessorInternal);
+    _INTERFACE_TYPE_NAME(InternalPowerBus);
+    _INTERFACE_TYPE_NAME(PNPISABus);
+    _INTERFACE_TYPE_NAME(PNPBus);
+    _INTERFACE_TYPE_NAME(Vmcs);
+    _INTERFACE_TYPE_NAME(ACPIBus);
+    default:
+        break;
+    }
+
+    return "UNKNOWN";
+
+#undef  _INTERFACE_TYPE_NAME
+}
+
+static FORCEINLINE const CHAR *
+DmaWidthName(
+    IN  DMA_WIDTH   Width
+    )
+{
+#define _DMA_WIDTH_NAME(_Width) \
+    case Width ## _Width:       \
+        return #_Width;
+
+    switch (Width) {
+    _DMA_WIDTH_NAME(8Bits);
+    _DMA_WIDTH_NAME(16Bits);
+    _DMA_WIDTH_NAME(32Bits);
+    _DMA_WIDTH_NAME(64Bits);
+    _DMA_WIDTH_NAME(NoWrap);
+    default:
+        break;
+    }
+
+    return "UNKNOWN";
+
+#undef  _DMA_WIDTH_NAME
+}
+
+static FORCEINLINE const CHAR *
+DmaSpeedName(
+    IN  DMA_SPEED   Speed
+    )
+{
+#define _DMA_SPEED_NAME(_Speed) \
+    case _Speed:                \
+        return #_Speed;
+
+    switch (Speed) {
+    _DMA_SPEED_NAME(Compatible);
+    _DMA_SPEED_NAME(TypeA);
+    _DMA_SPEED_NAME(TypeB);
+    _DMA_SPEED_NAME(TypeC);
+    _DMA_SPEED_NAME(TypeF);
+    _DMA_SPEED_NAME(MaximumDmaSpeed);
+    default:
+        break;
+    }
+
+    return "UNKNOWN";
+
+#undef  _DMA_SPEED_NAME
+}
+
+#endif // _COMMON_NAMES_H_
diff --git a/src/common/registry.c b/src/common/registry.c
new file mode 100644 (file)
index 0000000..6ec0f6a
--- /dev/null
@@ -0,0 +1,1096 @@
+/* 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
+RegistryOpenServiceKey(
+    IN  ACCESS_MASK     DesiredAccess,
+    OUT PHANDLE         Key
+    )
+{
+    OBJECT_ATTRIBUTES   Attributes;
+    NTSTATUS            status;
+
+    InitializeObjectAttributes(&Attributes,
+                               &RegistryPath,
+                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+                               NULL,
+                               NULL);
+
+    status = ZwOpenKey(Key,
+                       DesiredAccess,
+                       &Attributes);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    return STATUS_SUCCESS;
+
+fail1:
+    return status;
+}
+
+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
+    )
+{
+    NTSTATUS            status;
+
+    status = IoOpenDeviceRegistryKey(DeviceObject,
+                                     PLUGPLAY_REGKEY_DEVICE,
+                                     DesiredAccess,
+                                     Key);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    return STATUS_SUCCESS;
+
+fail1:
+    return status;
+}
+
+NTSTATUS
+RegistryOpenSubKey(
+    IN  PHANDLE         Key,
+    IN  PCHAR           Name,
+    IN  ACCESS_MASK     DesiredAccess,
+    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 = ZwOpenKey(SubKey,
+                       DesiredAccess,
+                       &Attributes);
+    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
+    )
+{
+    ANSI_STRING         Ansi;
+    UNICODE_STRING      Unicode;
+    OBJECT_ATTRIBUTES   Attributes;
+    HANDLE              SubKey;
+    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,
+                         REG_OPTION_NON_VOLATILE,
+                         NULL
+                         );
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    ZwClose(SubKey);
+
+    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;
+    OBJECT_ATTRIBUTES   Attributes;
+    HANDLE              SubKey;
+    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 = ZwOpenKey(&SubKey,
+                       KEY_ALL_ACCESS,
+                       &Attributes);
+    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 = 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
+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
+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
+RegistryQuerySystemStartOption(
+    IN  PCHAR                       Prefix,
+    OUT PANSI_STRING                *Value
+    )
+{
+    UNICODE_STRING                  Unicode;
+    OBJECT_ATTRIBUTES               Attributes;
+    HANDLE                          Key;
+    PKEY_VALUE_PARTIAL_INFORMATION  Partial;
+    ULONG                           Size;
+    ANSI_STRING                     Ansi;
+    PWCHAR                          Option;
+    PWCHAR                          Context;
+    NTSTATUS                        status;
+
+    RtlInitUnicodeString(&Unicode, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control");
+    
+    InitializeObjectAttributes(&Attributes,
+                               &Unicode,
+                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+                               NULL,
+                               NULL);
+
+    status = ZwOpenKey(&Key,
+                       KEY_READ,
+                       &Attributes);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    RtlInitUnicodeString(&Unicode, L"SystemStartOptions");
+
+    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_SZ)
+        goto fail5;
+
+    RtlInitAnsiString(&Ansi, Prefix);
+
+    status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
+    if (!NT_SUCCESS(status))
+        goto fail6;
+
+    // SystemStartOptions is a space separated list of options.
+    // Scan it looking for the one we want.
+    Option = __wcstok_r((PWCHAR)Partial->Data, L" ", &Context);
+    if (wcsncmp(Option, Unicode.Buffer, Unicode.Length / sizeof (WCHAR)) == 0)
+        goto found;
+
+    while ((Option = __wcstok_r(NULL, L" ", &Context)) != NULL)
+        if (wcsncmp(Option, Unicode.Buffer, Unicode.Length / sizeof (WCHAR)) == 0)
+            goto found;
+
+    status = STATUS_OBJECT_NAME_NOT_FOUND;
+    goto fail7;
+
+found:
+    *Value = RegistrySzToAnsi(Option);
+
+    status = STATUS_NO_MEMORY;
+    if (*Value == NULL)
+        goto fail8;
+
+    __RegistryFree(Partial);
+
+    RtlFreeUnicodeString(&Unicode);
+
+    ZwClose(Key);
+
+    return STATUS_SUCCESS;
+
+fail8:
+fail7:
+    RtlFreeUnicodeString(&Unicode);
+
+fail6:
+fail5:
+fail4:
+    __RegistryFree(Partial);
+
+fail3:
+fail2:
+    ZwClose(Key);
+
+fail1:
+    return status;
+}
+
+static PKEY_VALUE_PARTIAL_INFORMATION
+RegistryAnsiToSz(
+    PANSI_STRING                    Ansi
+    )
+{
+    ULONG                           Length;
+    PKEY_VALUE_PARTIAL_INFORMATION  Partial;
+    UNICODE_STRING                  Unicode;
+    NTSTATUS                        status;
+
+    Length = Ansi->Length + 1;
+    Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) +
+                                 Length * sizeof (WCHAR));
+
+    status = STATUS_NO_MEMORY;
+    if (Partial == NULL)
+        goto fail1;
+
+    Partial->TitleIndex = 0;
+    Partial->Type = REG_SZ;
+    Partial->DataLength = Length * sizeof (WCHAR);
+
+    Unicode.MaximumLength = (UCHAR)Partial->DataLength;
+    Unicode.Buffer = (PWCHAR)Partial->Data;
+    Unicode.Length = 0;
+
+    status = RtlAnsiStringToUnicodeString(&Unicode, Ansi, FALSE);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    return Partial;
+
+fail2:
+    __RegistryFree(Partial);
+
+fail1:
+    return NULL;
+}
+
+static PKEY_VALUE_PARTIAL_INFORMATION
+RegistryAnsiToMultiSz(
+    PANSI_STRING                    Ansi
+    )
+{
+    ULONG                           Length;
+    ULONG                           Index;
+    PKEY_VALUE_PARTIAL_INFORMATION  Partial;
+    UNICODE_STRING                  Unicode;
+    NTSTATUS                        status;
+
+    Length = 1;
+    for (Index = 0; Ansi[Index].Buffer != NULL; Index++)
+        Length += Ansi[Index].Length + 1;
+
+    Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) +
+                               Length * sizeof (WCHAR));
+
+    status = STATUS_NO_MEMORY;
+    if (Partial == NULL)
+        goto fail1;
+
+    Partial->TitleIndex = 0;
+    Partial->Type = REG_MULTI_SZ;
+    Partial->DataLength = Length * sizeof (WCHAR);
+
+    Unicode.MaximumLength = (USHORT)Partial->DataLength;
+    Unicode.Buffer = (PWCHAR)Partial->Data;
+    Unicode.Length = 0;
+
+    for (Index = 0; Ansi[Index].Buffer != NULL; Index++) {
+        status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi[Index], FALSE);
+        if (!NT_SUCCESS(status))
+            goto fail2;
+
+        Length = Unicode.Length / sizeof (WCHAR);
+
+        ASSERT3U(Unicode.MaximumLength, >=, (Length + 1) * sizeof (WCHAR));
+        Unicode.MaximumLength -= (USHORT)((Length + 1) * sizeof (WCHAR));
+        Unicode.Buffer += Length + 1;
+        Unicode.Length = 0;
+    }
+    *Unicode.Buffer = L'\0';
+
+    return Partial;
+
+fail2:
+    __RegistryFree(Partial);
+
+fail1:
+    return NULL;
+}
+
+NTSTATUS
+RegistryUpdateSzValue(
+    IN  HANDLE                      Key,
+    IN  PCHAR                       Name,
+    IN  ULONG                       Type,
+    ...
+    )
+{
+    ANSI_STRING                     Ansi;
+    UNICODE_STRING                  Unicode;
+    va_list                         Arguments;
+    PKEY_VALUE_PARTIAL_INFORMATION  Partial;
+    NTSTATUS                        status;
+
+    RtlInitAnsiString(&Ansi, Name);
+
+    status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+        
+    va_start(Arguments, Type);
+    switch (Type) {
+    case REG_SZ: {
+        PANSI_STRING    Argument;
+
+        Argument = va_arg(Arguments, PANSI_STRING);
+
+        status = STATUS_NO_MEMORY;
+        Partial = RegistryAnsiToSz(Argument);        
+        break;
+    }
+    case REG_MULTI_SZ: {
+        PANSI_STRING    Argument;
+
+        Argument = va_arg(Arguments, PANSI_STRING);
+
+        status = STATUS_NO_MEMORY;
+        Partial = RegistryAnsiToMultiSz(Argument);        
+        break;
+    }
+    default:
+        status = STATUS_INVALID_PARAMETER;
+        Partial = NULL;
+        break;
+    }
+    va_end(Arguments);
+
+    if (Partial == NULL)
+        goto fail2;
+
+    status = ZwSetValueKey(Key,
+                           &Unicode,
+                           Partial->TitleIndex,
+                           Partial->Type,
+                           Partial->Data,
+                           Partial->DataLength);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    __RegistryFree(Partial);
+
+    RtlFreeUnicodeString(&Unicode);
+
+    return STATUS_SUCCESS;
+
+fail3:
+    __RegistryFree(Partial);
+
+fail2:
+    RtlFreeUnicodeString(&Unicode);
+
+fail1:
+    return status;
+}
+
+VOID
+RegistryFreeSzValue(
+    IN  PANSI_STRING    Array
+    )
+{
+    ULONG               Index;
+
+    if (Array == NULL)
+        return;
+
+    for (Index = 0; Array[Index].Buffer != NULL; Index++)
+        __RegistryFree(Array[Index].Buffer);
+
+    __RegistryFree(Array);
+}
+
+VOID
+RegistryCloseKey(
+    IN  HANDLE  Key
+    )
+{
+    ZwClose(Key);
+}
diff --git a/src/common/registry.h b/src/common/registry.h
new file mode 100644 (file)
index 0000000..8440774
--- /dev/null
@@ -0,0 +1,146 @@
+/* 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 _COMMON_REGISTRY_H
+#define _COMMON_REGISTRY_H
+
+#include <ntddk.h>
+
+extern NTSTATUS
+RegistryInitialize(
+    IN PUNICODE_STRING  Path
+    );
+
+extern VOID
+RegistryTeardown(
+    VOID
+    );
+
+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
+    );
+
+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
+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
+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  // _COMMON_REGISTRY_H
diff --git a/src/common/util.h b/src/common/util.h
new file mode 100644 (file)
index 0000000..4665e36
--- /dev/null
@@ -0,0 +1,343 @@
+/* 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 _COMMON_UTIL_H
+#define _COMMON_UTIL_H
+
+#include <ntddk.h>
+
+#include "assert.h"
+
+#define        P2ROUNDUP(_x, _a)   \
+        (-(-(_x) & -(_a)))
+
+static FORCEINLINE LONG
+__ffs(
+    IN  unsigned long long  mask
+    )
+{
+    unsigned char           *array = (unsigned char *)&mask;
+    unsigned int            byte;
+    unsigned int            bit;
+    unsigned char           val;
+
+    val = 0;
+
+    byte = 0;
+    while (byte < 8) {
+        val = array[byte];
+
+        if (val != 0)
+            break;
+
+        byte++;
+    }
+    if (byte == 8)
+        return -1;
+
+    bit = 0;
+    while (bit < 8) {
+        if (val & 0x01)
+            break;
+
+        val >>= 1;
+        bit++;
+    }
+
+    return (byte * 8) + bit;
+}
+
+#define __ffu(_mask)  \
+        __ffs(~(_mask))
+
+static FORCEINLINE VOID
+__CpuId(
+    IN  ULONG   Leaf,
+    OUT PULONG  EAX OPTIONAL,
+    OUT PULONG  EBX OPTIONAL,
+    OUT PULONG  ECX OPTIONAL,
+    OUT PULONG  EDX OPTIONAL
+    )
+{
+    ULONG       Value[4] = {0};
+
+    __cpuid(Value, Leaf);
+
+    if (EAX)
+        *EAX = Value[0];
+
+    if (EBX)
+        *EBX = Value[1];
+
+    if (ECX)
+        *ECX = Value[2];
+
+    if (EDX)
+        *EDX = Value[3];
+}
+
+static FORCEINLINE LONG
+__InterlockedAdd(
+    IN  LONG    *Value,
+    IN  LONG    Delta
+    )
+{
+    LONG        New;
+    LONG        Old;
+
+    do {
+        Old = *Value;
+        New = Old + Delta;
+    } while (InterlockedCompareExchange(Value, New, Old) != Old);
+
+    return New;
+}
+
+static FORCEINLINE LONG
+__InterlockedSubtract(
+    IN  LONG    *Value,
+    IN  LONG    Delta
+    )
+{
+    LONG        New;
+    LONG        Old;
+
+    do {
+        Old = *Value;
+        New = Old - Delta;
+    } while (InterlockedCompareExchange(Value, New, Old) != Old);
+
+    return New;
+}
+
+typedef struct _NON_PAGED_BUFFER_HEADER {
+    SIZE_T  Length;
+    ULONG   Tag;
+} NON_PAGED_BUFFER_HEADER, *PNON_PAGED_BUFFER_HEADER;
+
+typedef struct _NON_PAGED_BUFFER_TRAILER {
+    ULONG   Tag;
+} NON_PAGED_BUFFER_TRAILER, *PNON_PAGED_BUFFER_TRAILER;
+
+static FORCEINLINE PVOID
+__AllocateNonPagedPoolWithTag(
+    IN  SIZE_T                  Length,
+    IN  ULONG                   Tag
+    )
+{
+    PUCHAR                      Buffer;
+    PNON_PAGED_BUFFER_HEADER    Header;
+    PNON_PAGED_BUFFER_TRAILER   Trailer;
+
+    ASSERT(Length != 0);
+
+    Buffer = ExAllocatePoolWithTag(NonPagedPool,
+                                   sizeof (NON_PAGED_BUFFER_HEADER) +
+                                   Length +
+                                   sizeof (NON_PAGED_BUFFER_TRAILER),
+                                   Tag);
+    if (Buffer == NULL)
+        goto done;
+
+    RtlZeroMemory(Buffer, 
+                  sizeof (NON_PAGED_BUFFER_HEADER) +
+                  Length +
+                  sizeof (NON_PAGED_BUFFER_TRAILER));
+
+    Header = (PNON_PAGED_BUFFER_HEADER)Buffer;
+    Header->Length = Length;
+    Header->Tag = Tag;
+
+    Buffer += sizeof (NON_PAGED_BUFFER_HEADER);
+
+    Trailer = (PNON_PAGED_BUFFER_TRAILER)(Buffer + Length);
+    Trailer->Tag = Tag;
+
+done:
+    return Buffer;
+}
+
+static FORCEINLINE VOID
+__FreePoolWithTag(
+    IN  PVOID                   _Buffer,
+    IN  ULONG                   Tag
+    )
+{
+    PUCHAR                      Buffer = _Buffer;
+    SIZE_T                      Length;
+    PNON_PAGED_BUFFER_HEADER    Header;
+    PNON_PAGED_BUFFER_TRAILER   Trailer;
+
+    ASSERT(Buffer != NULL);
+
+    Buffer -= sizeof (NON_PAGED_BUFFER_HEADER);
+
+    Header = (PNON_PAGED_BUFFER_HEADER)Buffer;
+    ASSERT3U(Tag, ==, Header->Tag);
+    Length = Header->Length;
+
+    Buffer += sizeof (NON_PAGED_BUFFER_HEADER);
+
+    Trailer = (PNON_PAGED_BUFFER_TRAILER)(Buffer + Length);
+    ASSERT3U(Tag, ==, Trailer->Tag);
+
+    Buffer -= sizeof (NON_PAGED_BUFFER_HEADER);
+
+    RtlFillMemory(Buffer, 
+                  sizeof (NON_PAGED_BUFFER_HEADER) +
+                  Length +
+                  sizeof (NON_PAGED_BUFFER_TRAILER),
+                  0xAA);
+
+    ExFreePoolWithTag(Buffer, Tag);
+}
+
+static FORCEINLINE PMDL
+__AllocatePage(
+    VOID
+    )
+{
+    PHYSICAL_ADDRESS    LowAddress;
+    PHYSICAL_ADDRESS    HighAddress;
+    LARGE_INTEGER       SkipBytes;
+    SIZE_T              TotalBytes;
+    PMDL                Mdl;
+    PUCHAR              MdlMappedSystemVa;
+    NTSTATUS            status;
+
+    LowAddress.QuadPart = 0ull;
+    HighAddress.QuadPart = ~0ull;
+    SkipBytes.QuadPart = 0ull;
+    TotalBytes = (SIZE_T)PAGE_SIZE;
+
+    Mdl = MmAllocatePagesForMdlEx(LowAddress,
+                                  HighAddress,
+                                  SkipBytes,
+                                  TotalBytes,
+                                  MmCached,
+                                  0);
+
+    status = STATUS_NO_MEMORY;
+    if (Mdl == NULL)
+        goto fail1;
+
+    ASSERT((Mdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA |
+                             MDL_PARTIAL_HAS_BEEN_MAPPED |
+                             MDL_PARTIAL |
+                             MDL_PARENT_MAPPED_SYSTEM_VA |
+                             MDL_SOURCE_IS_NONPAGED_POOL |
+                             MDL_IO_SPACE)) == 0);
+
+    MdlMappedSystemVa = MmMapLockedPagesSpecifyCache(Mdl,
+                                                     KernelMode,
+                                                                            MmCached,   
+                                                                            NULL,
+                                                                            FALSE,
+                                                                            NormalPagePriority);
+
+    status = STATUS_UNSUCCESSFUL;
+    if (MdlMappedSystemVa == NULL)
+        goto fail2;
+
+    ASSERT3P(MdlMappedSystemVa, ==, Mdl->MappedSystemVa);
+
+    RtlZeroMemory(MdlMappedSystemVa, PAGE_SIZE);
+
+    return Mdl;
+
+fail2:
+    Error("fail2\n");
+
+    MmFreePagesFromMdl(Mdl);
+    ExFreePool(Mdl);
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return NULL;
+}
+
+static FORCEINLINE VOID
+__FreePage(
+    IN PMDL    Mdl
+    )
+{
+    PUCHAR     MdlMappedSystemVa;
+
+    ASSERT(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA);
+    MdlMappedSystemVa = Mdl->MappedSystemVa;
+
+    RtlFillMemory(MdlMappedSystemVa, PAGE_SIZE, 0xAA);
+    
+    MmUnmapLockedPages(MdlMappedSystemVa, Mdl);
+
+    MmFreePagesFromMdl(Mdl);
+}
+
+static FORCEINLINE PWCHAR
+__wcstok_r(
+    IN      PWCHAR  Buffer,
+    IN      PWCHAR  Delimiter,
+    IN OUT  PWCHAR  *Context
+    )
+{
+    PWCHAR          Token;
+    PWCHAR          End;
+
+    if (Buffer != NULL)
+        *Context = Buffer;
+
+    Token = *Context;
+
+    if (Token == NULL)
+        return NULL;
+
+    while (*Token != L'\0' &&
+           wcschr(Delimiter, *Token) != NULL)
+        Token++;
+
+    if (*Token == L'\0')
+        return NULL;
+
+    End = Token + 1;
+    while (*End != L'\0' &&
+           wcschr(Delimiter, *End) == NULL)
+        End++;
+
+    if (*End != L'\0')
+        *End++ = L'\0';
+
+    *Context = End;
+
+    return Token;
+}
+
+#endif  // _COMMON_UTIL_H
diff --git a/src/xen/assert.h b/src/xen/assert.h
deleted file mode 100644 (file)
index 0871498..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/* 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 _XEN_ASSERT_H
-#define _XEN_ASSERT_H
-
-#include <ntddk.h>
-
-#include "log.h"
-
-static FORCEINLINE VOID
-__BugCheck(
-    IN  ULONG       Code,
-    IN  ULONG_PTR   Parameter1,
-    IN  ULONG_PTR   Parameter2,
-    IN  ULONG_PTR   Parameter3,
-    IN  ULONG_PTR   Parameter4
-    )
-{
-#pragma prefast(suppress:28159)
-    KeBugCheckEx(Code,
-                 Parameter1,
-                 Parameter2,
-                 Parameter3,
-                 Parameter4);
-}
-
-#define ASSERTION_FAILURE   0x0000DEAD
-
-#define BUG(_TEXT)                                              \
-        do {                                                    \
-            const CHAR  *_Text = (_TEXT);                       \
-            const CHAR  *_File = __FILE__;                      \
-            ULONG       _Line = __LINE__;                       \
-                                                                \
-            Error("BUG: " _TEXT "\n");                          \
-            __BugCheck(ASSERTION_FAILURE,                       \
-                       (ULONG_PTR)_Text,                        \
-                       (ULONG_PTR)_File,                        \
-                       (ULONG_PTR)_Line,                        \
-                       0);                                      \
-        } while (FALSE)
-
-#define BUG_ON(_EXP)                \
-        if (_EXP) BUG(#_EXP)
-
-#if DBG
-
-#define __NT_ASSERT(_EXP)                                       \
-        ((!(_EXP)) ?                                            \
-        (Error("ASSERTION FAILED: " #_EXP "\n"),                \
-         __annotation(L"Debug", L"AssertFail", L#_EXP),         \
-         DbgRaiseAssertionFailure(), FALSE) :                   \
-        TRUE)
-
-#define __ASSERT(_EXP)  __NT_ASSERT(_EXP)
-
-#else   // DBG
-
-#define __ASSERT(_EXP)  BUG_ON(!(_EXP))
-
-#endif  // DBG
-
-#undef  ASSERT
-
-#define ASSERT(_EXP)                    \
-        do {                            \
-            __ASSERT(_EXP);             \
-            __analysis_assume(_EXP);    \
-        } while (FALSE)
-
-#define ASSERT3U(_X, _OP, _Y)                       \
-        do {                                        \
-            ULONGLONG   _Lval = (ULONGLONG)(_X);    \
-            ULONGLONG   _Rval = (ULONGLONG)(_Y);    \
-            if (!(_Lval _OP _Rval)) {               \
-                Error("%s = %llu\n", #_X, _Lval);   \
-                Error("%s = %llu\n", #_Y, _Rval);   \
-                ASSERT(_X _OP _Y);                  \
-            }                                       \
-        } while (FALSE)
-
-#define ASSERT3S(_X, _OP, _Y)                       \
-        do {                                        \
-            LONGLONG    _Lval = (LONGLONG)(_X);     \
-            LONGLONG    _Rval = (LONGLONG)(_Y);     \
-            if (!(_Lval _OP _Rval)) {               \
-                Error("%s = %lld\n", #_X, _Lval);   \
-                Error("%s = %lld\n", #_Y, _Rval);   \
-                ASSERT(_X _OP _Y);                  \
-            }                                       \
-        } while (FALSE)
-
-#define ASSERT3P(_X, _OP, _Y)                       \
-        do {                                        \
-            PVOID   _Lval = (PVOID)(_X);            \
-            PVOID   _Rval = (PVOID)(_Y);            \
-            if (!(_Lval _OP _Rval)) {               \
-                Error("%s = %p\n", #_X, _Lval);     \
-                Error("%s = %p\n", #_Y, _Rval);     \
-                ASSERT(_X _OP _Y);                  \
-            }                                       \
-        } while (FALSE)
-
-#ifndef TEST_MEMORY
-#define TEST_MEMORY DBG
-#endif
-
-#if TEST_MEMORY
-
-static __inline BOOLEAN
-_IsZeroMemory(
-    IN  const PCHAR Caller,
-    IN  const PCHAR Name,
-    IN  PVOID       Buffer,
-    IN  ULONG       Length
-    )
-{
-    ULONG           Offset;
-
-    Offset = 0;
-    while (Offset < Length) {
-        if (*((PUCHAR)Buffer + Offset) != 0) {
-            Error("%s: non-zero byte in %s (0x%p+0x%x)\n", Caller, Name, Buffer, Offset);
-            return FALSE;
-        }
-        Offset++;
-    }
-
-    return TRUE;
-}
-
-#define IsZeroMemory(_Buffer, _Length) \
-        _IsZeroMemory(__FUNCTION__, #_Buffer, (_Buffer), (_Length))
-
-#else   // TEST_MEMORY
-
-#define IsZeroMemory(_Buffer, _Length)  TRUE
-
-#endif  // TEST_MEMORY
-
-#define IMPLY(_X, _Y)   (!(_X) || (_Y))
-#define EQUIV(_X, _Y)   (IMPLY((_X), (_Y)) && IMPLY((_Y), (_X)))
-
-#endif  // _XEN_ASSERT_H
-
diff --git a/src/xen/bug_check.c b/src/xen/bug_check.c
new file mode 100644 (file)
index 0000000..e924a4b
--- /dev/null
@@ -0,0 +1,1144 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, 
+ * with or without modification, are permitted provided 
+ * that the following conditions are met:
+ * 
+ * *   Redistributions of source code must retain the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer in the documentation and/or other 
+ *     materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE.
+ */
+
+#define XEN_API extern
+
+#include <ntddk.h>
+#include <xen.h>
+#include <bugcodes.h>
+
+#include "hypercall.h"
+#include "module.h"
+#include "log.h"
+#include "bug_check.h"
+#include "dbg_print.h"
+#include "assert.h"
+
+static KBUGCHECK_CALLBACK_RECORD BugCheckBugCheckCallbackRecord;
+
+VOID
+BugCheckTeardown(
+    VOID
+    )
+{
+    (VOID) KeDeregisterBugCheckCallback(&BugCheckBugCheckCallbackRecord);
+}
+
+#pragma warning(push)
+#pragma warning(disable: 6320) // Exception-filter expression is the constant EXCEPTION_EXECUTE_HANDLER. This might mask exceptions that were not intended to be handled.
+#pragma warning(disable: 6322) // Empty _except block.
+
+static DECLSPEC_NOINLINE VOID
+BugCheckDumpExceptionRecord(
+    IN  PEXCEPTION_RECORD   Exception
+    )
+{
+    __try {
+        while (Exception != NULL) {
+            ULONG   Index;
+
+            LogPrintf(LOG_LEVEL_CRITICAL,
+                      "%s|BUGCHECK: EXCEPTION (%p):\n",
+                      __MODULE__,
+                      Exception);
+            LogPrintf(LOG_LEVEL_CRITICAL,
+                      "%s|BUGCHECK: - Code = %08X\n",
+                      __MODULE__,
+                      Exception->ExceptionCode);
+            LogPrintf(LOG_LEVEL_CRITICAL,
+                      "%s|BUGCHECK: - Flags = %08X\n",
+                      __MODULE__,
+                      Exception->ExceptionFlags);
+            LogPrintf(LOG_LEVEL_CRITICAL,
+                      "%s|BUGCHECK: - Address = %p\n",
+                      __MODULE__,
+                      Exception->ExceptionAddress);
+
+            for (Index = 0; Index < Exception->NumberParameters; Index++)
+                LogPrintf(LOG_LEVEL_CRITICAL,
+                          "%s|BUGCHECK: - Parameter[%u] = %p\n", __MODULE__,
+                          Index,
+                          (PVOID)Exception->ExceptionInformation[Index]);
+
+            Exception = Exception->ExceptionRecord;
+        }
+    } __except (EXCEPTION_EXECUTE_HANDLER) {
+        // Nothing to to
+    }
+}
+
+#pragma warning(push)
+#pragma warning(disable:6262) // Uses more than 1024 bytes of stack
+
+#if defined(__i386__)
+static DECLSPEC_NOINLINE VOID
+BugCheckDumpContext(
+    IN  PCONTEXT    Context
+    )
+{
+    __try {
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: CONTEXT (%p):\n",
+                  __MODULE__,
+                  Context);
+
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - GS = %04X\n",
+                  __MODULE__,
+                  Context->SegGs);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - FS = %04X\n",
+                  __MODULE__,
+                  Context->SegFs);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - ES = %08X\n",
+                  __MODULE__,
+                  Context->SegEs);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - DS = %08X\n",
+                  __MODULE__,
+                  Context->SegDs);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - SS = %08X\n",
+                  __MODULE__,
+                  Context->SegSs);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - CS = %08X\n",
+                  __MODULE__,
+                  Context->SegCs);
+
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - EFLAGS = %08X\n",
+                  __MODULE__,
+                  Context->EFlags);
+
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - EDI = %08X\n",
+                  __MODULE__,
+                  Context->Edi);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - ESI = %08X\n",
+                  __MODULE__,
+                  Context->Esi);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - EBX = %08X\n",
+                  __MODULE__,
+                  Context->Ebx);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - EDX = %08X\n",
+                  __MODULE__,
+                  Context->Edx);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - ECX = %08X\n",
+                  __MODULE__,
+                  Context->Ecx);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - EAX = %08X\n",
+                  __MODULE__,
+                  Context->Eax);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - EBP = %08X\n",
+                  __MODULE__,
+                  Context->Ebp);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - EIP = %08X\n",
+                  __MODULE__,
+                  Context->Eip);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - ESP = %08X\n",
+                  __MODULE__,
+                  Context->Esp);
+    } __except (EXCEPTION_EXECUTE_HANDLER) {
+        // Nothing to to
+    }
+}
+
+static DECLSPEC_NOINLINE VOID
+BugCheckStackDump(
+    IN  PCONTEXT    Context
+    )
+{
+#define PARAMETER_COUNT     3
+#define MAXIMUM_ITERATIONS  20
+
+    __try {
+        ULONG_PTR   EBP;
+        ULONG       Iteration;
+
+        BugCheckDumpContext(Context);
+
+        EBP = (ULONG_PTR)Context->Ebp;
+
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: STACK:\n",
+                  __MODULE__);
+
+        for (Iteration = 0; Iteration < MAXIMUM_ITERATIONS; Iteration++) {
+            ULONG       NextEBP;
+            ULONG       EIP;
+            ULONG       Parameter[PARAMETER_COUNT] = {0};
+            ULONG       Index;
+            PCHAR       Name;
+            ULONG       Offset;
+
+            NextEBP = *(PULONG)EBP;
+            EIP = *(PULONG)(EBP + 4);
+
+            if (EIP == 0)
+                break;
+
+            Index = 0;
+            Offset = 8;
+            for (;;) {
+                if (EBP + Offset >= NextEBP)
+                    break;
+
+                if (Index == PARAMETER_COUNT)
+                    break;
+
+                Parameter[Index] = *(PULONG)(EBP + Offset);
+
+                Index += 1;
+                Offset += 4;
+            }
+
+            ModuleLookup(EIP, &Name, &Offset);
+
+            if (Name != NULL)
+                LogPrintf(LOG_LEVEL_CRITICAL,
+                          "%s|BUGCHECK: %08X: (%08X %08X %08X) %s + %p\n", __MODULE__,
+                          EBP,
+                          Parameter[0],
+                          Parameter[1],
+                          Parameter[2],
+                          Name,
+                          (PVOID)Offset);
+            else
+                LogPrintf(LOG_LEVEL_CRITICAL,
+                          "%s|BUGCHECK: %08X: (%08X %08X %08X) %p\n", __MODULE__,
+                          EBP,
+                          Parameter[0],
+                          Parameter[1],
+                          Parameter[2],
+                          (PVOID)EIP);
+
+            EBP = NextEBP;
+        }
+    } __except (EXCEPTION_EXECUTE_HANDLER) {
+        // End of stack
+    }
+
+#undef  MAXIMUM_ITERATIONS
+#undef  PARAMETER_COUNT
+}
+#elif defined(__x86_64__)
+static DECLSPEC_NOINLINE VOID
+BugCheckDumpContext(
+    IN  PCONTEXT    Context
+    )
+{
+    __try {
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: CONTEXT (%p):\n",
+                  __MODULE__,
+                  Context);
+
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - GS = %04X\n",
+                  __MODULE__,
+                  Context->SegGs);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - FS = %04X\n",
+                  __MODULE__,
+                  Context->SegFs);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - ES = %04X\n",
+                  __MODULE__,
+                  Context->SegEs);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - DS = %04X\n",
+                  __MODULE__,
+                  Context->SegDs);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - SS = %04X\n",
+                  __MODULE__,
+                  Context->SegSs);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - CS = %04X\n",
+                  __MODULE__,
+                  Context->SegCs);
+
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - EFLAGS = %08X\n",
+                  __MODULE__,
+                  Context->EFlags);
+
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - RDI = %016X\n",
+                  __MODULE__,
+                  Context->Rdi);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - RSI = %016X\n",
+                  __MODULE__,
+                  Context->Rsi);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - RBX = %016X\n",
+                  __MODULE__,
+                  Context->Rbx);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - RDX = %016X\n",
+                  __MODULE__,
+                  Context->Rdx);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - RCX = %016X\n",
+                  __MODULE__,
+                  Context->Rcx);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - RAX = %016X\n",
+                  __MODULE__,
+                  Context->Rax);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - RBP = %016X\n",
+                  __MODULE__,
+                  Context->Rbp);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - RIP = %016X\n",
+                  __MODULE__,
+                  Context->Rip);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - RSP = %016X\n",
+                  __MODULE__,
+                  Context->Rsp);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - R8 = %016X\n",
+                  __MODULE__,
+                  Context->R8);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - R9 = %016X\n",
+                  __MODULE__,
+                  Context->R9);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - R10 = %016X\n",
+                  __MODULE__,
+                  Context->R10);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - R11 = %016X\n",
+                  __MODULE__,
+                  Context->R11);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - R12 = %016X\n",
+                  __MODULE__,
+                  Context->R12);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - R13 = %016X\n",
+                  __MODULE__,
+                  Context->R13);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - R14 = %016X\n",
+                  __MODULE__,
+                  Context->R14);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - R15 = %016X\n",
+                  __MODULE__,
+                  Context->R15);
+    } __except (EXCEPTION_EXECUTE_HANDLER) {
+        // Nothing to to
+    }
+}
+
+typedef struct _RUNTIME_FUNCTION {
+    ULONG BeginAddress;
+    ULONG EndAddress;
+    ULONG UnwindData;
+} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
+
+#define UNWIND_HISTORY_TABLE_SIZE 12
+
+typedef struct _UNWIND_HISTORY_TABLE_ENTRY {
+        ULONG64 ImageBase;
+        PRUNTIME_FUNCTION FunctionEntry;
+} UNWIND_HISTORY_TABLE_ENTRY, *PUNWIND_HISTORY_TABLE_ENTRY;
+
+#define UNWIND_HISTORY_TABLE_NONE 0
+#define UNWIND_HISTORY_TABLE_GLOBAL 1
+#define UNWIND_HISTORY_TABLE_LOCAL 2
+
+typedef struct _UNWIND_HISTORY_TABLE {
+        ULONG Count;
+        UCHAR Search;
+        UCHAR RaiseStatusIndex;
+        BOOLEAN Unwind;
+        BOOLEAN Exception;
+        ULONG64 LowAddress;
+        ULONG64 HighAddress;
+        UNWIND_HISTORY_TABLE_ENTRY Entry[UNWIND_HISTORY_TABLE_SIZE];
+} UNWIND_HISTORY_TABLE, *PUNWIND_HISTORY_TABLE;
+
+extern PRUNTIME_FUNCTION
+RtlLookupFunctionEntry(
+    __in ULONG64 ControlPc,
+    __out PULONG64 ImageBase,
+    __inout_opt PUNWIND_HISTORY_TABLE HistoryTable OPTIONAL
+    );
+
+#pragma prefast(suppress:28301) // No annotations
+typedef EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE) (
+    __in struct _EXCEPTION_RECORD *ExceptionRecord,
+    __in PVOID EstablisherFrame,
+    __inout struct _CONTEXT *ContextRecord,
+    __inout PVOID DispatcherContext
+    );
+
+#pragma warning(push)
+#pragma warning(disable:4201) // nonstandard extension used : nameless struct/union
+
+typedef struct _KNONVOLATILE_CONTEXT_POINTERS {
+    union {
+        PM128A FloatingContext[16];
+        struct {
+            PM128A Xmm0;
+            PM128A Xmm1;
+            PM128A Xmm2;
+            PM128A Xmm3;
+            PM128A Xmm4;
+            PM128A Xmm5;
+            PM128A Xmm6;
+            PM128A Xmm7;
+            PM128A Xmm8;
+            PM128A Xmm9;
+            PM128A Xmm10;
+            PM128A Xmm11;
+            PM128A Xmm12;
+            PM128A Xmm13;
+            PM128A Xmm14;
+            PM128A Xmm15;
+        };
+    };
+
+    union {
+        PULONG64 IntegerContext[16];
+        struct {
+            PULONG64 Rax;
+            PULONG64 Rcx;
+            PULONG64 Rdx;
+            PULONG64 Rbx;
+            PULONG64 Rsp;
+            PULONG64 Rbp;
+            PULONG64 Rsi;
+            PULONG64 Rdi;
+            PULONG64 R8;
+            PULONG64 R9;
+            PULONG64 R10;
+            PULONG64 R11;
+            PULONG64 R12;
+            PULONG64 R13;
+            PULONG64 R14;
+            PULONG64 R15;
+        };
+    };
+} KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS;
+
+#pragma warning(pop)
+
+#define UNW_FLAG_NHANDLER   0
+#define UNW_FLAG_EHANDLER   1
+#define UNW_FLAG_UHANDLER   2
+
+extern PEXCEPTION_ROUTINE
+RtlVirtualUnwind(
+    __in ULONG HandlerType,
+    __in ULONG64 ImageBase,
+    __in ULONG64 ControlPc,
+    __in PRUNTIME_FUNCTION FunctionEntry,
+    __inout PCONTEXT ContextRecord,
+    __out PVOID *HandlerData,
+    __out PULONG64 EstablisherFrame,
+    __inout_opt PKNONVOLATILE_CONTEXT_POINTERS ContextPointers OPTIONAL
+    );
+
+static DECLSPEC_NOINLINE VOID
+BugCheckStackDump(
+    IN  PCONTEXT    Context
+    )
+{
+#define PARAMETER_COUNT     4
+#define MAXIMUM_ITERATIONS  20
+
+    __try {
+        ULONG   Iteration;
+
+        BugCheckDumpContext(Context);
+
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: STACK:\n",
+                  __MODULE__); 
+
+        for (Iteration = 0; Iteration < MAXIMUM_ITERATIONS; Iteration++) {
+            PRUNTIME_FUNCTION   FunctionEntry;
+            ULONG64             ImageBase;
+            ULONG64             RIP;
+            ULONG64             RSP;
+            ULONG64             Parameter[PARAMETER_COUNT] = {0};
+            ULONG               Index;
+            PCHAR               Name;
+            ULONG64             Offset;
+
+            if (Context->Rip == 0)
+                break;
+
+            FunctionEntry = RtlLookupFunctionEntry(Context->Rip,
+                                                   &ImageBase,
+                                                   NULL);
+
+            if (FunctionEntry != NULL) {
+                CONTEXT                         UnwindContext;
+                ULONG64                         ControlPc;
+                PVOID                           HandlerData;
+                ULONG64                         EstablisherFrame;
+                KNONVOLATILE_CONTEXT_POINTERS   ContextPointers;
+
+                UnwindContext = *Context;
+                ControlPc = Context->Rip;
+                HandlerData = NULL;
+                EstablisherFrame = 0;
+                RtlZeroMemory(&ContextPointers, sizeof (KNONVOLATILE_CONTEXT_POINTERS));
+
+                (VOID) RtlVirtualUnwind(UNW_FLAG_UHANDLER,
+                                        ImageBase,
+                                        ControlPc,
+                                        FunctionEntry,
+                                        &UnwindContext,
+                                        &HandlerData,
+                                        &EstablisherFrame,
+                                        &ContextPointers);
+
+                *Context = UnwindContext;
+            } else {
+                Context->Rip = *(PULONG64)(Context->Rsp);
+                Context->Rsp += sizeof (ULONG64);
+            }
+
+            RSP = Context->Rsp;
+            RIP = Context->Rip;
+
+            Index = 0;
+            Offset = 0;
+            for (;;) {
+                if (Index == PARAMETER_COUNT)
+                    break;
+
+                Parameter[Index] = *(PULONG64)(RSP + Offset);
+
+                Index += 1;
+                Offset += 8;
+            }
+
+            ModuleLookup(RIP, &Name, &Offset);
+
+            if (Name != NULL)
+                LogPrintf(LOG_LEVEL_CRITICAL,
+                          "%s|BUGCHECK: %016X: (%016X %016X %016X %016X) %s + %p\n",
+                          __MODULE__,
+                          RSP,
+                          Parameter[0],
+                          Parameter[1],
+                          Parameter[2],
+                          Parameter[3],
+                          Name,
+                          (PVOID)Offset);
+            else
+                LogPrintf(LOG_LEVEL_CRITICAL,
+                          "%s|BUGCHECK: %016X: (%016X %016X %016X %016X) %p\n",
+                          __MODULE__,
+                          RSP,
+                          Parameter[0],
+                          Parameter[1],
+                          Parameter[2],
+                          Parameter[3],
+                          (PVOID)RIP);
+        }
+    } __except (EXCEPTION_EXECUTE_HANDLER) {
+        // Error of some kind
+    }
+}
+#else
+#error 'Unrecognised architecture'
+#endif
+
+extern VOID
+RtlCaptureContext(
+    __out PCONTEXT    Context
+    );
+
+static DECLSPEC_NOINLINE VOID
+BugCheckIrqlNotLessOrEqual(
+    IN  ULONG_PTR   Parameter1,
+    IN  ULONG_PTR   Parameter2,
+    IN  ULONG_PTR   Parameter3,
+    IN  ULONG_PTR   Parameter4
+    )
+{
+    __try {
+        CONTEXT     Context;
+        PVOID       Memory = (PVOID)Parameter1;
+        KIRQL       Irql = (KIRQL)Parameter2;
+        ULONG_PTR   Access = Parameter3;
+        PVOID       Address = (PVOID)Parameter4;
+        PCHAR       Name;
+        ULONG_PTR   Offset;
+
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: MEMORY REFERENCED: %p\n",
+                  __MODULE__,
+                  Memory);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK:              IRQL: %02x\n",
+                  __MODULE__,
+                  Irql);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK:            ACCESS: %p\n",
+                  __MODULE__,
+                  (PVOID)Access);
+
+        ModuleLookup((ULONG_PTR)Address, &Name, &Offset);
+
+        if (Name != NULL)
+            LogPrintf(LOG_LEVEL_CRITICAL,
+                      "%s|BUGCHECK:           ADDRESS: %s + %p\n",
+                      __MODULE__,
+                      Name,
+                      Offset);
+        else
+            LogPrintf(LOG_LEVEL_CRITICAL,
+                      "%s|BUGCHECK:           ADDRESS: %p\n",
+                      __MODULE__,
+                      Address);
+
+        RtlCaptureContext(&Context);
+        BugCheckStackDump(&Context);
+    } __except (EXCEPTION_EXECUTE_HANDLER) {
+        // Error of some kind
+    }
+}
+
+static DECLSPEC_NOINLINE VOID
+BugCheckDriverIrqlNotLessOrEqual(
+    IN  ULONG_PTR   Parameter1,
+    IN  ULONG_PTR   Parameter2,
+    IN  ULONG_PTR   Parameter3,
+    IN  ULONG_PTR   Parameter4
+    )
+{
+    __try {
+        CONTEXT     Context;
+        PVOID       Memory = (PVOID)Parameter1;
+        KIRQL       Irql = (KIRQL)Parameter2;
+        ULONG_PTR   Access = Parameter3;
+        PVOID       Address = (PVOID)Parameter4;
+        PCHAR       Name;
+        ULONG_PTR   Offset;
+
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: MEMORY REFERENCED: %p\n",
+                  __MODULE__,
+                  Memory);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK:              IRQL: %02X\n",
+                  __MODULE__,
+                  Irql);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK:            ACCESS: %p\n",
+                  __MODULE__,
+                  (PVOID)Access);
+
+        ModuleLookup((ULONG_PTR)Address, &Name, &Offset);
+
+        if (Name != NULL)
+            LogPrintf(LOG_LEVEL_CRITICAL,
+                      "%s|BUGCHECK:           ADDRESS: %s + %p\n",
+                      __MODULE__,
+                      Name,
+                      Offset);
+        else
+            LogPrintf(LOG_LEVEL_CRITICAL,
+                      "%s|BUGCHECK:           ADDRESS: %p\n",
+                      __MODULE__,
+                      Address);
+
+        RtlCaptureContext(&Context);
+        BugCheckStackDump(&Context);
+    } __except (EXCEPTION_EXECUTE_HANDLER) {
+        // Error of some kind
+    }
+}
+
+static DECLSPEC_NOINLINE VOID
+BugCheckSystemServiceException(
+    IN  ULONG_PTR   Parameter1,
+    IN  ULONG_PTR   Parameter2,
+    IN  ULONG_PTR   Parameter3,
+    IN  ULONG_PTR   Parameter4
+    )
+{
+    __try {
+        PEXCEPTION_RECORD   Exception = (PEXCEPTION_RECORD)Parameter2;
+        PCONTEXT            Context = (PCONTEXT)Parameter3;
+
+        UNREFERENCED_PARAMETER(Parameter1);
+        UNREFERENCED_PARAMETER(Parameter4);
+
+        BugCheckDumpExceptionRecord(Exception);
+
+        BugCheckStackDump(Context);
+    } __except (EXCEPTION_EXECUTE_HANDLER) {
+        // Error of some kind
+    }
+}
+
+static DECLSPEC_NOINLINE VOID
+BugCheckSystemThreadExceptionNotHandled(
+    IN  ULONG_PTR   Parameter1,
+    IN  ULONG_PTR   Parameter2,
+    IN  ULONG_PTR   Parameter3,
+    IN  ULONG_PTR   Parameter4
+    )
+{
+    __try {
+        ULONG               Code = (ULONG)Parameter1;
+        PVOID               Address = (PVOID)Parameter2;
+        PEXCEPTION_RECORD   Exception = (PEXCEPTION_RECORD)Parameter3;
+        PCONTEXT            Context = (PCONTEXT)Parameter4;
+        PCHAR               Name;
+        ULONG_PTR           Offset;
+
+        ModuleLookup((ULONG_PTR)Address, &Name, &Offset);
+
+        if (Name != NULL)
+            LogPrintf(LOG_LEVEL_CRITICAL,
+                      "%s|BUGCHECK: %08X AT %s + %p\n",
+                      __MODULE__,
+                      Code,
+                      Name,
+                      Offset);
+        else
+            LogPrintf(LOG_LEVEL_CRITICAL,
+                      "%s|BUGCHECK: %08X AT %p\n",
+                      __MODULE__,
+                      Code,
+                      Name,
+                      Address);
+
+        BugCheckDumpExceptionRecord(Exception);
+
+        BugCheckStackDump(Context);
+    } __except (EXCEPTION_EXECUTE_HANDLER) {
+        // Error of some kind
+    }
+}
+
+static DECLSPEC_NOINLINE VOID
+BugCheckKernelModeExceptionNotHandled(
+    IN  ULONG_PTR   Parameter1,
+    IN  ULONG_PTR   Parameter2,
+    IN  ULONG_PTR   Parameter3,
+    IN  ULONG_PTR   Parameter4
+    )
+{
+    __try {
+        CONTEXT     Context;
+        ULONG       Code = (ULONG)Parameter1;
+        PVOID       Address = (PVOID)Parameter2;
+        PCHAR       Name;
+        ULONG_PTR      Offset;
+
+        UNREFERENCED_PARAMETER(Parameter3);
+        UNREFERENCED_PARAMETER(Parameter4);
+
+        ModuleLookup((ULONG_PTR)Address, &Name, &Offset);
+
+        if (Name != NULL)
+            LogPrintf(LOG_LEVEL_CRITICAL,
+                      "%s|BUGCHECK: %08X AT %s + %p\n",
+                      __MODULE__,
+                      Code,
+                      Name,
+                      Offset);
+        else
+            LogPrintf(LOG_LEVEL_CRITICAL,
+                      "%s|BUGCHECK: %08X AT %p\n",
+                      __MODULE__,
+                      Code,
+                      Name,
+                      Address);
+
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: - Code = %08X\n",
+                  __MODULE__,
+                  Code);
+
+        RtlCaptureContext(&Context);
+        BugCheckStackDump(&Context);
+    } __except (EXCEPTION_EXECUTE_HANDLER) {
+        // Error of some kind
+    }
+}
+
+static DECLSPEC_NOINLINE VOID
+BugCheckCriticalObjectTermination(
+    IN  ULONG_PTR   Parameter1,
+    IN  ULONG_PTR   Parameter2,
+    IN  ULONG_PTR   Parameter3,
+    IN  ULONG_PTR   Parameter4
+    )
+{
+    __try {
+        ULONG       Type = (ULONG)Parameter1;
+        PVOID      Object = (PVOID)Parameter2;
+        PCHAR      Name = (PCHAR)Parameter3;
+        PCHAR       Reason = (PCHAR)Parameter4;
+        CONTEXT     Context;
+
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: Type = %08X\n",
+                  __MODULE__,
+                  Type);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: Object = %p\n",
+                  __MODULE__,
+                  Object);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: Name = %s\n",
+                  __MODULE__,
+                  Name);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: Reason = %s\n",
+                  __MODULE__,
+                  Reason);
+
+        RtlCaptureContext(&Context);
+        BugCheckStackDump(&Context);
+    } __except (EXCEPTION_EXECUTE_HANDLER) {
+        // Error of some kind
+    }
+}
+
+static DECLSPEC_NOINLINE VOID
+BugCheckInaccessibleBootDevice(
+    IN  ULONG_PTR   Parameter1,
+    IN  ULONG_PTR   Parameter2,
+    IN  ULONG_PTR   Parameter3,
+    IN  ULONG_PTR   Parameter4
+    )
+{
+    __try {
+        PUNICODE_STRING Unicode = (PUNICODE_STRING)Parameter1;
+        CONTEXT         Context;
+
+        UNREFERENCED_PARAMETER(Parameter2);
+        UNREFERENCED_PARAMETER(Parameter3);
+        UNREFERENCED_PARAMETER(Parameter4);
+
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: %wZ\n",
+                  __MODULE__,
+                  Unicode);
+
+        RtlCaptureContext(&Context);
+        BugCheckStackDump(&Context);
+    } __except (EXCEPTION_EXECUTE_HANDLER) {
+        // Error of some kind
+    }
+}
+
+static DECLSPEC_NOINLINE VOID
+BugCheckDriverPowerStateFailure(
+    IN  ULONG_PTR       Parameter1,
+    IN  ULONG_PTR       Parameter2,
+    IN  ULONG_PTR       Parameter3,
+    IN  ULONG_PTR       Parameter4
+    )
+{
+    __try {
+        ULONG_PTR       Code = Parameter1;
+
+        UNREFERENCED_PARAMETER(Parameter3);
+
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: Code %08x\n",
+                  __MODULE__,
+                  Code);
+
+        switch (Code) {
+        case 0x1: {
+            PDEVICE_OBJECT  DeviceObject = (PDEVICE_OBJECT)Parameter2;
+
+            LogPrintf(LOG_LEVEL_CRITICAL,
+                      "%s|BUGCHECK: OUTSTANDING IRP (Device Object %p)\n",
+                      __MODULE__,
+                      DeviceObject);
+
+            break;
+        }
+        case 0x3: {
+            PDEVICE_OBJECT      DeviceObject = (PDEVICE_OBJECT)Parameter2;
+            PIRP                Irp = (PIRP)Parameter4;
+            PIO_STACK_LOCATION  StackLocation;
+            LONG                Index;
+
+            LogPrintf(LOG_LEVEL_CRITICAL,
+                      "%s|BUGCHECK: OUTSTANDING IRP %p (Device Object %p)\n",
+                      __MODULE__,
+                      Irp,
+                      DeviceObject);
+
+            StackLocation = IoGetCurrentIrpStackLocation(Irp);
+
+            LogPrintf(LOG_LEVEL_CRITICAL,
+                      "%s|BUGCHECK: IRP STACK:\n",
+                      __MODULE__);     
+
+            for (Index = 0; Index <= Irp->StackCount; Index++) {
+                PCHAR       Name;
+                ULONG_PTR   Offset;
+
+                LogPrintf(LOG_LEVEL_CRITICAL,
+                          "%s|BUGCHECK: [%c%u] %02x %02x %02x %02x\n",
+                          __MODULE__,
+                          (Index == Irp->CurrentLocation) ? '>' : ' ',
+                          Index,
+                          StackLocation->MajorFunction,
+                          StackLocation->MinorFunction,
+                          StackLocation->Flags,
+                          StackLocation->Control);
+
+                ModuleLookup((ULONG_PTR)StackLocation->CompletionRoutine, &Name, &Offset);
+
+                if (Name != NULL)
+                    LogPrintf(LOG_LEVEL_CRITICAL,
+                              "%s|BUGCHECK: [%c%u] CompletionRoutine = %s + %p\n",
+                              __MODULE__,
+                              (Index == Irp->CurrentLocation) ? '>' : ' ',
+                              Index,
+                              Name,
+                              (PVOID)Offset);
+                else
+                    LogPrintf(LOG_LEVEL_CRITICAL,
+                              "%s|BUGCHECK: [%c%u] CompletionRoutine = %p\n",
+                              __MODULE__,
+                              (Index == Irp->CurrentLocation) ? '>' : ' ',
+                              Index,
+                              StackLocation->CompletionRoutine);
+
+                LogPrintf(LOG_LEVEL_CRITICAL,
+                          "%s|BUGCHECK: [%c%u] Context = %p\n",
+                          __MODULE__,
+                          (Index == Irp->CurrentLocation) ? '>' : ' ',
+                          Index,
+                          StackLocation->Context);
+
+                StackLocation++;
+            } 
+
+            break;
+        }
+        default:
+            break;
+        }
+    } __except (EXCEPTION_EXECUTE_HANDLER) {
+        // Error of some kind
+    }
+}
+
+static DECLSPEC_NOINLINE VOID
+BugCheckAssertionFailure(
+    IN  ULONG_PTR   Parameter1,
+    IN  ULONG_PTR   Parameter2,
+    IN  ULONG_PTR   Parameter3,
+    IN  ULONG_PTR   Parameter4
+    )
+{
+    __try {
+        PCHAR       Text = (PCHAR)Parameter1;
+        PCHAR       File = (PCHAR)Parameter2;
+        ULONG       Line = (ULONG)Parameter3;
+        CONTEXT     Context;
+
+        UNREFERENCED_PARAMETER(Parameter4);
+
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: FILE: %s LINE: %u\n", __MODULE__,
+                  File,
+                  Line);
+        LogPrintf(LOG_LEVEL_CRITICAL,
+                  "%s|BUGCHECK: TEXT: %s\n", __MODULE__,
+                  Text);
+
+        RtlCaptureContext(&Context);
+        BugCheckStackDump(&Context);
+    } __except (EXCEPTION_EXECUTE_HANDLER) {
+        // Error of some kind
+    }
+}
+
+struct _BUG_CODE_ENTRY {
+    ULONG       Code;
+    const CHAR  *Name;
+    VOID        (*Handler)(ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR);
+};
+
+#define DEFINE_HANDLER(_Code, _Function) \
+        { (_Code), #_Code, (_Function) }
+
+struct _BUG_CODE_ENTRY   BugCodeTable[] = {
+    DEFINE_HANDLER(IRQL_NOT_LESS_OR_EQUAL, BugCheckIrqlNotLessOrEqual),
+    DEFINE_HANDLER(DRIVER_IRQL_NOT_LESS_OR_EQUAL, BugCheckDriverIrqlNotLessOrEqual),
+    DEFINE_HANDLER(SYSTEM_SERVICE_EXCEPTION, BugCheckSystemServiceException),
+    DEFINE_HANDLER(SYSTEM_THREAD_EXCEPTION_NOT_HANDLED, BugCheckSystemThreadExceptionNotHandled),
+    DEFINE_HANDLER(SYSTEM_THREAD_EXCEPTION_NOT_HANDLED_M, BugCheckSystemThreadExceptionNotHandled),
+    DEFINE_HANDLER(KERNEL_MODE_EXCEPTION_NOT_HANDLED, BugCheckKernelModeExceptionNotHandled),
+    DEFINE_HANDLER(KERNEL_MODE_EXCEPTION_NOT_HANDLED_M, BugCheckKernelModeExceptionNotHandled),
+    DEFINE_HANDLER(CRITICAL_OBJECT_TERMINATION, BugCheckCriticalObjectTermination),
+    DEFINE_HANDLER(INACCESSIBLE_BOOT_DEVICE, BugCheckInaccessibleBootDevice),
+    DEFINE_HANDLER(DRIVER_POWER_STATE_FAILURE, BugCheckDriverPowerStateFailure),
+    DEFINE_HANDLER(ASSERTION_FAILURE, BugCheckAssertionFailure),
+    { 0, NULL, NULL }
+};
+
+static DECLSPEC_NOINLINE VOID
+BugCheckDefaultHandler(
+    VOID
+    )
+{
+    __try {
+        CONTEXT Context;
+
+        RtlCaptureContext(&Context);
+        BugCheckStackDump(&Context);
+    } __except (EXCEPTION_EXECUTE_HANDLER) {
+        // Error of some kind
+    }
+}
+
+#pragma warning(pop)
+
+KBUGCHECK_CALLBACK_ROUTINE BugCheckBugCheckCallback;
+
+VOID                     
+BugCheckBugCheckCallback(
+    IN  PVOID               Argument,
+    IN  ULONG               Length
+    )
+{
+    extern PULONG_PTR       KiBugCheckData;
+    ULONG                   Code;
+    ULONG_PTR               Parameter1;
+    ULONG_PTR               Parameter2;
+    ULONG_PTR               Parameter3;
+    ULONG_PTR               Parameter4;
+    struct _BUG_CODE_ENTRY  *Entry;
+
+    UNREFERENCED_PARAMETER(Argument);
+    UNREFERENCED_PARAMETER(Length);
+
+    (VOID) SchedShutdownCode(SHUTDOWN_crash);
+
+    LogPrintf(LOG_LEVEL_CRITICAL,
+              "%s|BUGCHECK: ====>\n",
+              __MODULE__);
+
+    Code = (ULONG)KiBugCheckData[0];
+    Parameter1 = KiBugCheckData[1];
+    Parameter2 = KiBugCheckData[2];
+    Parameter3 = KiBugCheckData[3];
+    Parameter4 = KiBugCheckData[4];
+
+    for (Entry = BugCodeTable; Entry->Code != 0; Entry++) {
+        if (Code == Entry->Code) {
+            LogPrintf(LOG_LEVEL_CRITICAL,
+                      "%s|BUGCHECK: %s: %p %p %p %p\n",
+                      __MODULE__,
+                      Entry->Name,
+                      (PVOID)Parameter1,
+                      (PVOID)Parameter2,
+                      (PVOID)Parameter3,
+                      (PVOID)Parameter4);
+
+            Entry->Handler(Parameter1,
+                           Parameter2,
+                           Parameter3,
+                           Parameter4);
+
+            goto done;
+        }
+    }
+
+    LogPrintf(LOG_LEVEL_CRITICAL,
+              "%s|BUGCHECK: %08X: %p %p %p %p\n",
+              __MODULE__,
+              Code,
+              (PVOID)Parameter1,
+              (PVOID)Parameter2,
+              (PVOID)Parameter3,
+              (PVOID)Parameter4);
+
+    BugCheckDefaultHandler();
+
+done:
+    LogPrintf(LOG_LEVEL_CRITICAL,
+              "%s|BUGCHECK: <====\n",
+              __MODULE__);
+}
+
+#pragma warning(pop)
+
+NTSTATUS
+BugCheckInitialize(
+    VOID)
+{
+    NTSTATUS    status;
+
+    KeInitializeCallbackRecord(&BugCheckBugCheckCallbackRecord);
+
+    status = STATUS_UNSUCCESSFUL;
+    if (!KeRegisterBugCheckCallback(&BugCheckBugCheckCallbackRecord,
+                                    BugCheckBugCheckCallback,
+                                    NULL,
+                                    0,
+                                    (PUCHAR)__MODULE__))
+        goto fail1;
+
+    return STATUS_SUCCESS;
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
+}
diff --git a/src/xen/bug_check.h b/src/xen/bug_check.h
new file mode 100644 (file)
index 0000000..1d1727e
--- /dev/null
@@ -0,0 +1,46 @@
+/* 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 _XEN_BUG_CHECK_H
+#define _XEN_BUG_CHECK_H
+
+#include <ntddk.h>
+
+extern NTSTATUS
+BugCheckInitialize(
+    VOID);
+
+extern VOID
+BugCheckTeardown(
+    VOID
+    );
+
+#endif  // _XEN_BUG_CHECK_H
diff --git a/src/xen/debug.c b/src/xen/debug.c
deleted file mode 100644 (file)
index c0f073f..0000000
+++ /dev/null
@@ -1,974 +0,0 @@
-/* Copyright (c) Citrix Systems Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, 
- * with or without modification, are permitted provided 
- * that the following conditions are met:
- * 
- * *   Redistributions of source code must retain the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer.
- * *   Redistributions in binary form must reproduce the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer in the documentation and/or other 
- *     materials provided with the distribution.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
- * SUCH DAMAGE.
- */
-
-#define XEN_API extern
-
-#include <ntddk.h>
-#include <xen.h>
-#include <bugcodes.h>
-
-#include "hypercall.h"
-#include "module.h"
-#include "debug.h"
-#include "log.h"
-#include "assert.h"
-
-static KBUGCHECK_CALLBACK_RECORD DebugBugCheckCallbackRecord;
-
-VOID
-DebugTeardown(
-    VOID
-    )
-{
-    (VOID) KeDeregisterBugCheckCallback(&DebugBugCheckCallbackRecord);
-}
-
-#pragma warning(push)
-#pragma warning(disable: 6320) // Exception-filter expression is the constant EXCEPTION_EXECUTE_HANDLER. This might mask exceptions that were not intended to be handled.
-#pragma warning(disable: 6322) // Empty _except block.
-
-static DECLSPEC_NOINLINE VOID
-DebugDumpExceptionRecord(
-    IN  PEXCEPTION_RECORD   Exception
-    )
-{
-    __try {
-        while (Exception != NULL) {
-            ULONG   Index;
-
-            LogQemuPrintf("%s|BUGCHECK: EXCEPTION (%p):\n", __MODULE__,
-                          Exception);
-            LogQemuPrintf("%s|BUGCHECK: - Code = %08X\n", __MODULE__,
-                          Exception->ExceptionCode);
-            LogQemuPrintf("%s|BUGCHECK: - Flags = %08X\n", __MODULE__,
-                          Exception->ExceptionFlags);
-            LogQemuPrintf("%s|BUGCHECK: - Address = %p\n", __MODULE__,
-                          Exception->ExceptionAddress);
-
-            for (Index = 0; Index < Exception->NumberParameters; Index++)
-                LogQemuPrintf("%s|BUGCHECK: - Parameter[%u] = %p\n", __MODULE__,
-                              Index,
-                              (PVOID)Exception->ExceptionInformation[Index]);
-
-            Exception = Exception->ExceptionRecord;
-        }
-    } __except (EXCEPTION_EXECUTE_HANDLER) {
-        // Nothing to to
-    }
-}
-
-#pragma warning(push)
-#pragma warning(disable:6262) // Uses more than 1024 bytes of stack
-
-#if defined(__i386__)
-static DECLSPEC_NOINLINE VOID
-DebugDumpContext(
-    IN  PCONTEXT    Context
-    )
-{
-    __try {
-        LogQemuPrintf("%s|BUGCHECK: CONTEXT (%p):\n", __MODULE__,
-                      Context);
-        LogQemuPrintf("%s|BUGCHECK: - GS = %p\n", __MODULE__,
-                      (PVOID)Context->SegGs);
-        LogQemuPrintf("%s|BUGCHECK: - FS = %p\n", __MODULE__,
-                      (PVOID)Context->SegFs);
-        LogQemuPrintf("%s|BUGCHECK: - ES = %p\n", __MODULE__,
-                      (PVOID)Context->SegEs);
-        LogQemuPrintf("%s|BUGCHECK: - DS = %p\n", __MODULE__,
-                      (PVOID)Context->SegDs);
-        LogQemuPrintf("%s|BUGCHECK: - SS = %p\n", __MODULE__,
-                      (PVOID)Context->SegSs);
-        LogQemuPrintf("%s|BUGCHECK: - CS = %p\n", __MODULE__,
-                      (PVOID)Context->SegCs);
-
-        LogQemuPrintf("%s|BUGCHECK: - EFLAGS = %p\n", __MODULE__,
-                      (PVOID)Context->EFlags);
-
-        LogQemuPrintf("%s|BUGCHECK: - EDI = %p\n", __MODULE__,
-                      (PVOID)Context->Edi);
-        LogQemuPrintf("%s|BUGCHECK: - ESI = %p\n", __MODULE__,
-                      (PVOID)Context->Esi);
-        LogQemuPrintf("%s|BUGCHECK: - EBX = %p\n", __MODULE__,
-                      (PVOID)Context->Ebx);
-        LogQemuPrintf("%s|BUGCHECK: - EDX = %p\n", __MODULE__,
-                      (PVOID)Context->Edx);
-        LogQemuPrintf("%s|BUGCHECK: - ECX = %p\n", __MODULE__,
-                      (PVOID)Context->Ecx);
-        LogQemuPrintf("%s|BUGCHECK: - EAX = %p\n", __MODULE__,
-                      (PVOID)Context->Eax);
-        LogQemuPrintf("%s|BUGCHECK: - EBP = %p\n", __MODULE__,
-                      (PVOID)Context->Ebp);
-        LogQemuPrintf("%s|BUGCHECK: - EIP = %p\n", __MODULE__,
-                      (PVOID)Context->Eip);
-        LogQemuPrintf("%s|BUGCHECK: - ESP = %p\n", __MODULE__,
-                      (PVOID)Context->Esp);
-    } __except (EXCEPTION_EXECUTE_HANDLER) {
-        // Nothing to to
-    }
-}
-
-static DECLSPEC_NOINLINE VOID
-DebugStackDump(
-    IN  PCONTEXT    Context
-    )
-{
-#define PARAMETER_COUNT     3
-#define MAXIMUM_ITERATIONS  20
-
-    __try {
-        ULONG_PTR   EBP;
-        ULONG       Iteration;
-
-        DebugDumpContext(Context);
-
-        EBP = (ULONG_PTR)Context->Ebp;
-
-        LogQemuPrintf("%s|BUGCHECK: STACK:\n", __MODULE__);
-
-        for (Iteration = 0; Iteration < MAXIMUM_ITERATIONS; Iteration++) {
-            ULONG_PTR   NextEBP;
-            ULONG_PTR   EIP;
-            ULONG_PTR   Parameter[PARAMETER_COUNT] = {0};
-            ULONG       Index;
-            PCHAR       Name;
-            ULONG_PTR   Offset;
-
-            NextEBP = *(PULONG_PTR)EBP;
-            EIP = *(PULONG_PTR)(EBP + 4);
-
-            if (EIP == 0)
-                break;
-
-            Index = 0;
-            Offset = 8;
-            for (;;) {
-                if (EBP + Offset >= NextEBP)
-                    break;
-
-                if (Index == PARAMETER_COUNT)
-                    break;
-
-                Parameter[Index] = *(PULONG_PTR)(EBP + Offset);
-
-                Index += 1;
-                Offset += 4;
-            }
-
-            ModuleLookup(EIP, &Name, &Offset);
-
-            if (Name != NULL)
-                LogQemuPrintf("%s|BUGCHECK: %p: (%p %p %p) %s + %p\n", __MODULE__,
-                              EBP,
-                              (PVOID)Parameter[0],
-                              (PVOID)Parameter[1],
-                              (PVOID)Parameter[2],
-                              Name,
-                              (PVOID)Offset);
-            else
-                LogQemuPrintf("%s|BUGCHECK: %p: (%p %p %p) %p\n", __MODULE__,
-                              EBP,
-                              (PVOID)Parameter[0],
-                              (PVOID)Parameter[1],
-                              (PVOID)Parameter[2],
-                              (PVOID)EIP);
-
-            EBP = NextEBP;
-        }
-    } __except (EXCEPTION_EXECUTE_HANDLER) {
-        // End of stack
-    }
-
-#undef  MAXIMUM_ITERATIONS
-#undef  PARAMETER_COUNT
-}
-#elif defined(__x86_64__)
-static DECLSPEC_NOINLINE VOID
-DebugDumpContext(
-    IN  PCONTEXT    Context
-    )
-{
-    __try {
-        LogQemuPrintf("%s|BUGCHECK: CONTEXT (%p):\n", __MODULE__,
-                      Context);
-        LogQemuPrintf("%s|BUGCHECK: - GS = %p\n", __MODULE__,
-                      (PVOID)Context->SegGs);
-        LogQemuPrintf("%s|BUGCHECK: - FS = %p\n", __MODULE__,
-                      (PVOID)Context->SegFs);
-        LogQemuPrintf("%s|BUGCHECK: - ES = %p\n", __MODULE__,
-                      (PVOID)Context->SegEs);
-        LogQemuPrintf("%s|BUGCHECK: - DS = %p\n", __MODULE__,
-                      (PVOID)Context->SegDs);
-        LogQemuPrintf("%s|BUGCHECK: - SS = %p\n", __MODULE__,
-                      (PVOID)Context->SegSs);
-        LogQemuPrintf("%s|BUGCHECK: - CS = %p\n", __MODULE__,
-                      (PVOID)Context->SegCs);
-
-        LogQemuPrintf("%s|BUGCHECK: - EFLAGS = %p\n", __MODULE__,
-                      (PVOID)Context->EFlags);
-
-        LogQemuPrintf("%s|BUGCHECK: - RDI = %p\n", __MODULE__,
-                      (PVOID)Context->Rdi);
-        LogQemuPrintf("%s|BUGCHECK: - RSI = %p\n", __MODULE__,
-                      (PVOID)Context->Rsi);
-        LogQemuPrintf("%s|BUGCHECK: - RBX = %p\n", __MODULE__,
-                      (PVOID)Context->Rbx);
-        LogQemuPrintf("%s|BUGCHECK: - RDX = %p\n", __MODULE__,
-                      (PVOID)Context->Rdx);
-        LogQemuPrintf("%s|BUGCHECK: - RCX = %p\n", __MODULE__,
-                      (PVOID)Context->Rcx);
-        LogQemuPrintf("%s|BUGCHECK: - RAX = %p\n", __MODULE__,
-                      (PVOID)Context->Rax);
-        LogQemuPrintf("%s|BUGCHECK: - RBP = %p\n", __MODULE__,
-                      (PVOID)Context->Rbp);
-        LogQemuPrintf("%s|BUGCHECK: - RIP = %p\n", __MODULE__,
-                      (PVOID)Context->Rip);
-        LogQemuPrintf("%s|BUGCHECK: - RSP = %p\n", __MODULE__,
-                      (PVOID)Context->Rsp);
-        LogQemuPrintf("%s|BUGCHECK: - R8 = %p\n", __MODULE__,
-                      (PVOID)Context->R8);
-        LogQemuPrintf("%s|BUGCHECK: - R9 = %p\n", __MODULE__,
-                      (PVOID)Context->R9);
-        LogQemuPrintf("%s|BUGCHECK: - R10 = %p\n", __MODULE__,
-                      (PVOID)Context->R10);
-        LogQemuPrintf("%s|BUGCHECK: - R11 = %p\n", __MODULE__,
-                      (PVOID)Context->R11);
-        LogQemuPrintf("%s|BUGCHECK: - R12 = %p\n", __MODULE__,
-                      (PVOID)Context->R12);
-        LogQemuPrintf("%s|BUGCHECK: - R13 = %p\n", __MODULE__,
-                      (PVOID)Context->R13);
-        LogQemuPrintf("%s|BUGCHECK: - R14 = %p\n", __MODULE__,
-                      (PVOID)Context->R14);
-        LogQemuPrintf("%s|BUGCHECK: - R15 = %p\n", __MODULE__,
-                      (PVOID)Context->R15);
-    } __except (EXCEPTION_EXECUTE_HANDLER) {
-        // Nothing to to
-    }
-}
-
-typedef struct _RUNTIME_FUNCTION {
-    ULONG BeginAddress;
-    ULONG EndAddress;
-    ULONG UnwindData;
-} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
-
-#define UNWIND_HISTORY_TABLE_SIZE 12
-
-typedef struct _UNWIND_HISTORY_TABLE_ENTRY {
-        ULONG64 ImageBase;
-        PRUNTIME_FUNCTION FunctionEntry;
-} UNWIND_HISTORY_TABLE_ENTRY, *PUNWIND_HISTORY_TABLE_ENTRY;
-
-#define UNWIND_HISTORY_TABLE_NONE 0
-#define UNWIND_HISTORY_TABLE_GLOBAL 1
-#define UNWIND_HISTORY_TABLE_LOCAL 2
-
-typedef struct _UNWIND_HISTORY_TABLE {
-        ULONG Count;
-        UCHAR Search;
-        UCHAR RaiseStatusIndex;
-        BOOLEAN Unwind;
-        BOOLEAN Exception;
-        ULONG64 LowAddress;
-        ULONG64 HighAddress;
-        UNWIND_HISTORY_TABLE_ENTRY Entry[UNWIND_HISTORY_TABLE_SIZE];
-} UNWIND_HISTORY_TABLE, *PUNWIND_HISTORY_TABLE;
-
-extern PRUNTIME_FUNCTION
-RtlLookupFunctionEntry(
-    __in ULONG64 ControlPc,
-    __out PULONG64 ImageBase,
-    __inout_opt PUNWIND_HISTORY_TABLE HistoryTable OPTIONAL
-    );
-
-#pragma prefast(suppress:28301) // No annotations
-typedef EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE) (
-    __in struct _EXCEPTION_RECORD *ExceptionRecord,
-    __in PVOID EstablisherFrame,
-    __inout struct _CONTEXT *ContextRecord,
-    __inout PVOID DispatcherContext
-    );
-
-#pragma warning(push)
-#pragma warning(disable:4201) // nonstandard extension used : nameless struct/union
-
-typedef struct _KNONVOLATILE_CONTEXT_POINTERS {
-    union {
-        PM128A FloatingContext[16];
-        struct {
-            PM128A Xmm0;
-            PM128A Xmm1;
-            PM128A Xmm2;
-            PM128A Xmm3;
-            PM128A Xmm4;
-            PM128A Xmm5;
-            PM128A Xmm6;
-            PM128A Xmm7;
-            PM128A Xmm8;
-            PM128A Xmm9;
-            PM128A Xmm10;
-            PM128A Xmm11;
-            PM128A Xmm12;
-            PM128A Xmm13;
-            PM128A Xmm14;
-            PM128A Xmm15;
-        };
-    };
-
-    union {
-        PULONG64 IntegerContext[16];
-        struct {
-            PULONG64 Rax;
-            PULONG64 Rcx;
-            PULONG64 Rdx;
-            PULONG64 Rbx;
-            PULONG64 Rsp;
-            PULONG64 Rbp;
-            PULONG64 Rsi;
-            PULONG64 Rdi;
-            PULONG64 R8;
-            PULONG64 R9;
-            PULONG64 R10;
-            PULONG64 R11;
-            PULONG64 R12;
-            PULONG64 R13;
-            PULONG64 R14;
-            PULONG64 R15;
-        };
-    };
-} KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS;
-
-#pragma warning(pop)
-
-#define UNW_FLAG_NHANDLER   0
-#define UNW_FLAG_EHANDLER   1
-#define UNW_FLAG_UHANDLER   2
-
-extern PEXCEPTION_ROUTINE
-RtlVirtualUnwind(
-    __in ULONG HandlerType,
-    __in ULONG64 ImageBase,
-    __in ULONG64 ControlPc,
-    __in PRUNTIME_FUNCTION FunctionEntry,
-    __inout PCONTEXT ContextRecord,
-    __out PVOID *HandlerData,
-    __out PULONG64 EstablisherFrame,
-    __inout_opt PKNONVOLATILE_CONTEXT_POINTERS ContextPointers OPTIONAL
-    );
-
-static DECLSPEC_NOINLINE VOID
-DebugStackDump(
-    IN  PCONTEXT    Context
-    )
-{
-#define PARAMETER_COUNT     4
-#define MAXIMUM_ITERATIONS  20
-
-    __try {
-        ULONG   Iteration;
-
-        DebugDumpContext(Context);
-
-        LogQemuPrintf("%s|BUGCHECK: STACK:\n", __MODULE__);    
-
-        for (Iteration = 0; Iteration < MAXIMUM_ITERATIONS; Iteration++) {
-            PRUNTIME_FUNCTION   FunctionEntry;
-            ULONG_PTR           ImageBase;
-            ULONG_PTR           RIP;
-            ULONG_PTR           RSP;
-            ULONG_PTR           Parameter[PARAMETER_COUNT] = {0};
-            ULONG               Index;
-            PCHAR               Name;
-            ULONG_PTR           Offset;
-
-            if (Context->Rip == 0)
-                break;
-
-            FunctionEntry = RtlLookupFunctionEntry(Context->Rip,
-                                                   &ImageBase,
-                                                   NULL);
-
-            if (FunctionEntry != NULL) {
-                CONTEXT                         UnwindContext;
-                ULONG64                         ControlPc;
-                PVOID                           HandlerData;
-                ULONG64                         EstablisherFrame;
-                KNONVOLATILE_CONTEXT_POINTERS   ContextPointers;
-
-                UnwindContext = *Context;
-                ControlPc = Context->Rip;
-                HandlerData = NULL;
-                EstablisherFrame = 0;
-                RtlZeroMemory(&ContextPointers, sizeof (KNONVOLATILE_CONTEXT_POINTERS));
-
-                (VOID) RtlVirtualUnwind(UNW_FLAG_UHANDLER,
-                                        ImageBase,
-                                        ControlPc,
-                                        FunctionEntry,
-                                        &UnwindContext,
-                                        &HandlerData,
-                                        &EstablisherFrame,
-                                        &ContextPointers);
-
-                *Context = UnwindContext;
-            } else {
-                Context->Rip = *(PULONG64)(Context->Rsp);
-                Context->Rsp += sizeof (ULONG64);
-            }
-
-            RSP = Context->Rsp;
-            RIP = Context->Rip;
-
-            Index = 0;
-            Offset = 0;
-            for (;;) {
-                if (Index == PARAMETER_COUNT)
-                    break;
-
-                Parameter[Index] = *(PULONG64)(RSP + Offset);
-
-                Index += 1;
-                Offset += 8;
-            }
-
-            ModuleLookup(RIP, &Name, &Offset);
-
-            if (Name != NULL)
-                LogQemuPrintf("%s|BUGCHECK: %p: (%p %p %p %p) %s + %p\n", __MODULE__,
-                              RSP,
-                              (PVOID)Parameter[0],
-                              (PVOID)Parameter[1],
-                              (PVOID)Parameter[2],
-                              (PVOID)Parameter[3],
-                              Name,
-                              (PVOID)Offset);
-            else
-                LogQemuPrintf("%s|BUGCHECK: %p: (%p %p %p %p) %p\n", __MODULE__,
-                              RSP,
-                              (PVOID)Parameter[0],
-                              (PVOID)Parameter[1],
-                              (PVOID)Parameter[2],
-                              (PVOID)Parameter[3],
-                              (PVOID)RIP);
-        }
-    } __except (EXCEPTION_EXECUTE_HANDLER) {
-        // Error of some kind
-    }
-}
-#else
-#error 'Unrecognised architecture'
-#endif
-
-extern VOID
-RtlCaptureContext(
-    __out PCONTEXT    Context
-    );
-
-static DECLSPEC_NOINLINE VOID
-DebugIrqlNotLessOrEqual(
-    IN  ULONG_PTR   Parameter1,
-    IN  ULONG_PTR   Parameter2,
-    IN  ULONG_PTR   Parameter3,
-    IN  ULONG_PTR   Parameter4
-    )
-{
-    __try {
-        CONTEXT     Context;
-        PVOID       Memory = (PVOID)Parameter1;
-        KIRQL       Irql = (KIRQL)Parameter2;
-        ULONG_PTR   Access = Parameter3;
-        PVOID       Address = (PVOID)Parameter4;
-        PCHAR       Name;
-        ULONG_PTR   Offset;
-
-        LogQemuPrintf("%s|BUGCHECK: MEMORY REFERENCED: %p\n", __MODULE__,
-                      Memory);
-        LogQemuPrintf("%s|BUGCHECK:              IRQL: %02x\n", __MODULE__,
-                      Irql);
-        LogQemuPrintf("%s|BUGCHECK:            ACCESS: %p\n", __MODULE__,
-                      (PVOID)Access);
-
-        ModuleLookup((ULONG_PTR)Address, &Name, &Offset);
-
-        if (Name != NULL)
-            LogQemuPrintf("%s|BUGCHECK:           ADDRESS: %s + %p\n", __MODULE__,
-                          Name,
-                          Offset);
-        else
-            LogQemuPrintf("%s|BUGCHECK:           ADDRESS: %p\n", __MODULE__,
-                          Address);
-
-        RtlCaptureContext(&Context);
-        DebugStackDump(&Context);
-    } __except (EXCEPTION_EXECUTE_HANDLER) {
-        // Error of some kind
-    }
-}
-
-static DECLSPEC_NOINLINE VOID
-DebugDriverIrqlNotLessOrEqual(
-    IN  ULONG_PTR   Parameter1,
-    IN  ULONG_PTR   Parameter2,
-    IN  ULONG_PTR   Parameter3,
-    IN  ULONG_PTR   Parameter4
-    )
-{
-    __try {
-        CONTEXT     Context;
-        PVOID       Memory = (PVOID)Parameter1;
-        KIRQL       Irql = (KIRQL)Parameter2;
-        ULONG_PTR   Access = Parameter3;
-        PVOID       Address = (PVOID)Parameter4;
-        PCHAR       Name;
-        ULONG_PTR   Offset;
-
-        LogQemuPrintf("%s|BUGCHECK: MEMORY REFERENCED: %p\n", __MODULE__,
-                      Memory);
-        LogQemuPrintf("%s|BUGCHECK:              IRQL: %02X\n", __MODULE__,
-                      Irql);
-        LogQemuPrintf("%s|BUGCHECK:            ACCESS: %p\n", __MODULE__,
-                      (PVOID)Access);
-
-        ModuleLookup((ULONG_PTR)Address, &Name, &Offset);
-
-        if (Name != NULL)
-            LogQemuPrintf("%s|BUGCHECK:           ADDRESS: %s + %p\n", __MODULE__,
-                          Name,
-                          Offset);
-        else
-            LogQemuPrintf("%s|BUGCHECK:           ADDRESS: %p\n", __MODULE__,
-                          Address);
-
-        RtlCaptureContext(&Context);
-        DebugStackDump(&Context);
-    } __except (EXCEPTION_EXECUTE_HANDLER) {
-        // Error of some kind
-    }
-}
-
-static DECLSPEC_NOINLINE VOID
-DebugSystemServiceException(
-    IN  ULONG_PTR   Parameter1,
-    IN  ULONG_PTR   Parameter2,
-    IN  ULONG_PTR   Parameter3,
-    IN  ULONG_PTR   Parameter4
-    )
-{
-    __try {
-        PEXCEPTION_RECORD   Exception = (PEXCEPTION_RECORD)Parameter2;
-        PCONTEXT            Context = (PCONTEXT)Parameter3;
-
-        UNREFERENCED_PARAMETER(Parameter1);
-        UNREFERENCED_PARAMETER(Parameter4);
-
-        DebugDumpExceptionRecord(Exception);
-
-        DebugStackDump(Context);
-    } __except (EXCEPTION_EXECUTE_HANDLER) {
-        // Error of some kind
-    }
-}
-
-static DECLSPEC_NOINLINE VOID
-DebugSystemThreadExceptionNotHandled(
-    IN  ULONG_PTR   Parameter1,
-    IN  ULONG_PTR   Parameter2,
-    IN  ULONG_PTR   Parameter3,
-    IN  ULONG_PTR   Parameter4
-    )
-{
-    __try {
-        ULONG               Code = (ULONG)Parameter1;
-        PVOID               Address = (PVOID)Parameter2;
-        PEXCEPTION_RECORD   Exception = (PEXCEPTION_RECORD)Parameter3;
-        PCONTEXT            Context = (PCONTEXT)Parameter4;
-        PCHAR               Name;
-        ULONG_PTR           Offset;
-
-        ModuleLookup((ULONG_PTR)Address, &Name, &Offset);
-
-        if (Name != NULL)
-            LogQemuPrintf("%s|BUGCHECK: %08X AT %s + %p\n", __MODULE__,
-                          Code,
-                          Name,
-                          Offset);
-        else
-            LogQemuPrintf("%s|BUGCHECK: %08X AT %p\n", __MODULE__,
-                          Code,
-                          Name,
-                          Address);
-
-        DebugDumpExceptionRecord(Exception);
-
-        DebugStackDump(Context);
-    } __except (EXCEPTION_EXECUTE_HANDLER) {
-        // Error of some kind
-    }
-}
-
-static DECLSPEC_NOINLINE VOID
-DebugKernelModeExceptionNotHandled(
-    IN  ULONG_PTR   Parameter1,
-    IN  ULONG_PTR   Parameter2,
-    IN  ULONG_PTR   Parameter3,
-    IN  ULONG_PTR   Parameter4
-    )
-{
-    __try {
-        CONTEXT     Context;
-        ULONG       Code = (ULONG)Parameter1;
-        PVOID       Address = (PVOID)Parameter2;
-        PCHAR       Name;
-        ULONG_PTR      Offset;
-
-        UNREFERENCED_PARAMETER(Parameter3);
-        UNREFERENCED_PARAMETER(Parameter4);
-
-        ModuleLookup((ULONG_PTR)Address, &Name, &Offset);
-
-        if (Name != NULL)
-            LogQemuPrintf("%s|BUGCHECK: %08X AT %s + %p\n", __MODULE__,
-                          Code,
-                          Name,
-                          Offset);
-        else
-            LogQemuPrintf("%s|BUGCHECK: %08X AT %p\n", __MODULE__,
-                          Code,
-                          Name,
-                          Address);
-
-        LogQemuPrintf("%s|BUGCHECK: - Code = %08X\n", __MODULE__,
-                      Code);
-
-        RtlCaptureContext(&Context);
-        DebugStackDump(&Context);
-    } __except (EXCEPTION_EXECUTE_HANDLER) {
-        // Error of some kind
-    }
-}
-
-static DECLSPEC_NOINLINE VOID
-DebugCriticalObjectTermination(
-    IN  ULONG_PTR   Parameter1,
-    IN  ULONG_PTR   Parameter2,
-    IN  ULONG_PTR   Parameter3,
-    IN  ULONG_PTR   Parameter4
-    )
-{
-    __try {
-        ULONG       Type = (ULONG)Parameter1;
-        PVOID      Object = (PVOID)Parameter2;
-        PCHAR      Name = (PCHAR)Parameter3;
-        PCHAR       Reason = (PCHAR)Parameter4;
-        CONTEXT     Context;
-
-        LogQemuPrintf("%s|BUGCHECK: Type = %08X\n", __MODULE__,
-                      Type);
-        LogQemuPrintf("%s|BUGCHECK: Object = %p\n", __MODULE__,
-                      Object);
-        LogQemuPrintf("%s|BUGCHECK: Name = %s\n", __MODULE__,
-                      Name);
-        LogQemuPrintf("%s|BUGCHECK: Reason = %s\n", __MODULE__,
-                      Reason);
-
-        RtlCaptureContext(&Context);
-        DebugStackDump(&Context);
-    } __except (EXCEPTION_EXECUTE_HANDLER) {
-        // Error of some kind
-    }
-}
-
-static DECLSPEC_NOINLINE VOID
-DebugInaccessibleBootDevice(
-    IN  ULONG_PTR   Parameter1,
-    IN  ULONG_PTR   Parameter2,
-    IN  ULONG_PTR   Parameter3,
-    IN  ULONG_PTR   Parameter4
-    )
-{
-    __try {
-        PUNICODE_STRING Unicode = (PUNICODE_STRING)Parameter1;
-        CONTEXT         Context;
-
-        UNREFERENCED_PARAMETER(Parameter2);
-        UNREFERENCED_PARAMETER(Parameter3);
-        UNREFERENCED_PARAMETER(Parameter4);
-
-        LogQemuPrintf("%s|BUGCHECK: %wZ\n", __MODULE__,
-                      Unicode);
-
-        RtlCaptureContext(&Context);
-        DebugStackDump(&Context);
-    } __except (EXCEPTION_EXECUTE_HANDLER) {
-        // Error of some kind
-    }
-}
-
-static DECLSPEC_NOINLINE VOID
-DebugDriverPowerStateFailure(
-    IN  ULONG_PTR       Parameter1,
-    IN  ULONG_PTR       Parameter2,
-    IN  ULONG_PTR       Parameter3,
-    IN  ULONG_PTR       Parameter4
-    )
-{
-    __try {
-        ULONG_PTR       Code = Parameter1;
-
-        UNREFERENCED_PARAMETER(Parameter3);
-
-        LogQemuPrintf("%s|BUGCHECK: Code %08x\n", __MODULE__,
-                      Code);
-
-        switch (Code) {
-        case 0x1: {
-            PDEVICE_OBJECT  DeviceObject = (PDEVICE_OBJECT)Parameter2;
-
-            LogQemuPrintf("%s|BUGCHECK: OUTSTANDING IRP (Device Object %p)\n", __MODULE__,
-                          DeviceObject);
-
-            break;
-        }
-        case 0x3: {
-            PDEVICE_OBJECT      DeviceObject = (PDEVICE_OBJECT)Parameter2;
-            PIRP                Irp = (PIRP)Parameter4;
-            PIO_STACK_LOCATION  StackLocation;
-            LONG                Index;
-
-            LogQemuPrintf("%s|BUGCHECK: OUTSTANDING IRP %p (Device Object %p)\n", __MODULE__,
-                          Irp,
-                          DeviceObject);
-
-            StackLocation = IoGetCurrentIrpStackLocation(Irp);
-
-            LogQemuPrintf("%s|BUGCHECK: IRP STACK:\n", __MODULE__);    
-
-            for (Index = 0; Index <= Irp->StackCount; Index++) {
-                PCHAR       Name;
-                ULONG_PTR   Offset;
-
-                LogQemuPrintf("%s|BUGCHECK: [%c%u] %02x %02x %02x %02x\n", __MODULE__,
-                              (Index == Irp->CurrentLocation) ? '>' : ' ',
-                              Index,
-                              StackLocation->MajorFunction,
-                              StackLocation->MinorFunction,
-                              StackLocation->Flags,
-                              StackLocation->Control);
-
-                ModuleLookup((ULONG_PTR)StackLocation->CompletionRoutine, &Name, &Offset);
-
-                if (Name != NULL)
-                    LogQemuPrintf("%s|BUGCHECK: [%c%u] CompletionRoutine = %s + %p\n", __MODULE__,
-                                  (Index == Irp->CurrentLocation) ? '>' : ' ',
-                                  Index,
-                                  Name,
-                                  (PVOID)Offset);
-                else
-                    LogQemuPrintf("%s|BUGCHECK: [%c%u] CompletionRoutine = %p\n", __MODULE__,
-                                  (Index == Irp->CurrentLocation) ? '>' : ' ',
-                                  Index,
-                                  StackLocation->CompletionRoutine);
-
-                LogQemuPrintf("%s|BUGCHECK: [%c%u] Context = %p\n", __MODULE__,
-                              (Index == Irp->CurrentLocation) ? '>' : ' ',
-                              Index,
-                              StackLocation->Context);
-
-                StackLocation++;
-            } 
-
-            break;
-        }
-        default:
-            break;
-        }
-    } __except (EXCEPTION_EXECUTE_HANDLER) {
-        // Error of some kind
-    }
-}
-
-static DECLSPEC_NOINLINE VOID
-DebugAssertionFailure(
-    IN  ULONG_PTR   Parameter1,
-    IN  ULONG_PTR   Parameter2,
-    IN  ULONG_PTR   Parameter3,
-    IN  ULONG_PTR   Parameter4
-    )
-{
-    __try {
-        PCHAR       Text = (PCHAR)Parameter1;
-        PCHAR       File = (PCHAR)Parameter2;
-        ULONG       Line = (ULONG)Parameter3;
-        CONTEXT     Context;
-
-        UNREFERENCED_PARAMETER(Parameter4);
-
-        LogQemuPrintf("%s|BUGCHECK: FILE: %s LINE: %u\n", __MODULE__,
-                      File,
-                      Line);
-        LogQemuPrintf("%s|BUGCHECK: TEXT: %s\n", __MODULE__,
-                      Text);
-
-        RtlCaptureContext(&Context);
-        DebugStackDump(&Context);
-    } __except (EXCEPTION_EXECUTE_HANDLER) {
-        // Error of some kind
-    }
-}
-
-struct _BUG_CODE_ENTRY {
-    ULONG       Code;
-    const CHAR  *Name;
-    VOID        (*Handler)(ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR);
-};
-
-#define DEFINE_HANDLER(_Code, _Function) \
-        { (_Code), #_Code, (_Function) }
-
-struct _BUG_CODE_ENTRY   BugCodeTable[] = {
-    DEFINE_HANDLER(IRQL_NOT_LESS_OR_EQUAL, DebugIrqlNotLessOrEqual),
-    DEFINE_HANDLER(DRIVER_IRQL_NOT_LESS_OR_EQUAL, DebugDriverIrqlNotLessOrEqual),
-    DEFINE_HANDLER(SYSTEM_SERVICE_EXCEPTION, DebugSystemServiceException),
-    DEFINE_HANDLER(SYSTEM_THREAD_EXCEPTION_NOT_HANDLED, DebugSystemThreadExceptionNotHandled),
-    DEFINE_HANDLER(SYSTEM_THREAD_EXCEPTION_NOT_HANDLED_M, DebugSystemThreadExceptionNotHandled),
-    DEFINE_HANDLER(KERNEL_MODE_EXCEPTION_NOT_HANDLED, DebugKernelModeExceptionNotHandled),
-    DEFINE_HANDLER(KERNEL_MODE_EXCEPTION_NOT_HANDLED_M, DebugKernelModeExceptionNotHandled),
-    DEFINE_HANDLER(CRITICAL_OBJECT_TERMINATION, DebugCriticalObjectTermination),
-    DEFINE_HANDLER(INACCESSIBLE_BOOT_DEVICE, DebugInaccessibleBootDevice),
-    DEFINE_HANDLER(DRIVER_POWER_STATE_FAILURE, DebugDriverPowerStateFailure),
-    DEFINE_HANDLER(ASSERTION_FAILURE, DebugAssertionFailure),
-    { 0, NULL, NULL }
-};
-
-static DECLSPEC_NOINLINE VOID
-DebugDefaultHandler(
-    VOID
-    )
-{
-    __try {
-        CONTEXT Context;
-
-        RtlCaptureContext(&Context);
-        DebugStackDump(&Context);
-    } __except (EXCEPTION_EXECUTE_HANDLER) {
-        // Error of some kind
-    }
-}
-
-#pragma warning(pop)
-
-KBUGCHECK_CALLBACK_ROUTINE DebugBugCheckCallback;
-
-VOID                     
-DebugBugCheckCallback(
-    IN  PVOID               Argument,
-    IN  ULONG               Length
-    )
-{
-    extern PULONG_PTR       KiBugCheckData;
-    ULONG                   Code;
-    ULONG_PTR               Parameter1;
-    ULONG_PTR               Parameter2;
-    ULONG_PTR               Parameter3;
-    ULONG_PTR               Parameter4;
-    struct _BUG_CODE_ENTRY  *Entry;
-
-    UNREFERENCED_PARAMETER(Argument);
-    UNREFERENCED_PARAMETER(Length);
-
-    (VOID) SchedShutdownCode(SHUTDOWN_crash);
-
-    LogQemuPrintf("%s|BUGCHECK: ====>\n", __MODULE__);
-
-    Code = (ULONG)KiBugCheckData[0];
-    Parameter1 = KiBugCheckData[1];
-    Parameter2 = KiBugCheckData[2];
-    Parameter3 = KiBugCheckData[3];
-    Parameter4 = KiBugCheckData[4];
-
-    for (Entry = BugCodeTable; Entry->Code != 0; Entry++) {
-        if (Code == Entry->Code) {
-            LogQemuPrintf("%s|BUGCHECK: %s: %p %p %p %p\n", __MODULE__,
-                          Entry->Name,
-                          (PVOID)Parameter1,
-                          (PVOID)Parameter2,
-                          (PVOID)Parameter3,
-                          (PVOID)Parameter4);
-
-            Entry->Handler(Parameter1,
-                            Parameter2,
-                            Parameter3,
-                            Parameter4);
-
-            goto done;
-        }
-    }
-
-    LogQemuPrintf("%s|BUGCHECK: %08X: %p %p %p %p\n", __MODULE__,
-                  Code,
-                  (PVOID)Parameter1,
-                  (PVOID)Parameter2,
-                  (PVOID)Parameter3,
-                  (PVOID)Parameter4);
-
-    DebugDefaultHandler();
-
-done:
-    LogQemuPrintf("%s|BUGCHECK: <====\n", __MODULE__);
-}
-
-#pragma warning(pop)
-
-NTSTATUS
-DebugInitialize(
-    VOID)
-{
-    NTSTATUS    status;
-
-    KeInitializeCallbackRecord(&DebugBugCheckCallbackRecord);
-
-    status = STATUS_UNSUCCESSFUL;
-    if (!KeRegisterBugCheckCallback(&DebugBugCheckCallbackRecord,
-                                    DebugBugCheckCallback,
-                                    NULL,
-                                    0,
-                                    (PUCHAR)__MODULE__))
-        goto fail1;
-
-    Info("callback registered\n");
-
-    return STATUS_SUCCESS;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
-}
diff --git a/src/xen/debug.h b/src/xen/debug.h
deleted file mode 100644 (file)
index 61bce92..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/* 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 _XEN_DEBUG_H
-#define _XEN_DEBUG_H
-
-#include <ntddk.h>
-
-extern NTSTATUS
-DebugInitialize(
-    VOID);
-
-extern VOID
-DebugTeardown(
-    VOID
-    );
-
-#endif  // _XEN_DEBUG_H
index a8803c9eaad090b211b9b35a051ab6ec6bb33e32..5811030d20bf0e802669abceea1552ee1cb60a08 100644 (file)
 #include <xen.h>
 
 #include "hypercall.h"
-#include "debug.h"
-#include "dump.h"
+#include "log.h"
 #include "module.h"
 #include "process.h"
-#include "unplug.h"
 #include "system.h"
-#include "log.h"
+#include "bug_check.h"
+#include "dbg_print.h"
 #include "assert.h"
 #include "version.h"
 
 extern PULONG   InitSafeBootMode;
 
-XEN_API
-const CHAR *
-XenVersion = MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR;
+typedef struct _XEN_DRIVER {
+    PLOG_DISPOSITION    TraceDisposition;
+    PLOG_DISPOSITION    InfoDisposition;
+} XEN_DRIVER, *PXEN_DRIVER;
+
+static XEN_DRIVER   Driver;
+
+static VOID
+DriverOutputBuffer(
+    IN  PVOID   Argument,
+    IN  PCHAR   Buffer,
+    IN  ULONG   Length
+    )
+{
+    ULONG_PTR   Port = (ULONG_PTR)Argument;
+
+    __outbytestring((USHORT)Port, (PUCHAR)Buffer, Length);
+}
+
+#define XEN_PORT    0xE9
+#define QEMU_PORT   0x12
 
 NTSTATUS
 DllInitialize(
@@ -62,26 +79,50 @@ DllInitialize(
 
     ExInitializeDriverRuntime(DrvRtPoolNxOptIn);
 
-    LogInitialize();
+    __DbgPrintEnable();
 
-    Info("%s (%s)\n",
-         MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR,
-         DAY_STR "/" MONTH_STR "/" YEAR_STR);
+    Trace("====>\n");
 
     if (*InitSafeBootMode > 0)
         goto done;
 
-    SystemGetInformation();
-
-    status = HypercallInitialize();
+    status = LogInitialize();
     if (!NT_SUCCESS(status))
         goto fail1;
 
-    status = DebugInitialize();
+    status = LogAddDisposition(LOG_LEVEL_TRACE |
+                               LOG_LEVEL_CRITICAL,
+                               DriverOutputBuffer,
+                               (PVOID)XEN_PORT,
+                               &Driver.TraceDisposition);
+    ASSERT(NT_SUCCESS(status));
+
+    status = LogAddDisposition(LOG_LEVEL_INFO |
+                               LOG_LEVEL_WARNING |
+                               LOG_LEVEL_ERROR |
+                               LOG_LEVEL_CRITICAL,
+                               DriverOutputBuffer,
+                               (PVOID)QEMU_PORT,
+                               &Driver.InfoDisposition);
+    ASSERT(NT_SUCCESS(status));
+
+    LogPrintf(LOG_LEVEL_INFO,
+              "XEN %d.%d.%d (%d) (%02d.%02d.%04d)\n",
+              MAJOR_VERSION,
+              MINOR_VERSION,
+              MICRO_VERSION,
+              BUILD_NUMBER,
+              DAY,
+              MONTH,
+              YEAR);
+
+    SystemGetInformation();
+
+    status = HypercallInitialize();
     if (!NT_SUCCESS(status))
         goto fail2;
 
-    status = DumpInitialize();
+    status = BugCheckInitialize();
     if (!NT_SUCCESS(status))
         goto fail3;
 
@@ -93,9 +134,9 @@ DllInitialize(
     if (!NT_SUCCESS(status))
         goto fail5;
 
-    UnplugInitialize();
-
 done:
+    Trace("<====\n");
+
     return STATUS_SUCCESS;
 
 fail5:
@@ -106,22 +147,28 @@ fail5:
 fail4:
     Error("fail4\n");
 
-    DumpTeardown();
+    BugCheckTeardown();
 
 fail3:
     Error("fail3\n");
 
-    DebugTeardown();
+    HypercallTeardown();
 
 fail2:
     Error("fail2\n");
 
-    HypercallTeardown();
+    LogRemoveDisposition(Driver.InfoDisposition);
+    Driver.InfoDisposition = NULL;
+
+    LogRemoveDisposition(Driver.TraceDisposition);
+    Driver.TraceDisposition = NULL;
+
+    LogTeardown();
 
 fail1:
     Error("fail1 (%08x)", status);
 
-    LogTeardown();
+    ASSERT(IsZeroMemory(&Driver, sizeof (XEN_DRIVER)));
 
     return status;
 }
@@ -131,28 +178,32 @@ DllUnload(
     VOID
     )
 {
-    Info("%s (%s)\n",
-         MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR,
-         DAY_STR "/" MONTH_STR "/" YEAR_STR);
+    Trace("====>\n");
 
     if (*InitSafeBootMode > 0)
         goto done;
 
-    UnplugTeardown();
-
     ProcessTeardown();
 
     ModuleTeardown();
 
-    DumpTeardown();
-
-    DebugTeardown();
+    BugCheckTeardown();
 
     HypercallTeardown();
 
-done:
+    LogRemoveDisposition(Driver.InfoDisposition);
+    Driver.InfoDisposition = NULL;
+
+    LogRemoveDisposition(Driver.TraceDisposition);
+    Driver.TraceDisposition = NULL;
+
     LogTeardown();
 
+done:
+    ASSERT(IsZeroMemory(&Driver, sizeof (XEN_DRIVER)));
+
+    Trace("<====\n");
+
     return STATUS_SUCCESS;
 }
 
diff --git a/src/xen/dump.c b/src/xen/dump.c
deleted file mode 100644 (file)
index 1bc8099..0000000
+++ /dev/null
@@ -1,245 +0,0 @@
-/* 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 <xen.h>
-
-#include "dump.h"
-#include "log.h"
-#include "assert.h"
-
-//
-// Crash dumps via QEMU
-//
-// To enable you need to customize /opt/xensource/libexec/qemu-dm-wrapper in dom0 to add the following
-// arguments to the qemu command line:
-//
-// -dumpdir <directory> -dumpquota <quota>
-//
-// <directory> is best pointed at an empty directory. Files will be created with numeric names starting at 0.
-// <quota> should be the total size in MB of all possible crash dump files. I.e. once sufficient crash dumps have
-// occurred to fill this quota, no more will be allowed until sufficient space is cleared in <directory>. This is
-// to prevent dump files (which can be very large) from overrunning dom0's filesystem.
-//
-
-static KBUGCHECK_REASON_CALLBACK_RECORD DumpBugCheckReasonCallbackRecord;
-
-VOID
-DumpTeardown(
-    VOID
-    )
-{
-    (VOID) KeDeregisterBugCheckReasonCallback(&DumpBugCheckReasonCallbackRecord);
-}
-
-static PVOID    PortEB = ((PVOID)(ULONG_PTR)0xeb);
-static PVOID    PortEC = ((PVOID)(ULONG_PTR)0xec);
-
-#define DUMP_VERSION        0x01
-
-#define DUMP_IO_REGISTERED  0x00
-#define DUMP_IO_OPEN        0x01
-#define DUMP_IO_CLOSE       0x02
-
-static KBUGCHECK_DUMP_IO_TYPE   DumpIoType = KbDumpIoInvalid;
-
-static FORCEINLINE VOID
-__DumpPortOpen(
-    VOID
-    )
-{
-    Info("====>\n");
-    WRITE_PORT_UCHAR(PortEB, DUMP_IO_OPEN);   
-    Info("<====\n");
-}
-
-static FORCEINLINE VOID
-__DumpPortClose(
-    VOID
-    )
-{
-    Info("====>\n");
-    WRITE_PORT_UCHAR(PortEB, DUMP_IO_CLOSE);   
-    Info("<====\n");
-}
-
-#define IS_PAGE_ALIGNED(_Address)   (((ULONG_PTR)(_Address) & (PAGE_SIZE - 1)) == 0)
-
-static VOID
-DumpPortWrite(
-    IN  ULONG64         Offset,
-    IN  PVOID           Buffer,
-    IN  ULONG           Length
-    )
-{
-    PHYSICAL_ADDRESS    Address;
-
-    ASSERT(Offset == (ULONG64)-1);
-    ASSERT(IS_PAGE_ALIGNED(Buffer));
-    ASSERT(IS_PAGE_ALIGNED(Length));
-
-    //
-    // Sometimes Windows passes us virtual addresses, sometimes it passes
-    // physical addresses. It doesn't tell us which it's handing us, and
-    // how this plays with PAE is anybody's guess.
-    //
-    Address = MmGetPhysicalAddress(Buffer);
-    if (Address.QuadPart == 0)
-        Address.QuadPart = (ULONG_PTR)Buffer;
-
-    Address.QuadPart >>= PAGE_SHIFT;
-    ASSERT3U(Address.HighPart, ==, 0);
-
-    for (Length >>= PAGE_SHIFT; Length != 0; Length--)
-        WRITE_PORT_ULONG(PortEC, Address.LowPart++);
-}
-
-static const CHAR *
-DumpIoTypeName(
-    IN  KBUGCHECK_DUMP_IO_TYPE  Type
-    )
-{
-#define _IO_TYPE_NAME(_Type)    \
-        case KbDumpIo ## _Type: \
-            return #_Type;
-
-    switch (Type) {
-    _IO_TYPE_NAME(Invalid);
-    _IO_TYPE_NAME(Header);
-    _IO_TYPE_NAME(Body);
-    _IO_TYPE_NAME(SecondaryData);
-    _IO_TYPE_NAME(Complete);
-    default:
-        break;
-    }
-
-    return "UNKNOWN";
-
-#undef  _IO_TYPE_NAME
-}
-
-KBUGCHECK_REASON_CALLBACK_ROUTINE   DumpBugCheckReasonCallback;
-
-VOID
-DumpBugCheckReasonCallback(
-    IN  KBUGCHECK_CALLBACK_REASON           Reason,
-    IN  PKBUGCHECK_REASON_CALLBACK_RECORD   Record,
-    IN  OUT PVOID                           ReasonSpecificData,
-    IN  ULONG                               ReasonSpecificDataLength 
-    )
-{   
-    PKBUGCHECK_DUMP_IO                      DumpIo = (PKBUGCHECK_DUMP_IO)ReasonSpecificData;
-
-    UNREFERENCED_PARAMETER(ReasonSpecificDataLength);
-
-    ASSERT3U(Reason, ==, KbCallbackDumpIo);
-    ASSERT3P(Record, ==, &DumpBugCheckReasonCallbackRecord);
-    ASSERT(DumpIo != NULL);
-    
-    switch (DumpIo->Type) {
-        case KbDumpIoHeader:
-            ASSERT(DumpIoType == KbDumpIoInvalid ||
-                   DumpIoType == KbDumpIoHeader);
-            DumpIoType = KbDumpIoHeader;
-                 
-            __DumpPortOpen();
-
-            DumpPortWrite(DumpIo->Offset,
-                          DumpIo->Buffer,
-                          DumpIo->BufferLength);
-            break;
-
-        case KbDumpIoBody:
-            ASSERT(DumpIoType == KbDumpIoHeader ||
-                   DumpIoType == KbDumpIoBody);
-            DumpIoType = KbDumpIoBody;
-
-            DumpPortWrite(DumpIo->Offset,
-                          DumpIo->Buffer,
-                          DumpIo->BufferLength);
-            break;
-
-        case KbDumpIoSecondaryData:
-            ASSERT(DumpIoType == KbDumpIoBody ||
-                   DumpIoType == KbDumpIoSecondaryData);
-            DumpIoType = KbDumpIoSecondaryData;
-                 
-            DumpPortWrite(DumpIo->Offset,
-                          DumpIo->Buffer,
-                          DumpIo->BufferLength);
-            break;
-
-        case KbDumpIoComplete:
-            ASSERT3U(DumpIoType, ==, KbDumpIoSecondaryData);
-            DumpIoType = KbDumpIoComplete;
-            
-            __DumpPortClose();
-            break;
-        
-        case KbDumpIoInvalid:
-        default:
-            ASSERT(FALSE);
-            break;  
-    }
-}
-
-NTSTATUS
-DumpInitialize(
-    VOID
-    )
-{
-    UCHAR       Version;
-    NTSTATUS    status;
-
-    Version = READ_PORT_UCHAR(PortEB);
-
-    if (Version != DUMP_VERSION)
-        goto done;
-
-    KeInitializeCallbackRecord(&DumpBugCheckReasonCallbackRecord);
-
-    status = STATUS_UNSUCCESSFUL;
-    if (!KeRegisterBugCheckReasonCallback(&DumpBugCheckReasonCallbackRecord,
-                                          DumpBugCheckReasonCallback,
-                                          KbCallbackDumpIo,
-                                          (PUCHAR)__MODULE__))
-        goto fail1;
-
-    Info("callback registered\n");
-
-done:
-    return STATUS_SUCCESS;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
-}
diff --git a/src/xen/dump.h b/src/xen/dump.h
deleted file mode 100644 (file)
index 6a1f113..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/* 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 _XEN_DUMP_H
-#define _XEN_DUMP_H
-
-#include <ntddk.h>
-
-extern NTSTATUS
-DumpInitialize(
-    VOID);
-
-extern VOID
-DumpTeardown(
-    VOID
-    );
-
-#endif  // _XEN_DUMP_H
index 12f301d76db7ccd6236ecaa57f5d0c138e6033d9..9e05eff4a4f0f2acf102d5633c5ea33f38ded577 100644 (file)
@@ -35,7 +35,7 @@
 #include <xen.h>
 
 #include "hypercall.h"
-#include "log.h"
+#include "dbg_print.h"
 #include "assert.h"
 
 static FORCEINLINE LONG_PTR
index a2043bcba90db4f3ec603e882ccd1b8a8ca2fef5..a463a8ced5c9b52c44ec993eb89d76f50d9b6073 100644 (file)
@@ -35,7 +35,7 @@
 #include <xen.h>
 
 #include "hypercall.h"
-#include "log.h"
+#include "dbg_print.h"
 #include "assert.h"
 
 static FORCEINLINE LONG_PTR
diff --git a/src/xen/high.h b/src/xen/high.h
deleted file mode 100644 (file)
index 272b237..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/* 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 _XEN_HIGH_H
-#define _XEN_HIGH_H
-
-#include <ntddk.h>
-
-#pragma warning(disable:4127)   // conditional expression is constant
-
-typedef LONG    HIGH_LOCK, *PHIGH_LOCK;
-
-#define LOCK_MAGIC  0xFEEDFACE
-
-static FORCEINLINE
-__drv_maxIRQL(HIGH_LEVEL)
-__drv_raisesIRQL(HIGH_LEVEL)
-__drv_savesIRQL
-KIRQL
-__AcquireHighLock(
-    IN  PHIGH_LOCK  Lock
-    )
-{
-    KIRQL           Irql;
-
-    KeRaiseIrql(HIGH_LEVEL, &Irql);
-
-    while (InterlockedCompareExchange(Lock, LOCK_MAGIC, 0) != 0)
-        _mm_pause();
-
-    KeMemoryBarrier();
-
-    return Irql;
-}
-
-#define AcquireHighLock(_Lock, _Irql)               \
-        do {                                        \
-            *(_Irql) = __AcquireHighLock(_Lock);    \
-        } while (FALSE)
-
-static FORCEINLINE
-__drv_maxIRQL(HIGH_LEVEL)
-__drv_requiresIRQL(HIGH_LEVEL)
-VOID
-ReleaseHighLock(
-    IN  PHIGH_LOCK                  Lock,
-    IN  __drv_restoresIRQL KIRQL    Irql
-    )
-{
-    KeMemoryBarrier();
-
-    InterlockedExchange(Lock, 0);
-    KeLowerIrql(Irql);
-}
-
-static FORCEINLINE
-VOID
-InitializeHighLock(
-    IN  PHIGH_LOCK  Lock
-    )
-{
-    RtlZeroMemory(&Lock, sizeof (HIGH_LOCK));
-}
-
-#endif  // _XEN_HIGH_H
index 97a613c17f3328f574d17b05143a1b132f8f71b6..f31e5d0469d2f2fbac29af2f76bf03ec73d04ee1 100644 (file)
@@ -35,7 +35,7 @@
 #include <xen.h>
 
 #include "hypercall.h"
-#include "log.h"
+#include "dbg_print.h"
 #include "assert.h"
 
 static FORCEINLINE LONG_PTR
index 488634aadc2c0583caecf3aa82690ffc48e1e9ca..a35b461420e52e61832552c657da8a6966eee15c 100644 (file)
@@ -33,7 +33,7 @@
 #include <xen.h>
 
 #include "hypercall.h"
-#include "log.h"
+#include "dbg_print.h"
 #include "assert.h"
 
 #define MAXIMUM_HYPERCALL_PFN_COUNT 2
index a1a116aff579fa1dbab713da5889cdbfcb55336b..22cd15b613854dc00416c8b2131ea5a83ca78434 100644 (file)
@@ -35,7 +35,6 @@
 
 #include <ntddk.h>
 #include <stdlib.h>
-#include <xen.h>
 
 #include "log.h"
 #include "assert.h"
 
 #define LOG_BUFFER_SIZE 256
 
-static UCHAR        LogBuffer[LOG_BUFFER_SIZE];
-static ULONG        LogOffset;
-static HIGH_LOCK    LogLock;
+struct _LOG_DISPOSITION {
+    LOG_LEVEL   Mask;
+    VOID        (*Function)(PVOID, PCHAR, ULONG);
+    PVOID       Argument;
+};
+
+#define LOG_MAXIMUM_DISPOSITION 8
+
+typedef struct _LOG_CONTEXT {
+    LONG            References;
+    BOOLEAN         Enabled;
+    CHAR            Buffer[LOG_BUFFER_SIZE];
+    ULONG           Offset;
+    LOG_DISPOSITION Disposition[LOG_MAXIMUM_DISPOSITION];
+    HIGH_LOCK       Lock;
+} LOG_CONTEXT, *PLOG_CONTEXT;
+
+static LOG_CONTEXT  LogContext;
 
 static FORCEINLINE
 __drv_maxIRQL(HIGH_LEVEL)
@@ -53,39 +67,45 @@ __drv_raisesIRQL(HIGH_LEVEL)
 __drv_savesIRQL
 KIRQL
 __LogAcquireBuffer(
-    VOID
+    IN  PLOG_CONTEXT    Context
     )
 {
-    return __AcquireHighLock(&LogLock);
+    return __AcquireHighLock(&Context->Lock);
 }
 
-#define LOG_XEN_PORT    0xE9
-#define LOG_QEMU_PORT   0x12
-
 static DECLSPEC_NOINLINE VOID
 __drv_maxIRQL(HIGH_LEVEL)
 __drv_requiresIRQL(HIGH_LEVEL)
 __LogReleaseBuffer(
-    IN  USHORT                      Port,
+    IN  PLOG_CONTEXT                Context,
+    IN  LOG_LEVEL                   Level,
     IN  __drv_restoresIRQL KIRQL    Irql
     )
 {
-    __outbytestring(Port, LogBuffer, LogOffset);
+    ULONG                           Index;
 
-    RtlZeroMemory(LogBuffer, LogOffset);
-    LogOffset = 0;
+    for (Index = 0; Index < LOG_MAXIMUM_DISPOSITION; Index++) {
+        PLOG_DISPOSITION    Disposition = &Context->Disposition[Index];
 
-    ReleaseHighLock(&LogLock, Irql);
+        if (Level & Disposition->Mask)
+            Disposition->Function(Disposition->Argument, Context->Buffer, Context->Offset);
+    }
+
+    RtlZeroMemory(Context->Buffer, Context->Offset);
+    Context->Offset = 0;
+
+    ReleaseHighLock(&Context->Lock, Irql);
 }
 
 static FORCEINLINE VOID
 __LogPut(
-    IN  CHAR    Character
+    IN  PLOG_CONTEXT    Context,
+    IN  CHAR            Character
     )
 {
-    ASSERT(LogOffset < LOG_BUFFER_SIZE);
+    ASSERT(Context->Offset < LOG_BUFFER_SIZE);
 
-    LogBuffer[LogOffset++] = Character;
+    Context->Buffer[Context->Offset++] = Character;
 }
 
 static DECLSPEC_NOINLINE PCHAR
@@ -149,13 +169,14 @@ LogFormatNumber(
         } while (FALSE)
 
 static DECLSPEC_NOINLINE VOID
-LogCchVPrintf(
-    IN  LONG        Count,
-    IN  const CHAR  *Format,
-    IN  va_list     Arguments
+LogWriteBuffer(
+    IN  PLOG_CONTEXT    Context, 
+    IN  LONG            Count,
+    IN  const CHAR      *Format,
+    IN  va_list         Arguments
     )
 {
-    CHAR            Character;
+    CHAR                Character;
 
     while ((Character = *Format++) != '\0') {
         UCHAR   Pad = 0;
@@ -165,7 +186,7 @@ LogCchVPrintf(
         BOOLEAN OppositeJustification = FALSE;
         
         if (Character != '%') {
-            __LogPut(Character);
+            __LogPut(Context, Character);
             goto loop;
         }
 
@@ -214,13 +235,13 @@ LogCchVPrintf(
                 WCHAR   Value;
                 Value = va_arg(Arguments, WCHAR);
 
-                __LogPut((CHAR)Value);
+                __LogPut(Context, (CHAR)Value);
             } else { 
                 CHAR    Value;
 
                 Value = va_arg(Arguments, CHAR);
 
-                __LogPut(Value);
+                __LogPut(Context, Value);
             }
             break;
         }
@@ -247,15 +268,15 @@ LogCchVPrintf(
             Length = (ULONG)strlen(Buffer);
             if (!OppositeJustification) {
                 while (Pad > Length) {
-                    __LogPut((ZeroPrefix) ? '0' : ' ');
+                    __LogPut(Context, (ZeroPrefix) ? '0' : ' ');
                     --Pad;
                 }
             }
             for (Index = 0; Index < Length; Index++)
-                __LogPut(Buffer[Index]);
+                __LogPut(Context, Buffer[Index]);
             if (OppositeJustification) {
                 while (Pad > Length) {
-                    __LogPut(' ');
+                    __LogPut(Context, ' ');
                     --Pad;
                 }
             }
@@ -275,17 +296,17 @@ LogCchVPrintf(
 
                 if (OppositeJustification) {
                     while (Pad > Length) {
-                        __LogPut(' ');
+                        __LogPut(Context, ' ');
                         --Pad;
                     }
                 }
 
                 for (Index = 0; Index < Length; Index++)
-                    __LogPut((CHAR)Value[Index]);
+                    __LogPut(Context, (CHAR)Value[Index]);
 
                 if (!OppositeJustification) {
                     while (Pad > Length) {
-                        __LogPut(' ');
+                        __LogPut(Context, ' ');
                         --Pad;
                     }
                 }
@@ -301,17 +322,17 @@ LogCchVPrintf(
 
                 if (OppositeJustification) {
                     while (Pad > Length) {
-                        __LogPut(' ');
+                        __LogPut(Context, ' ');
                         --Pad;
                     }
                 }
 
                 for (Index = 0; Index < Length; Index++)
-                    __LogPut(Value[Index]);
+                    __LogPut(Context, Value[Index]);
 
                 if (!OppositeJustification) {
                     while (Pad > Length) {
-                        __LogPut(' ');
+                        __LogPut(Context, ' ');
                         --Pad;
                     }
                 }
@@ -336,17 +357,17 @@ LogCchVPrintf(
 
                 if (OppositeJustification) {
                     while (Pad > Length) {
-                        __LogPut(' ');
+                        __LogPut(Context, ' ');
                         --Pad;
                     }
                 }
 
                 for (Index = 0; Index < Length; Index++)
-                    __LogPut((CHAR)Buffer[Index]);
+                    __LogPut(Context, (CHAR)Buffer[Index]);
 
                 if (!OppositeJustification) {
                     while (Pad > Length) {
-                        __LogPut(' ');
+                        __LogPut(Context, ' ');
                         --Pad;
                     }
                 }
@@ -366,17 +387,17 @@ LogCchVPrintf(
 
                 if (OppositeJustification) {
                     while (Pad > Length) {
-                        __LogPut(' ');
+                        __LogPut(Context, ' ');
                         --Pad;
                     }
                 }
 
                 for (Index = 0; Index < Length; Index++)
-                    __LogPut(Buffer[Index]);
+                    __LogPut(Context, Buffer[Index]);
 
                 if (!OppositeJustification) {
                     while (Pad > Length) {
-                        __LogPut(' ');
+                        __LogPut(Context, ' ');
                         --Pad;
                     }
                 }
@@ -385,7 +406,7 @@ LogCchVPrintf(
             break;
         }
         default:
-            __LogPut(Character);
+            __LogPut(Context, Character);
             break;
         }
 
@@ -395,127 +416,43 @@ loop:
     }
 }
 
-static FORCEINLINE VOID
-__LogXenCchVPrintf(
-    IN  ULONG       Count,
-    IN  const CHAR  *Format,
-    IN  va_list     Arguments
-    )
-{
-    KIRQL           Irql;
-
-    Irql = __LogAcquireBuffer();
-
-    LogCchVPrintf(__min(Count, LOG_BUFFER_SIZE),
-                  Format,
-                  Arguments);
-
-    __LogReleaseBuffer(LOG_XEN_PORT, Irql);
-}
-
-
-XEN_API
-DECLSPEC_NOINLINE
-VOID
-LogXenCchVPrintf(
-    IN  ULONG       Count,
-    IN  const CHAR  *Format,
-    IN  va_list     Arguments
-    )
-{
-    __LogXenCchVPrintf(Count, Format, Arguments);
-}
-
 XEN_API
 VOID
-LogXenCchPrintf(
-    IN  ULONG       Count,
-    IN  const CHAR  *Format,
-    ...
-    )
-{
-    va_list         Arguments;
-
-    va_start(Arguments, Format);
-    __LogXenCchVPrintf(Count, Format, Arguments);
-    va_end(Arguments);
-}
-
-static FORCEINLINE VOID
-__LogXenVPrintf(
-    IN  const CHAR  *Format,
-    IN  va_list     Arguments
-    )
-{
-    KIRQL           Irql;
-
-    Irql = __LogAcquireBuffer();
-
-    LogCchVPrintf(LOG_BUFFER_SIZE,
-                  Format,
-                  Arguments);
-
-    __LogReleaseBuffer(LOG_XEN_PORT, Irql);
-}
-
-XEN_API
-DECLSPEC_NOINLINE
-VOID
-LogXenVPrintf(
-    IN  const CHAR  *Format,
-    IN  va_list     Arguments
-    )
-{
-    __LogXenVPrintf(Format, Arguments);
-}
-
-XEN_API
-VOID
-LogXenPrintf(
-    IN  const CHAR  *Format,
-    ...
-    )
-{
-    va_list         Arguments;
-
-    va_start(Arguments, Format);
-    __LogXenVPrintf(Format, Arguments);
-    va_end(Arguments);
-}
-
-static FORCEINLINE VOID
-__LogQemuCchVPrintf(
+LogCchVPrintf(
+    IN  LOG_LEVEL   Level,
     IN  ULONG       Count,
     IN  const CHAR  *Format,
     IN  va_list     Arguments
     )
 {
+    PLOG_CONTEXT    Context = &LogContext;
     KIRQL           Irql;
 
-    Irql = __LogAcquireBuffer();
+    Irql = __LogAcquireBuffer(Context);
 
-    LogCchVPrintf(__min(Count, LOG_BUFFER_SIZE),
-                  Format,
-                  Arguments);
+    LogWriteBuffer(Context,
+                   __min(Count, LOG_BUFFER_SIZE),
+                   Format,
+                   Arguments);
 
-    __LogReleaseBuffer(LOG_QEMU_PORT, Irql);
+    __LogReleaseBuffer(Context, Level, Irql);
 }
 
 XEN_API
-DECLSPEC_NOINLINE
 VOID
-LogQemuCchVPrintf(
-    IN  ULONG       Count,
+LogVPrintf(
+    IN  LOG_LEVEL   Level,
     IN  const CHAR  *Format,
     IN  va_list     Arguments
     )
 {
-    __LogQemuCchVPrintf(Count, Format, Arguments);
+    LogCchVPrintf(Level, LOG_BUFFER_SIZE, Format, Arguments);
 }
 
 XEN_API
 VOID
-LogQemuCchPrintf(
+LogCchPrintf(
+    IN  LOG_LEVEL   Level,
     IN  ULONG       Count,
     IN  const CHAR  *Format,
     ...
@@ -524,41 +461,14 @@ LogQemuCchPrintf(
     va_list         Arguments;
 
     va_start(Arguments, Format);
-    __LogQemuCchVPrintf(Count, Format, Arguments);
+    LogCchVPrintf(Level, Count, Format, Arguments);
     va_end(Arguments);
 }
 
-static FORCEINLINE VOID
-__LogQemuVPrintf(
-    IN  const CHAR  *Format,
-    IN  va_list     Arguments
-    )
-{
-    KIRQL           Irql;
-
-    Irql = __LogAcquireBuffer();
-
-    LogCchVPrintf(LOG_BUFFER_SIZE,
-                  Format,
-                  Arguments);
-
-    __LogReleaseBuffer(LOG_QEMU_PORT, Irql);
-}
-
-XEN_API
-DECLSPEC_NOINLINE
-VOID
-LogQemuVPrintf(
-    IN  const CHAR  *Format,
-    IN  va_list     Arguments
-    )
-{
-    __LogQemuVPrintf(Format, Arguments);
-}
-
 XEN_API
 VOID
-LogQemuPrintf(
+LogPrintf(
+    IN  LOG_LEVEL   Level,
     IN  const CHAR  *Format,
     ...
     )
@@ -566,7 +476,7 @@ LogQemuPrintf(
     va_list         Arguments;
 
     va_start(Arguments, Format);
-    __LogQemuVPrintf(Format, Arguments);
+    LogCchVPrintf(Level, LOG_BUFFER_SIZE, Format, Arguments);
     va_end(Arguments);
 }
 
@@ -577,119 +487,153 @@ typedef VOID
     ULONG           Level
     );
 
-static VOID
+static DECLSPEC_NOINLINE VOID
 LogDebugPrint(
     IN  PANSI_STRING    Ansi,
     IN  ULONG           ComponentId,
     IN  ULONG           Level
     )
 {
+    PLOG_CONTEXT        Context = &LogContext;
+    KIRQL               Irql;
+    ULONG               Index;
+
     if (Ansi->Length == 0 || Ansi->Buffer == NULL)
         return;
 
-    if (ComponentId == DPFLTR_IHVDRIVER_ID) {
-        switch (Level) {
-        case DPFLTR_ERROR_LEVEL:
-            LogQemuCchPrintf(Ansi->Length, Ansi->Buffer);
-            break;
-
-        case DPFLTR_WARNING_LEVEL:
-            LogQemuCchPrintf(Ansi->Length, Ansi->Buffer);
-            break;
+    if (ComponentId != DPFLTR_IHVDRIVER_ID)
+        return;
 
-        case DPFLTR_INFO_LEVEL:
-            LogQemuCchPrintf(Ansi->Length, Ansi->Buffer);
-            break;
+    AcquireHighLock(&Context->Lock, &Irql);
 
-        case DPFLTR_TRACE_LEVEL:
-            LogXenCchPrintf(Ansi->Length, Ansi->Buffer);
-            break;
+    for (Index = 0; Index < LOG_MAXIMUM_DISPOSITION; Index++) {
+        PLOG_DISPOSITION    Disposition = &Context->Disposition[Index];
 
-        default:
-            break;
-        }
-    } else {
-        LogXenCchPrintf(Ansi->Length, Ansi->Buffer);
+        if ((1 << Level) & Disposition->Mask)
+            Disposition->Function(Disposition->Argument, Ansi->Buffer, Ansi->Length);
     }
-}
 
-BOOLEAN CallbackInstalled;
-
-#define LOG_ENABLE_FILTER(_Id, _Level)                              \
-        do {                                                        \
-            DbgSetDebugFilterState((_Id), (_Level), TRUE);          \
-            DbgPrintEx((_Id),                                       \
-                       (_Level),                                    \
-                       "DbgPrint(%s, %s) interception enabled\n",   \
-/**/                   #_Id,                                        \
-/**/                   #_Level);                                    \
-        } while (FALSE)
+    ReleaseHighLock(&Context->Lock, Irql);
+}
 
-static FORCEINLINE VOID
-__LogEnable(
+VOID
+LogTeardown(
     VOID
     )
 {
-    NTSTATUS    status;
+    PLOG_CONTEXT    Context = &LogContext;
 
-    if (!CallbackInstalled) {
-        status = DbgSetDebugPrintCallback(LogDebugPrint, TRUE);
-        CallbackInstalled = NT_SUCCESS(status) ? TRUE : FALSE;
+    if (Context->Enabled) {
+        (VOID) DbgSetDebugPrintCallback(LogDebugPrint, FALSE); 
+        Context->Enabled = FALSE;
     }
 
-    LOG_ENABLE_FILTER(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL);
-    LOG_ENABLE_FILTER(DPFLTR_IHVDRIVER_ID, DPFLTR_WARNING_LEVEL);
-    LOG_ENABLE_FILTER(DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL);
-    LOG_ENABLE_FILTER(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL);
+    RtlZeroMemory(&Context->Lock, sizeof (HIGH_LOCK));
 
-    LOG_ENABLE_FILTER(DPFLTR_DEFAULT_ID, DPFLTR_ERROR_LEVEL);
-    LOG_ENABLE_FILTER(DPFLTR_DEFAULT_ID, DPFLTR_WARNING_LEVEL);
-    LOG_ENABLE_FILTER(DPFLTR_DEFAULT_ID, DPFLTR_TRACE_LEVEL);
-    LOG_ENABLE_FILTER(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL);
-}
+    (VOID) InterlockedDecrement(&Context->References);
 
-XEN_API
-VOID
-LogEnable(
-    VOID
-    )
-{
-    __LogEnable();
+    ASSERT(IsZeroMemory(Context, sizeof (LOG_CONTEXT)));
 }
 
-static FORCEINLINE VOID
-__LogDisable(
-    VOID
+NTSTATUS
+LogAddDisposition(
+    IN  LOG_LEVEL           Mask,
+    IN  VOID                (*Function)(PVOID, PCHAR, ULONG),
+    IN  PVOID               Argument OPTIONAL,
+    OUT PLOG_DISPOSITION    *Disposition
     )
 {
-    if (CallbackInstalled) {
-        (VOID) DbgSetDebugPrintCallback(LogDebugPrint, FALSE); 
-        CallbackInstalled = FALSE;
+    PLOG_CONTEXT            Context = &LogContext;
+    KIRQL                   Irql;
+    ULONG                   Index;
+    NTSTATUS                status;
+
+    status = STATUS_INVALID_PARAMETER;
+    if (Mask == 0)
+        goto fail1;
+
+    AcquireHighLock(&Context->Lock, &Irql);
+
+    status = STATUS_UNSUCCESSFUL;
+    for (Index = 0; Index < LOG_MAXIMUM_DISPOSITION; Index++) {
+        *Disposition = &Context->Disposition[Index];
+
+        if ((*Disposition)->Mask == 0) {
+            (*Disposition)->Mask = Mask;
+            (*Disposition)->Function = Function;
+            (*Disposition)->Argument = Argument;
+
+            status = STATUS_SUCCESS;
+            break;
+        }
     }
-}
 
-XEN_API
-VOID
-LogDisable(
-    VOID
-    )
-{
-    __LogDisable();
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    ReleaseHighLock(&Context->Lock, Irql);
+
+    return STATUS_SUCCESS;
+
+fail2:
+    Error("fail2\n");
+
+    *Disposition = NULL;
+
+    ReleaseHighLock(&Context->Lock, Irql);
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
 }
 
-VOID
-LogTeardown(
-    VOID
+extern VOID
+LogRemoveDisposition(
+    IN  PLOG_DISPOSITION    Disposition
     )
 {
-    __LogDisable();
+    PLOG_CONTEXT            Context = &LogContext;
+    KIRQL                   Irql;
+    ULONG                   Index;
+
+    AcquireHighLock(&Context->Lock, &Irql);
+
+    for (Index = 0; Index < LOG_MAXIMUM_DISPOSITION; Index++) {
+        if (&Context->Disposition[Index] != Disposition)
+            continue;
+
+        RtlZeroMemory(&Context->Disposition[Index], sizeof (LOG_DISPOSITION));
+    }
+
+    ReleaseHighLock(&Context->Lock, Irql);
 }
 
-VOID
+NTSTATUS
 LogInitialize(
     VOID)
 {
-    InitializeHighLock(&LogLock);
+    PLOG_CONTEXT    Context = &LogContext;
+    ULONG           References;
+    NTSTATUS        status;
+
+    References = InterlockedIncrement(&Context->References);
+
+    status = STATUS_OBJECTID_EXISTS;
+    if (References != 1)
+        goto fail1;
+
+    InitializeHighLock(&Context->Lock);
+
+    ASSERT(!Context->Enabled);
+
+    status = DbgSetDebugPrintCallback(LogDebugPrint, TRUE);
+    Context->Enabled = NT_SUCCESS(status) ? TRUE : FALSE;
+
+    return STATUS_SUCCESS;
+
+fail1:
+    Error("fail1 (%08x)\n", status);
 
-    __LogEnable();
+    return status;
 }
index 3a2d80b0c56a42c368fdd3129f64c9ba9c573dae..67b4f16d9343f01d963265107cc862528c2e0f49 100644 (file)
 #ifndef _XEN_LOG_H
 #define _XEN_LOG_H
 
-#define __MODULE__ "XEN"
+#include <xen.h>
 
-#include <ntddk.h>
-#include <stdarg.h>
+typedef struct _LOG_DISPOSITION LOG_DISPOSITION, *PLOG_DISPOSITION;
 
-#pragma warning(disable:4127)   // conditional expression is constant
-
-static __inline VOID
-__Error(
-    IN  const CHAR  *Prefix,
-    IN  const CHAR  *Format,
-    ...
-    )
-{
-    va_list         Arguments;
-
-    va_start(Arguments, Format);
-
-#pragma prefast(suppress:6001) // Using uninitialized memory
-    vDbgPrintExWithPrefix(Prefix,
-                          DPFLTR_IHVDRIVER_ID,
-                          DPFLTR_ERROR_LEVEL,
-                          Format,
-                          Arguments);
-    va_end(Arguments);
-}
-
-#define Error(...)  \
-        __Error(__MODULE__ "|" __FUNCTION__ ": ", __VA_ARGS__)
-
-static __inline VOID
-__Warning(
-    IN  const CHAR  *Prefix,
-    IN  const CHAR  *Format,
-    ...
-    )
-{
-    va_list         Arguments;
-
-    va_start(Arguments, Format);
-
-#pragma prefast(suppress:6001) // Using uninitialized memory
-    vDbgPrintExWithPrefix(Prefix,
-                          DPFLTR_IHVDRIVER_ID,
-                          DPFLTR_WARNING_LEVEL,
-                          Format,
-                          Arguments);
-    va_end(Arguments);
-}
-
-#define Warning(...)  \
-        __Warning(__MODULE__ "|" __FUNCTION__ ": ", __VA_ARGS__)
-
-#if DBG
-static __inline VOID
-__Trace(
-    IN  const CHAR  *Prefix,
-    IN  const CHAR  *Format,
-    ...
-    )
-{
-    va_list         Arguments;
-
-    va_start(Arguments, Format);
-
-#pragma prefast(suppress:6001) // Using uninitialized memory
-    vDbgPrintExWithPrefix(Prefix,
-                          DPFLTR_IHVDRIVER_ID,
-                          DPFLTR_TRACE_LEVEL,
-                          Format,
-                          Arguments);
-    va_end(Arguments);
-}
-
-#define Trace(...)  \
-        __Trace(__MODULE__ "|" __FUNCTION__ ": ", __VA_ARGS__)
-#else   // DBG
-#define Trace(...)  (VOID)(__VA_ARGS__)
-#endif  // DBG
-
-static __inline VOID
-__Info(
-    IN  const CHAR  *Prefix,
-    IN  const CHAR  *Format,
-    ...
-    )
-{
-    va_list         Arguments;
-
-    va_start(Arguments, Format);
-
-#pragma prefast(suppress:6001) // Using uninitialized memory
-    vDbgPrintExWithPrefix(Prefix,
-                          DPFLTR_IHVDRIVER_ID,
-                          DPFLTR_INFO_LEVEL,
-                          Format,
-                          Arguments);
-    va_end(Arguments);
-}
-
-#define Info(...)  \
-        __Info(__MODULE__ "|"  __FUNCTION__ ": ", __VA_ARGS__)
+extern NTSTATUS
+LogAddDisposition(
+    IN  LOG_LEVEL           Mask,
+    IN  VOID                (*Function)(PVOID, PCHAR, ULONG),
+    IN  PVOID               Argument OPTIONAL,
+    OUT PLOG_DISPOSITION    *Disposition
+    );
 
 extern VOID
+LogRemoveDisposition(
+    IN  PLOG_DISPOSITION    Disposition
+    );
+
+extern NTSTATUS
 LogInitialize(
-    VOID);
+    VOID
+    );
 
 extern VOID
 LogTeardown(
index a1760b45e01b8c9f0d37b2bc29a9a22cd2fe294c..fdae0652714c671b5539981d88787b2d6d3329b0 100644 (file)
@@ -35,7 +35,7 @@
 #include <xen.h>
 
 #include "hypercall.h"
-#include "log.h"
+#include "dbg_print.h"
 #include "assert.h"
 
 static FORCEINLINE LONG_PTR
index 21de52c4c2849a77f9d427c675399abf2fddf931..6c9b9fc46a2048bb8c4f7c613fe557c8c066558c 100644 (file)
  * SUCH DAMAGE.
  */
 
-#define XEN_API   __declspec(dllexport)
+#define XEN_API __declspec(dllexport)
 
 #include <ntddk.h>
 #include <ntstrsafe.h>
 #include <aux_klib.h>
-#include <xen.h>
 #include <util.h>
 
 #include "high.h"
 #include "module.h"
-#include "log.h"
+#include "dbg_print.h"
 #include "assert.h"
 
 #define MODULE_TAG   'UDOM'
@@ -51,9 +50,14 @@ typedef struct _MODULE {
     CHAR        Name[AUX_KLIB_MODULE_PATH_LEN];
 } MODULE, *PMODULE;
 
-LIST_ENTRY  ModuleList;
-PLIST_ENTRY ModuleCursor = &ModuleList;
-HIGH_LOCK   ModuleLock;
+typedef struct _MODULE_CONTEXT {
+    LONG        References;
+    LIST_ENTRY  List;
+    PLIST_ENTRY Cursor;
+    HIGH_LOCK   Lock;
+} MODULE_CONTEXT, *PMODULE_CONTEXT;
+
+static MODULE_CONTEXT   ModuleContext;
 
 static FORCEINLINE PVOID
 __ModuleAllocate(
@@ -73,28 +77,28 @@ __ModuleFree(
 
 static FORCEINLINE VOID
 __ModuleAudit(
-    VOID
+    IN  PMODULE_CONTEXT Context
     )
 {
-    if (!IsListEmpty(&ModuleList)) {
+    if (!IsListEmpty(&Context->List)) {
         PLIST_ENTRY ListEntry;
         BOOLEAN     FoundCursor;
 
         FoundCursor = FALSE;
 
-        for (ListEntry = ModuleList.Flink;
-             ListEntry != &ModuleList;
+        for (ListEntry = Context->List.Flink;
+             ListEntry != &Context->List;
              ListEntry = ListEntry->Flink) {
             PMODULE Module;
 
-            if (ListEntry == ModuleCursor)
+            if (ListEntry == Context->Cursor)
                 FoundCursor = TRUE;
 
             Module = CONTAINING_RECORD(ListEntry, MODULE, ListEntry);
 
             ASSERT(Module->Start < Module->End);
 
-            if (ListEntry->Flink != &ModuleList) {
+            if (ListEntry->Flink != &Context->List) {
                 PMODULE Next;
 
                 Next = CONTAINING_RECORD(ListEntry->Flink, MODULE, ListEntry);
@@ -109,40 +113,43 @@ __ModuleAudit(
 
 static FORCEINLINE VOID
 __ModuleSearchForwards(
-    IN  ULONG_PTR   Address
+    IN  PMODULE_CONTEXT Context,
+    IN  ULONG_PTR       Address
     )
 {
-    while (ModuleCursor != &ModuleList) {
+    while (Context->Cursor != &Context->List) {
         PMODULE Module;
 
-        Module = CONTAINING_RECORD(ModuleCursor, MODULE, ListEntry);
+        Module = CONTAINING_RECORD(Context->Cursor, MODULE, ListEntry);
 
         if (Address <= Module->End)
             break;
 
-        ModuleCursor = ModuleCursor->Flink;
+        Context->Cursor = Context->Cursor->Flink;
     }
 }
 
 static FORCEINLINE VOID
 __ModuleSearchBackwards(
-    IN  ULONG_PTR   Address
+    IN  PMODULE_CONTEXT Context,
+    IN  ULONG_PTR       Address
     )
 {
-    while (ModuleCursor != &ModuleList) {
+    while (Context->Cursor != &Context->List) {
         PMODULE Module;
 
-        Module = CONTAINING_RECORD(ModuleCursor, MODULE, ListEntry);
+        Module = CONTAINING_RECORD(Context->Cursor, MODULE, ListEntry);
 
         if (Address >= Module->Start)
             break;
 
-        ModuleCursor = ModuleCursor->Blink;
+        Context->Cursor = Context->Cursor->Blink;
     }
 }
 
 static FORCEINLINE NTSTATUS
 __ModuleAdd(
+    IN  PMODULE_CONTEXT Context,
     IN  PCHAR           Name,
     IN  ULONG_PTR       Start,
     IN  ULONG_PTR       Size
@@ -197,79 +204,79 @@ __ModuleAdd(
 
     InitializeListHead(&List);
 
-    AcquireHighLock(&ModuleLock, &Irql);
+    AcquireHighLock(&Context->Lock, &Irql);
 
 again:
     After = TRUE;
 
-    if (ModuleCursor == &ModuleList) {
-        ASSERT(IsListEmpty(&ModuleList));
+    if (Context->Cursor == &Context->List) {
+        ASSERT(IsListEmpty(&Context->List));
         goto done;
     }
 
-    Module = CONTAINING_RECORD(ModuleCursor, MODULE, ListEntry);
+    Module = CONTAINING_RECORD(Context->Cursor, MODULE, ListEntry);
 
     if (New->Start > Module->End) {
-        __ModuleSearchForwards(New->Start);
+        __ModuleSearchForwards(Context, New->Start);
 
         After = FALSE;
 
-        if (ModuleCursor == &ModuleList)    // End of list
+        if (Context->Cursor == &Context->List)    // End of list
             goto done;
 
-        Module = CONTAINING_RECORD(ModuleCursor, MODULE, ListEntry);
+        Module = CONTAINING_RECORD(Context->Cursor, MODULE, ListEntry);
 
         if (New->End >= Module->Start) {    // Overlap
-            PLIST_ENTRY Cursor = ModuleCursor->Blink;
+            PLIST_ENTRY Cursor = Context->Cursor->Blink;
 
-            RemoveEntryList(ModuleCursor);
+            RemoveEntryList(Context->Cursor);
             InsertTailList(&List, &Module->ListEntry);
 
-            ModuleCursor = Cursor;
+            Context->Cursor = Cursor;
             goto again;
         }
     } else if (New->End < Module->Start) {
-        __ModuleSearchBackwards(New->End);
+        __ModuleSearchBackwards(Context, New->End);
 
         After = TRUE;
 
-        if (ModuleCursor == &ModuleList)    // Start of list
+        if (Context->Cursor == &Context->List)    // Start of list
             goto done;
 
-        Module = CONTAINING_RECORD(ModuleCursor, MODULE, ListEntry);
+        Module = CONTAINING_RECORD(Context->Cursor, MODULE, ListEntry);
 
         if (New->Start <= Module->End) {    // Overlap
-            PLIST_ENTRY Cursor = ModuleCursor->Flink;
+            PLIST_ENTRY Cursor = Context->Cursor->Flink;
 
-            RemoveEntryList(ModuleCursor);
+            RemoveEntryList(Context->Cursor);
             InsertTailList(&List, &Module->ListEntry);
 
-            ModuleCursor = Cursor;
+            Context->Cursor = Cursor;
             goto again;
         }
     } else {
         PLIST_ENTRY Cursor;
         
-        Cursor = (ModuleCursor->Flink != &ModuleList) ?
-                 ModuleCursor->Flink :
-                 ModuleCursor->Blink;
+        Cursor = (Context->Cursor->Flink != &Context->List) ?
+                 Context->Cursor->Flink :
+                 Context->Cursor->Blink;
 
-        RemoveEntryList(ModuleCursor);
+        RemoveEntryList(Context->Cursor);
         InsertTailList(&List, &Module->ListEntry);
 
-        ModuleCursor = Cursor;
+        Context->Cursor = Cursor;
         goto again;
     }
 
 done:
     if (After)
-        INSERT_AFTER(ModuleCursor, &New->ListEntry);
+        INSERT_AFTER(Context->Cursor, &New->ListEntry);
     else
-        INSERT_BEFORE(ModuleCursor, &New->ListEntry);
+        INSERT_BEFORE(Context->Cursor, &New->ListEntry);
 
-    ModuleCursor = &New->ListEntry;
+    Context->Cursor = &New->ListEntry;
 
-    ReleaseHighLock(&ModuleLock, Irql);
+    ReleaseHighLock(&Context->Lock, Irql);
 
     while (!IsListEmpty(&List)) {
         PLIST_ENTRY     ListEntry;
@@ -287,7 +294,7 @@ done:
         __ModuleFree(Module);
     }
 
-    __ModuleAudit();
+    __ModuleAudit(Context);
 
     return STATUS_SUCCESS;
 
@@ -307,6 +314,7 @@ ModuleLoad(
     IN  PIMAGE_INFO     ImageInfo
     )
 {
+    PMODULE_CONTEXT     Context = &ModuleContext;
     ANSI_STRING         Ansi;
     PCHAR               Buffer;
     PCHAR               Name;
@@ -334,7 +342,8 @@ ModuleLoad(
     Name = strrchr((const CHAR *)Buffer, '\\');
     Name = (Name == NULL) ? Buffer : (Name + 1);
 
-    status = __ModuleAdd(Name,
+    status = __ModuleAdd(Context,
+                         Name,
                          (ULONG_PTR)ImageInfo->ImageBase,
                          (ULONG_PTR)ImageInfo->ImageSize);
     if (!NT_SUCCESS(status))
@@ -368,16 +377,17 @@ ModuleLookup(
     OUT PULONG_PTR  Offset
     )
 {
+    PMODULE_CONTEXT Context = &ModuleContext;
     PLIST_ENTRY     ListEntry;
     KIRQL           Irql;
 
     *Name = NULL;
     *Offset = 0;
 
-    AcquireHighLock(&ModuleLock, &Irql);
+    AcquireHighLock(&Context->Lock, &Irql);
 
-    for (ListEntry = ModuleList.Flink;
-         ListEntry != &ModuleList;
+    for (ListEntry = Context->List.Flink;
+         ListEntry != &Context->List;
          ListEntry = ListEntry->Flink) {
         PMODULE Module;
 
@@ -391,7 +401,7 @@ ModuleLookup(
         }
     }
 
-    ReleaseHighLock(&ModuleLock, Irql);
+    ReleaseHighLock(&Context->Lock, Irql);
 }
 
 VOID
@@ -399,33 +409,51 @@ ModuleTeardown(
     VOID
     )
 {
+    PMODULE_CONTEXT Context = &ModuleContext;
+
     (VOID) PsRemoveLoadImageNotifyRoutine(ModuleLoad);
 
-    while (!IsListEmpty(&ModuleList)) {
+    Context->Cursor = NULL;
+
+    while (!IsListEmpty(&Context->List)) {
         PLIST_ENTRY ListEntry;
         PMODULE     Module;
 
-        ListEntry = RemoveHeadList(&ModuleList);
-        ASSERT(ListEntry != &ModuleList);
+        ListEntry = RemoveHeadList(&Context->List);
+        ASSERT(ListEntry != &Context->List);
 
         Module = CONTAINING_RECORD(ListEntry, MODULE, ListEntry);
         __ModuleFree(Module);
     }
 
-    RtlZeroMemory(&ModuleList, sizeof (LIST_ENTRY));
+    RtlZeroMemory(&Context->List, sizeof (LIST_ENTRY));
+
+    RtlZeroMemory(&Context->Lock, sizeof (HIGH_LOCK));
+
+    (VOID) InterlockedDecrement(&Context->References);
+
+    ASSERT(IsZeroMemory(Context, sizeof (MODULE_CONTEXT)));
 }
 
 NTSTATUS
 ModuleInitialize(
     VOID)
 {
+    PMODULE_CONTEXT             Context = &ModuleContext;
+    ULONG                       References;
     ULONG                       BufferSize;
     ULONG                       Count;
     PAUX_MODULE_EXTENDED_INFO   QueryInfo;
     ULONG                       Index;
     NTSTATUS                    status;
 
-    InitializeHighLock(&ModuleLock);
+    References = InterlockedIncrement(&Context->References);
+
+    status = STATUS_OBJECTID_EXISTS;
+    if (References != 1)
+        goto fail1;
+
+    InitializeHighLock(&Context->Lock);
 
     (VOID) AuxKlibInitialize();
 
@@ -433,26 +461,27 @@ ModuleInitialize(
                                            sizeof (AUX_MODULE_EXTENDED_INFO),
                                            NULL);
     if (!NT_SUCCESS(status))
-        goto fail1;
+        goto fail2;
 
     status = STATUS_UNSUCCESSFUL;
     if (BufferSize == 0)
-        goto fail2;
+        goto fail3;
 
     Count = BufferSize / sizeof (AUX_MODULE_EXTENDED_INFO);
     QueryInfo = __ModuleAllocate(sizeof (AUX_MODULE_EXTENDED_INFO) * Count);
 
     status = STATUS_NO_MEMORY;
     if (QueryInfo == NULL)
-        goto fail3;
+        goto fail4;
 
     status = AuxKlibQueryModuleInformation(&BufferSize,
                                            sizeof (AUX_MODULE_EXTENDED_INFO),
                                            QueryInfo);
     if (!NT_SUCCESS(status))
-        goto fail4;
+        goto fail5;
 
-    InitializeListHead(&ModuleList);
+    InitializeListHead(&Context->List);
+    Context->Cursor = &Context->List;
 
     for (Index = 0; Index < Count; Index++) {
         PCHAR   Name;
@@ -460,47 +489,49 @@ ModuleInitialize(
         Name = strrchr((const CHAR *)QueryInfo[Index].FullPathName, '\\');
         Name = (Name == NULL) ? (PCHAR)QueryInfo[Index].FullPathName : (Name + 1);
 
-        status = __ModuleAdd(Name,
+        status = __ModuleAdd(Context,
+                             Name,
                              (ULONG_PTR)QueryInfo[Index].BasicInfo.ImageBase,
                              (ULONG_PTR)QueryInfo[Index].ImageSize);
         if (!NT_SUCCESS(status))
-            goto fail5;
+            goto fail6;
     }
 
     status = PsSetLoadImageNotifyRoutine(ModuleLoad);
     if (!NT_SUCCESS(status))
-        goto fail6;
+        goto fail7;
 
     __ModuleFree(QueryInfo);
 
-    __ModuleAudit();
-
     return STATUS_SUCCESS;
 
+fail7:
+    Error("fail7\n");
+
 fail6:
     Error("fail6\n");
 
-fail5:
-    Error("fail5\n");
-
-    while (!IsListEmpty(&ModuleList)) {
+    while (!IsListEmpty(&Context->List)) {
         PLIST_ENTRY ListEntry;
         PMODULE     Module;
 
-        ListEntry = RemoveHeadList(&ModuleList);
-        ASSERT(ListEntry != &ModuleList);
+        ListEntry = RemoveHeadList(&Context->List);
+        ASSERT(ListEntry != &Context->List);
 
         Module = CONTAINING_RECORD(ListEntry, MODULE, ListEntry);
         __ModuleFree(Module);
     }
 
-    RtlZeroMemory(&ModuleList, sizeof (LIST_ENTRY));
+    RtlZeroMemory(&Context->List, sizeof (LIST_ENTRY));
 
-fail4:
-    Error("fail4\n");
+fail5:
+    Error("fail5\n");
 
     __ModuleFree(QueryInfo);
 
+fail4:
+    Error("fail4\n");
+
 fail3:
     Error("fail3\n");
 
@@ -510,5 +541,9 @@ fail2:
 fail1:
     Error("fail1 (%08x)\n", status);
 
+    (VOID) InterlockedDecrement(&Context->References);
+
+    ASSERT(IsZeroMemory(Context, sizeof (MODULE_CONTEXT)));    
+
     return status;
 }
index 085c3b5f0641acb5055aa7f593745da91d1d3977..7d6dc74e5aff5f4317b1a85971224598700ea334 100644 (file)
 #include <xen.h>
 
 #include "process.h"
-#include "log.h"
+#include "dbg_print.h"
 #include "assert.h"
 
+typedef struct _PROCESS_CONTEXT {
+    LONG            References;
+} PROCESS_CONTEXT, *PPROCESS_CONTEXT;
+
+static PROCESS_CONTEXT  ProcessContext;
+
 static VOID
 ProcessNotify(
-    IN  HANDLE          ParentId,
-    IN  HANDLE          ProcessId,
-    IN  BOOLEAN         Create
+    IN  HANDLE                      ParentId,
+    IN  HANDLE                      ProcessId,
+    IN  BOOLEAN                     Create
     )
 {
-    static LONG         HAP = -1;
-    KIRQL               Irql;
-    PHYSICAL_ADDRESS    Address;
-    NTSTATUS            status;
+    KIRQL                           Irql;
+    PHYSICAL_ADDRESS                Address;
 
     UNREFERENCED_PARAMETER(ParentId);
     UNREFERENCED_PARAMETER(ProcessId);
@@ -56,25 +60,14 @@ ProcessNotify(
     if (Create)
         return;
 
-    if (HAP > 0)    // Hardware Assisted Paging
-        return;
-
     // Process destruction callbacks occur within the context of the
     // dying process so just read the current CR3 and notify Xen that
     // it's about to cease pointing at a page table hierarchy.
-    // If the hypercall fails with EINVAL the either we're not an HVM
-    // domain, which would be pretty miraculous, or HAP is turned on
-    // in which case we need not tell Xen about CR3 invalidation.
 
     KeRaiseIrql(DISPATCH_LEVEL, &Irql);
 
-    Address.QuadPart = __readcr3();
-    status = HvmPagetableDying(Address);
-    if (!NT_SUCCESS(status) && HAP < 0) {
-        HAP = (status == STATUS_INVALID_PARAMETER) ? 1 : 0;
-
-        Info("PAGING MODE: %s\n", (HAP > 0) ? "HAP" : "Shadow");
-    }
+    Address.QuadPart = __readcr3();   
+    (VOID)HvmPagetableDying(Address);
 
     KeLowerIrql(Irql);
 }
@@ -84,23 +77,45 @@ ProcessTeardown(
     VOID
     )
 {
+    PPROCESS_CONTEXT    Context = &ProcessContext;
+
     (VOID) PsSetCreateProcessNotifyRoutine(ProcessNotify, TRUE);
+
+    (VOID) InterlockedDecrement(&Context->References);
+
+    ASSERT(IsZeroMemory(Context, sizeof (PROCESS_CONTEXT)));
 }
 
 NTSTATUS
 ProcessInitialize(
-    VOID)
+    VOID              
+    )
 {
-    NTSTATUS    status;
+    PPROCESS_CONTEXT    Context = &ProcessContext;
+    ULONG               References;
+    NTSTATUS            status;
+
+    References = InterlockedIncrement(&Context->References);
+
+    status = STATUS_OBJECTID_EXISTS;
+    if (References != 1)
+        goto fail1;
 
     status = PsSetCreateProcessNotifyRoutine(ProcessNotify, FALSE);
     if (!NT_SUCCESS(status))
-        goto fail1;
+        goto fail2;
 
     return STATUS_SUCCESS;
 
+fail2:
+    Error("fail2\n");
+
 fail1:
     Error("fail1 (%08x)\n", status);
 
+    (VOID) InterlockedDecrement(&Context->References);
+
+    ASSERT(IsZeroMemory(Context, sizeof (PROCESS_CONTEXT)));
+
     return status;
 }
index 193dc2aa799375a677dd5f1a4b254344e442f64f..463adb5a2f675ee498c0d662c8692212ec928547 100644 (file)
@@ -35,7 +35,7 @@
 #include <xen.h>
 
 #include "hypercall.h"
-#include "log.h"
+#include "dbg_print.h"
 #include "assert.h"
 
 static FORCEINLINE LONG_PTR
index c1e88fa7c9693740420b2b8d3ac0418f2ae0992e..ed14bed4463a5043b5b0e20b5dd5737f33c9a430 100644 (file)
@@ -37,7 +37,7 @@
 #include <util.h>
 
 #include "system.h"
-#include "log.h"
+#include "dbg_print.h"
 #include "assert.h"
 
 static FORCEINLINE const CHAR *
diff --git a/src/xen/unplug.c b/src/xen/unplug.c
deleted file mode 100644 (file)
index d285e66..0000000
+++ /dev/null
@@ -1,362 +0,0 @@
-/* Copyright (c) Citrix Systems Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, 
- * with or without modification, are permitted provided 
- * that the following conditions are met:
- * 
- * *   Redistributions of source code must retain the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer.
- * *   Redistributions in binary form must reproduce the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer in the documentation and/or other 
- *     materials provided with the distribution.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
- * SUCH DAMAGE.
- */
-
-#define XEN_API __declspec(dllexport)
-
-#include <ntddk.h>
-#include <ntstrsafe.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <xen.h>
-#include <util.h>
-
-#include <binding.h>
-
-#include "unplug.h"
-#include "log.h"
-#include "assert.h"
-
-typedef struct _UNPLUG_CONTEXT {
-    LONG        References;
-    KSPIN_LOCK  Lock;
-} UNPLUG_CONTEXT, *PUNPLUG_CONTEXT;
-
-UNPLUG_CONTEXT  UnplugContext;
-
-static PVOID Port10 = ((PVOID)(ULONG_PTR)0x10);
-static PVOID Port11 = ((PVOID)(ULONG_PTR)0x11);
-static PVOID Port12 = ((PVOID)(ULONG_PTR)0x12);
-static PVOID Port13 = ((PVOID)(ULONG_PTR)0x13);
-
-typedef enum _UNPLUG_TYPE {
-    UNPLUG_TYPE_INVALID = 0,
-    UNPLUG_TYPE_IDE,
-    UNPLUG_TYPE_NIC,
-    UNPLUG_TYPE_COUNT
-} UNPLUG_TYPE, *PUNPLUG_TYPE;
-
-#define MAXIMUM_UNPLUG_INDEX    ((1 << (sizeof (UCHAR) * 8)) - 1)
-
-static FORCEINLINE USHORT
-__UnplugReadMagic(
-    VOID
-    )
-{
-    return READ_PORT_USHORT(Port10);
-}
-
-#define UNPLUG_MAGIC    0x49D2
-
-static FORCEINLINE UCHAR
-__UnplugReadVersion(
-    VOID
-    )
-{
-    return READ_PORT_UCHAR(Port12);
-}
-
-static FORCEINLINE VOID
-__UnplugWriteVersion(
-    IN  UCHAR   Version
-    )
-{
-    // Careful here: we must speculatively set the version 2 unplug type to
-    // an invalid value. This is because, if the unplug protocol is already set
-    // to version 2 then writing the version will actually perform an unplug.
-    // However, if the unplug type is invalid nothing will actually disappear!
-
-    WRITE_PORT_UCHAR(Port11, (UCHAR)UNPLUG_TYPE_INVALID);
-    WRITE_PORT_UCHAR(Port13, Version);
-}
-
-static FORCEINLINE UCHAR
-__UnplugGetVersion(
-    VOID
-    )
-{
-    UCHAR   Version;
-
-    __UnplugWriteVersion(2);
-    Version = __UnplugReadVersion();
-
-    return Version;
-}
-
-#define UNPLUG_PRODUCT_ID 3
-
-static FORCEINLINE VOID
-__UnplugWriteProductId(
-    IN  USHORT  Id
-    )
-{
-    WRITE_PORT_USHORT(Port12, Id);
-}
-
-#define UNPLUG_BUILD_NUMBER ((PCI_DEVICE_ID << 8) | PCI_REVISION)
-
-static FORCEINLINE VOID
-__UnplugWriteBuildNumber(
-    IN  ULONG   BuildNumber
-    )
-{
-    WRITE_PORT_ULONG(Port10, BuildNumber);
-}
-
-static FORCEINLINE VOID
-__UnplugWriteUnplugCommand(
-    IN  UCHAR   Type,
-    IN  UCHAR   Index
-    )
-{
-    WRITE_PORT_UCHAR(Port11, Type);
-    WRITE_PORT_UCHAR(Port13, Index);
-}
-
-static FORCEINLINE NTSTATUS
-__UnplugPrepare(
-    VOID
-    )
-{
-    USHORT      Magic;
-    UCHAR       Version;
-    NTSTATUS    status;
-
-    Magic = __UnplugReadMagic();
-
-    status = STATUS_NO_SUCH_DEVICE;
-    if (Magic != UNPLUG_MAGIC)
-        goto fail1;
-
-    Version = __UnplugGetVersion();
-
-    // We only support version 2 onwards
-
-    status = STATUS_NOT_SUPPORTED;
-    if (Version < 2)
-        goto fail2;
-        
-    // Version 1 of the unplug protocol onwards allows for blacklisting of
-    // drivers. This is done by modifying the returned magic number if the
-    // drivers should not be used.
-
-    __UnplugWriteProductId(UNPLUG_PRODUCT_ID);
-    __UnplugWriteBuildNumber(UNPLUG_BUILD_NUMBER);
-
-    Magic = __UnplugReadMagic();
-
-    status = STATUS_INVALID_PARAMETER;
-    if (Magic != UNPLUG_MAGIC)
-        goto fail3;
-
-    return STATUS_SUCCESS;
-
-fail3:
-    Error("fail3\n");
-
-fail2:
-    Error("fail2\n");
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
-}
-
-XEN_API
-NTSTATUS
-UnplugReference(
-    VOID
-    )
-{
-    ULONG       References;
-    KIRQL       Irql;
-    NTSTATUS    status;
-
-    Trace("====>\n");
-
-    KeAcquireSpinLock(&UnplugContext.Lock, &Irql);
-
-    References = UnplugContext.References++;
-
-    if (References == 0) {
-        status = __UnplugPrepare();
-        if (!NT_SUCCESS(status))
-            goto fail1;
-    }
-
-    KeReleaseSpinLock(&UnplugContext.Lock, Irql);
-
-    Trace("<==== (%u)\n", References);
-
-    return STATUS_SUCCESS;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    ASSERT(UnplugContext.References != 0);
-    --UnplugContext.References;
-
-    KeReleaseSpinLock(&UnplugContext.Lock, Irql);
-
-    return status;
-}
-
-static BOOLEAN  UnplugEntry[UNPLUG_TYPE_COUNT][MAXIMUM_UNPLUG_INDEX + 1];
-
-XEN_API
-VOID
-UnplugDereference(
-    VOID
-    )
-{
-    ULONG   References;
-    KIRQL   Irql;
-
-    Trace("====>\n");
-
-    KeAcquireSpinLock(&UnplugContext.Lock, &Irql);
-
-    References = UnplugContext.References;
-
-    if (References == 0)
-        goto done;
-
-    --UnplugContext.References;
-
-    if (References == 0)
-        RtlZeroMemory(UnplugEntry, sizeof (BOOLEAN) * UNPLUG_TYPE_COUNT * (MAXIMUM_UNPLUG_INDEX + 1));
-
-done:
-    KeReleaseSpinLock(&UnplugContext.Lock, Irql);
-
-    Trace("<==== (%u)\n", References);
-}
-
-XEN_API
-NTSTATUS
-UnplugDevice(
-    PCHAR       Class,
-    PCHAR       Device
-    )
-{
-    KIRQL       Irql;
-    UNPLUG_TYPE Type;
-    UCHAR       Index;
-    NTSTATUS    status;
-
-    KeAcquireSpinLock(&UnplugContext.Lock, &Irql);
-
-    ASSERT(UnplugContext.References != 0);
-
-    Info("%s %s\n", Class, Device);
-
-    status = STATUS_INVALID_PARAMETER;
-    if (strcmp(Class, "VIF") == 0)
-        Type = UNPLUG_TYPE_NIC;
-    else if (strcmp(Class, "VBD") == 0)
-        Type = UNPLUG_TYPE_IDE;
-    else
-        goto fail1;
-
-    ASSERT3U(Type, <, UNPLUG_TYPE_COUNT);
-
-    Index = (UCHAR)strtol(Device, NULL, 0);
-    ASSERT3U(Index, <=, MAXIMUM_UNPLUG_INDEX);
-
-    if (!UnplugEntry[Type][Index]) {
-        UnplugEntry[Type][Index] = TRUE;
-        __UnplugWriteUnplugCommand(Type, Index);
-    }
-
-    KeReleaseSpinLock(&UnplugContext.Lock, Irql);
-
-    return STATUS_SUCCESS;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    KeReleaseSpinLock(&UnplugContext.Lock, Irql);
-
-    return status;
-}
-
-XEN_API
-VOID
-UnplugReplay(
-    VOID
-    )
-{
-    KIRQL       Irql;
-    UNPLUG_TYPE Type;
-    ULONG       Index;
-    NTSTATUS    status;
-
-    KeAcquireSpinLock(&UnplugContext.Lock, &Irql);
-
-    if (UnplugContext.References == 0)
-        goto done;
-
-    status = __UnplugPrepare();
-    ASSERT(NT_SUCCESS(status));
-
-    for (Type = 0; Type < UNPLUG_TYPE_COUNT; Type++) {
-        if (Type == UNPLUG_TYPE_INVALID)
-            continue;
-
-        for (Index = 0; Index <= MAXIMUM_UNPLUG_INDEX; Index++) {
-            if (UnplugEntry[Type][Index])
-                __UnplugWriteUnplugCommand(Type, (UCHAR)Index);
-        }
-    }
-
-done:
-    KeReleaseSpinLock(&UnplugContext.Lock, Irql);
-}
-
-VOID
-UnplugInitialize(
-    VOID
-    )
-{
-    ASSERT(IsZeroMemory(&UnplugContext, sizeof (UNPLUG_CONTEXT)));
-
-    KeInitializeSpinLock(&UnplugContext.Lock);
-}
-
-VOID
-UnplugTeardown(
-    VOID
-    )
-{
-    RtlZeroMemory(&UnplugContext.Lock, sizeof (KSPIN_LOCK));
-
-    ASSERT(IsZeroMemory(&UnplugContext, sizeof (UNPLUG_CONTEXT)));
-}
diff --git a/src/xen/unplug.h b/src/xen/unplug.h
deleted file mode 100644 (file)
index b7638f2..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* 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 _XEN_UNPLUG_H
-#define _XEN_UNPLUG_H
-
-#include <ntddk.h>
-#include <xen.h>
-
-extern VOID
-UnplugInitialize(
-    VOID
-    );
-
-extern VOID
-UnplugTeardown(
-    VOID
-    );
-
-#endif  // _XEN_UNPLUG_H
index 107f22fd8e6a06cb82e471b19d562c770678ceda..aa6b28b47383efefe13971d2a690526e3e319e24 100644 (file)
@@ -61,7 +61,12 @@ xenbus_coinst_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.dll
 %Citrix%=Citrix,NT$ARCH$
 
 [Citrix.NT$ARCH$]
-%XenBusDesc%=XenBus_Inst,PCI\VEN_@PCI_VENDOR_ID@&DEV_@PCI_DEVICE_ID@&SUBSYS_@PCI_DEVICE_ID@@PCI_VENDOR_ID@&REV_@PCI_REVISION@
+; DisplayName          Section         DeviceID
+; -----------          -------         --------
+
+%XenBusDesc%           =XenBus_Inst,   PCI\VEN_5853&DEV_C000&SUBSYS_C0005853&REV_01
+%XenBusDesc%           =XenBus_Inst,   PCI\VEN_5853&DEV_0002
+%XenBusDesc%           =XenBus_Inst,   PCI\VEN_5853&DEV_0001
 
 [XenBus_Inst] 
 CopyFiles=XenBus_Copyfiles
@@ -94,29 +99,7 @@ AddReg = XenFilt_Parameters
 
 [XenFilt_Parameters]
 HKR,"Parameters",,0x00000010
-
 HKR,"Parameters","FilterDevices",0x00010000,"ACPI\PNP0A03","PCIIDE\IDEChannel"
-HKR,"Parameters","ACPI\PNP0A03",0x00010000,"VIF","VBD"
-
-HKR,"Aliases",,0x00000010
-
-HKR,"Aliases\VIF",,0x00000010
-
-HKR,"Aliases\VIF","0",0x00000000,"PCI\VEN_10EC&DEV_8139&SUBSYS_00015853&REV_20#20"
-HKR,"Aliases\VIF","1",0x00000000,"PCI\VEN_10EC&DEV_8139&SUBSYS_00015853&REV_20#28"
-HKR,"Aliases\VIF","2",0x00000000,"PCI\VEN_10EC&DEV_8139&SUBSYS_00015853&REV_20#30"
-HKR,"Aliases\VIF","3",0x00000000,"PCI\VEN_10EC&DEV_8139&SUBSYS_00015853&REV_20#38"
-HKR,"Aliases\VIF","4",0x00000000,"PCI\VEN_10EC&DEV_8139&SUBSYS_00015853&REV_20#40"
-HKR,"Aliases\VIF","5",0x00000000,"PCI\VEN_10EC&DEV_8139&SUBSYS_00015853&REV_20#48"
-HKR,"Aliases\VIF","6",0x00000000,"PCI\VEN_10EC&DEV_8139&SUBSYS_00015853&REV_20#50"
-HKR,"Aliases\VIF","7",0x00000000,"PCI\VEN_10EC&DEV_8139&SUBSYS_00015853&REV_20#58"
-
-HKR,"Aliases\VBD",,0x00000010
-
-HKR,"Aliases\VBD","0",0x00000000,"IDE\DiskQEMU_HARDDISK___________________________0.10.2__#0.0.0"
-HKR,"Aliases\VBD","1",0x00000000,"IDE\DiskQEMU_HARDDISK___________________________0.10.2__#0.1.0"
-HKR,"Aliases\VBD","2",0x00000000,"IDE\DiskQEMU_HARDDISK___________________________0.10.2__#1.0.0"
-HKR,"Aliases\VBD","3",0x00000000,"IDE\DiskQEMU_HARDDISK___________________________0.10.2__#1.1.0"
 
 [XenBus_Inst.CoInstallers]
 CopyFiles=CoInst_CopyFiles
@@ -128,9 +111,9 @@ HKR,,CoInstallers32,0x00010000,"xenbus_coinst_@MAJOR_VERSION@_@MINOR_VERSION@_@M
 [Strings] 
 
 Citrix="Citrix Systems Inc." 
-DiskDesc="Citrix Tools for Virtual Machines" 
-XenBusDesc="Citrix PV Bus"
-XenFiltDesc="Citrix Bus Filter"
+DiskDesc="XenServer Tools for Virtual Machines" 
+XenBusDesc="XenServer PV Bus"
+XenFiltDesc="XenServer Bus Filter"
 
 SERVICE_BOOT_START=0x0 
 SERVICE_SYSTEM_START=0x1 
diff --git a/src/xenbus/assert.h b/src/xenbus/assert.h
deleted file mode 100644 (file)
index abb9e72..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/* 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 _XENBUS_ASSERT_H
-#define _XENBUS_ASSERT_H
-
-#include <ntddk.h>
-
-#include "log.h"
-
-static FORCEINLINE VOID
-__BugCheck(
-    IN  ULONG       Code,
-    IN  ULONG_PTR   Parameter1,
-    IN  ULONG_PTR   Parameter2,
-    IN  ULONG_PTR   Parameter3,
-    IN  ULONG_PTR   Parameter4
-    )
-{
-#pragma prefast(suppress:28159)
-    KeBugCheckEx(Code,
-                 Parameter1,
-                 Parameter2,
-                 Parameter3,
-                 Parameter4);
-}
-
-#define ASSERTION_FAILURE   0x0000DEAD
-
-#define BUG(_TEXT)                                              \
-        do {                                                    \
-            const CHAR  *_Text = (_TEXT);                       \
-            const CHAR  *_File = __FILE__;                      \
-            ULONG       _Line = __LINE__;                       \
-                                                                \
-            Error("BUG: " _TEXT "\n");                          \
-            __BugCheck(ASSERTION_FAILURE,                       \
-                       (ULONG_PTR)_Text,                        \
-                       (ULONG_PTR)_File,                        \
-                       (ULONG_PTR)_Line,                        \
-                       0);                                      \
-        } while (FALSE)
-
-#define BUG_ON(_EXP)                \
-        if (_EXP) BUG(#_EXP)
-
-#if DBG
-
-#define __NT_ASSERT(_EXP)                                       \
-        ((!(_EXP)) ?                                            \
-        (Error("ASSERTION FAILED: " #_EXP "\n"),                \
-         __annotation(L"Debug", L"AssertFail", L#_EXP),         \
-         DbgRaiseAssertionFailure(), FALSE) :                   \
-        TRUE)
-
-#define __ASSERT(_EXP)  __NT_ASSERT(_EXP)
-
-#else   // DBG
-
-#define __ASSERT(_EXP)  BUG_ON(!(_EXP))
-
-#endif  // DBG
-
-#undef  ASSERT
-
-#define ASSERT(_EXP)                    \
-        do {                            \
-            __ASSERT(_EXP);             \
-            __analysis_assume(_EXP);    \
-        } while (FALSE)
-
-#define ASSERT3U(_X, _OP, _Y)                       \
-        do {                                        \
-            ULONGLONG   _Lval = (ULONGLONG)(_X);    \
-            ULONGLONG   _Rval = (ULONGLONG)(_Y);    \
-            if (!(_Lval _OP _Rval)) {               \
-                Error("%s = %llu\n", #_X, _Lval);   \
-                Error("%s = %llu\n", #_Y, _Rval);   \
-                ASSERT(_X _OP _Y);                  \
-            }                                       \
-        } while (FALSE)
-
-#define ASSERT3S(_X, _OP, _Y)                       \
-        do {                                        \
-            LONGLONG    _Lval = (LONGLONG)(_X);     \
-            LONGLONG    _Rval = (LONGLONG)(_Y);     \
-            if (!(_Lval _OP _Rval)) {               \
-                Error("%s = %lld\n", #_X, _Lval);   \
-                Error("%s = %lld\n", #_Y, _Rval);   \
-                ASSERT(_X _OP _Y);                  \
-            }                                       \
-        } while (FALSE)
-
-#define ASSERT3P(_X, _OP, _Y)                       \
-        do {                                        \
-            PVOID   _Lval = (PVOID)(_X);            \
-            PVOID   _Rval = (PVOID)(_Y);            \
-            if (!(_Lval _OP _Rval)) {               \
-                Error("%s = %p\n", #_X, _Lval);     \
-                Error("%s = %p\n", #_Y, _Rval);     \
-                ASSERT(_X _OP _Y);                  \
-            }                                       \
-        } while (FALSE)
-
-#ifndef TEST_MEMORY
-#define TEST_MEMORY DBG
-#endif
-
-#if TEST_MEMORY
-
-static __inline BOOLEAN
-_IsZeroMemory(
-    IN  const PCHAR Caller,
-    IN  const PCHAR Name,
-    IN  PVOID       Buffer,
-    IN  ULONG       Length
-    )
-{
-    ULONG           Offset;
-
-    Offset = 0;
-    while (Offset < Length) {
-        if (*((PUCHAR)Buffer + Offset) != 0) {
-            Error("%s: non-zero byte in %s (0x%p+0x%x)\n", Caller, Name, Buffer, Offset);
-            return FALSE;
-        }
-        Offset++;
-    }
-
-    return TRUE;
-}
-
-#define IsZeroMemory(_Buffer, _Length) \
-        _IsZeroMemory(__FUNCTION__, #_Buffer, (_Buffer), (_Length))
-
-#else   // TEST_MEMORY
-
-#define IsZeroMemory(_Buffer, _Length)  TRUE
-
-#endif  // TEST_MEMORY
-
-#define IMPLY(_X, _Y)   (!(_X) || (_Y))
-#define EQUIV(_X, _Y)   (IMPLY((_X), (_Y)) && IMPLY((_Y), (_X)))
-
-#endif  // _XENBUS_ASSERT_H
-
index 3b2d817840d2ee0b277a573337623282389dfeaf..b3317ff42b8df6d60cc1fa0b94f5d7950a3c9a0b 100644 (file)
@@ -37,8 +37,8 @@
 #include "mutex.h"
 #include "balloon.h"
 #include "range_set.h"
+#include "dbg_print.h"
 #include "assert.h"
-#include "log.h"
 
 #define BALLOON_AUDIT   DBG
 
@@ -53,7 +53,7 @@ struct _XENBUS_BALLOON
 {
     PKEVENT             LowMemoryEvent;
     HANDLE              LowMemoryHandle;
-    XENBUS_MUTEX        Mutex;
+    MUTEX               Mutex;
     ULONGLONG           Size;
     PXENBUS_RANGE_SET   RangeSet;
     MDL                 Mdl;
@@ -814,7 +814,7 @@ BalloonInitialize(
 fail3:
     Error("fail3\n");
 
-    RtlZeroMemory(&(*Balloon)->Mutex, sizeof (XENBUS_MUTEX));
+    RtlZeroMemory(&(*Balloon)->Mutex, sizeof (MUTEX));
 
 fail2:
     Error("fail2\n");
@@ -837,7 +837,7 @@ BalloonTeardown(
     Balloon->LowMemoryHandle = NULL;
     Balloon->LowMemoryEvent = NULL;
 
-    RtlZeroMemory(&Balloon->Mutex, sizeof (XENBUS_MUTEX));
+    RtlZeroMemory(&Balloon->Mutex, sizeof (MUTEX));
 
     RangeSetTeardown(Balloon->RangeSet);
     Balloon->RangeSet = NULL;
index 483b33263c33fdb30d0d707100cf542e9c342053..376564cc0d0c3dd1d534c61b2862d73e358f5239 100644 (file)
 #include "dma.h"
 #include "fdo.h"
 #include "pdo.h"
-#include "log.h"
+#include "registry.h"
 #include "sync.h"
+#include "dbg_print.h"
 #include "assert.h"
 
 typedef struct _XENBUS_BUS_CONTEXT {
     LONG                    References;
     PXENBUS_PDO             Pdo;
+    ULONG                   InterceptDmaAdapter;
 } XENBUS_BUS_CONTEXT, *PXENBUS_BUS_CONTEXT;
 
 #define BUS_TAG 'SUB'
@@ -118,7 +120,7 @@ BusGetDmaAdapter(
     PXENBUS_BUS_CONTEXT     Context = _Context;
     XENBUS_DMA_ADAPTER_TYPE Type;
 
-    if (DriverParameters.InterceptDmaAdapter != 0) {
+    if (Context->InterceptDmaAdapter != 0) {
         RTL_OSVERSIONINFOEXW    VersionInformation;
 
         RtlGetVersion((PRTL_OSVERSIONINFOW)&VersionInformation);
@@ -187,6 +189,7 @@ BusInitialize(
     )
 {
     PXENBUS_BUS_CONTEXT         Context;
+    HANDLE                      ParametersKey;
     NTSTATUS                    status;
 
     Trace("====>\n");
@@ -199,6 +202,20 @@ BusInitialize(
 
     Context->Pdo = Pdo;
 
+    ParametersKey = DriverGetParametersKey();
+
+    Context->InterceptDmaAdapter = 0;
+
+    if (ParametersKey != NULL) {
+        ULONG   InterceptDmaAdapter;
+
+        status = RegistryQueryDwordValue(ParametersKey,
+                                         "InterceptDmaAdapter",
+                                         &InterceptDmaAdapter);
+        if (NT_SUCCESS(status))
+            Context->InterceptDmaAdapter = InterceptDmaAdapter;
+    }
+
     Interface->Size = sizeof (BUS_INTERFACE_STANDARD);
     Interface->Version = 1;
     Interface->Context = Context;
index 7bc923e1ca843f7f1885be999c86e2f03f9b170b..025205d7d9ded747545c5a1af68e5f4143b11107 100644 (file)
@@ -39,7 +39,7 @@
 #include "high.h"
 #include "debug.h"
 #include "fdo.h"
-#include "log.h"
+#include "dbg_print.h"
 #include "assert.h"
 
 #define MAXIMUM_PREFIX_LENGTH   32
@@ -136,10 +136,14 @@ DebugPrintf(
 
     UNREFERENCED_PARAMETER(Context);
 
-    LogQemuPrintf("%s: ", Callback->Prefix);
+    LogPrintf(LOG_LEVEL_INFO,
+              "%s: ",
+              Callback->Prefix);
 
     va_start(Arguments, Format);
-    LogQemuVPrintf(Format, Arguments);
+    LogVPrintf(LOG_LEVEL_INFO,
+               Format,
+               Arguments);
     va_end(Arguments);
 }
 
@@ -207,21 +211,29 @@ __DebugTrigger(
             ModuleLookup((ULONG_PTR)Callback->Caller, &Name, &Offset);
 
             if (Name != NULL) {
-                LogQemuPrintf("XEN|DEBUG: SKIPPING %p PREFIX '%s' REGISTERED BY %s + %p\n",
-                            Callback->Function,
-                            Callback->Prefix,
-                            Name,
-                            Offset);
+                LogPrintf(LOG_LEVEL_INFO,
+                          "XEN|DEBUG: SKIPPING %p PREFIX '%s' REGISTERED BY %s + %p\n",
+                          Callback->Function,
+                          Callback->Prefix,
+                          Name,
+                          Offset);
             } else {
-                LogQemuPrintf("XEN|DEBUG: SKIPPING %p PREFIX '%s' REGISTERED BY %p\n",
-                            Callback->Function,
-                            Callback->Prefix,
-                            Callback->Caller);
+                LogPrintf(LOG_LEVEL_INFO,
+                          "XEN|DEBUG: SKIPPING %p PREFIX '%s' REGISTERED BY %p\n",
+                          Callback->Function,
+                          Callback->Prefix,
+                          Callback->Caller);
             }
         } else {
-            LogQemuPrintf("XEN|DEBUG: ====> (%s + %p)\n", Name, Offset);
+            LogPrintf(LOG_LEVEL_INFO,
+                      "XEN|DEBUG: ====> (%s + %p)\n",
+                      Name,
+                      Offset);
             Callback->Function(Callback->Argument, Crashing);
-            LogQemuPrintf("XEN|DEBUG: <==== (%s + %p)\n", Name, Offset);
+            LogPrintf(LOG_LEVEL_INFO,
+                      "XEN|DEBUG: <==== (%s + %p)\n",
+                      Name,
+                      Offset);
         }
     }
 }
index ffbc801879ff299dbb867123885f1071257ccde1..defdfbee8194a0aa965925df5222f9963a90cbfc 100644 (file)
@@ -38,8 +38,7 @@
 #include "dma.h"
 #include "fdo.h"
 #include "pdo.h"
-#include "log.h"
-#include "sync.h"
+#include "dbg_print.h"
 #include "assert.h"
 
 #pragma warning(push)
index 1641d902e1aa4cafd8228e067767e353aaad2825..949f97a810834d0a7c85b198e2db14f06e7cadc6 100644 (file)
  * SUCH DAMAGE.
  */
 
-//
-// This driver responds to the following system start options:
-// (These can be set by bcdedit /set loadoptions <string>).
-//
-// /XEN:BALLOON=OFF
-//
-// The system balloon defaults to ON and is adjusted via the
-// xenstore 'memory/static-max' and 'memory/target' values. If
-// this option is present those values are ignored and the
-// balloon remains inactive.
-//
-
 #include <ntddk.h>
 #include <util.h>
 
 #include "fdo.h"
 #include "pdo.h"
 #include "driver.h"
-#include "log.h"
+#include "dbg_print.h"
 #include "assert.h"
 #include "version.h"
 
-extern const CHAR   *XenVersion;
-extern const CHAR   *XenPciVersion;
-
 extern PULONG       InitSafeBootMode;
 
-PDRIVER_OBJECT      DriverObject;
+typedef struct _XENBUS_DRIVER {
+    PDRIVER_OBJECT      DriverObject;
+    HANDLE              ParametersKey;
+} XENBUS_DRIVER, *PXENBUS_DRIVER;
+
+static XENBUS_DRIVER    Driver;
+
+static FORCEINLINE VOID
+__DriverSetDriverObject(
+    IN  PDRIVER_OBJECT  DriverObject
+    )
+{
+    Driver.DriverObject = DriverObject;
+}
 
-HANDLE              DriverServiceKey;
+static FORCEINLINE PDRIVER_OBJECT
+__DriverGetDriverObject(
+    VOID
+    )
+{
+    return Driver.DriverObject;
+}
 
-XENBUS_PARAMETERS   DriverParameters;
+PDRIVER_OBJECT
+DriverGetDriverObject(
+    VOID
+    )
+{
+    return __DriverGetDriverObject();
+}
+
+static FORCEINLINE VOID
+__DriverSetParametersKey(
+    IN  HANDLE  Key
+    )
+{
+    Driver.ParametersKey = Key;
+}
+
+static FORCEINLINE HANDLE
+__DriverGetParametersKey(
+    VOID
+    )
+{
+    return Driver.ParametersKey;
+}
+
+HANDLE
+DriverGetParametersKey(
+    VOID
+    )
+{
+    return __DriverGetParametersKey();
+}
 
 DRIVER_UNLOAD       DriverUnload;
 
 VOID
 DriverUnload(
-    IN  PDRIVER_OBJECT  _DriverObject
+    IN  PDRIVER_OBJECT  DriverObject
     )
 {
-    ASSERT3P(_DriverObject, ==, DriverObject);
+    HANDLE              ParametersKey;
 
-    Trace("====>\n");
+    ASSERT3P(DriverObject, ==, __DriverGetDriverObject());
 
-    Info("%s (%s)\n",
-         MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR,
-         DAY_STR "/" MONTH_STR "/" YEAR_STR);
+    Trace("====>\n");
 
     if (*InitSafeBootMode > 0)
         goto done;
 
-    RegistryFreeSzValue(DriverParameters.SyntheticClasses);
-    RegistryFreeSzValue(DriverParameters.SupportedClasses);
-
-    RegistryCloseKey(DriverServiceKey);
+    ParametersKey = __DriverGetParametersKey();
+    if (ParametersKey != NULL) {
+        RegistryCloseKey(ParametersKey);
+        __DriverSetParametersKey(NULL);
+    }
 
     RegistryTeardown();
 
 done:
-    DriverObject = NULL;
+    __DriverSetDriverObject(NULL);
+
+    ASSERT(IsZeroMemory(&Driver, sizeof (XENBUS_DRIVER)));
 
     Trace("<====\n");
 }
 
+__drv_functionClass(IO_COMPLE7TION_ROUTINE)
+__drv_sameIRQL
+static NTSTATUS
+DriverQueryIdCompletion(
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  PIRP            Irp,
+    IN  PVOID           Context
+    )
+{
+    PKEVENT             Event = Context;
+
+    UNREFERENCED_PARAMETER(DeviceObject);
+    UNREFERENCED_PARAMETER(Irp);
+
+    KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
+
+    return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+static FORCEINLINE NTSTATUS
+__DriverQueryId(
+    IN  PDEVICE_OBJECT      PhysicalDeviceObject,
+    IN  BUS_QUERY_ID_TYPE   IdType,
+    OUT PVOID               *Information
+    )
+{
+    PDEVICE_OBJECT          DeviceObject;
+    PIRP                    Irp;
+    KEVENT                  Event;
+    PIO_STACK_LOCATION      StackLocation;
+    NTSTATUS                status;
+
+    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+    DeviceObject = IoGetAttachedDeviceReference(PhysicalDeviceObject);
+
+    Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
+
+    status = STATUS_INSUFFICIENT_RESOURCES;
+    if (Irp == NULL)
+        goto fail1;
+
+    StackLocation = IoGetNextIrpStackLocation(Irp);
+
+    StackLocation->MajorFunction = IRP_MJ_PNP;
+    StackLocation->MinorFunction = IRP_MN_QUERY_ID;
+    StackLocation->Flags = 0;
+    StackLocation->Parameters.QueryId.IdType = IdType;
+    StackLocation->DeviceObject = DeviceObject;
+    StackLocation->FileObject = NULL;
+
+    KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+    IoSetCompletionRoutine(Irp,
+                           DriverQueryIdCompletion,
+                           &Event,
+                           TRUE,
+                           TRUE,
+                           TRUE);
+
+    // Default completion status
+    Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+
+    status = IoCallDriver(DeviceObject, Irp);
+    if (status == STATUS_PENDING) {
+        (VOID) KeWaitForSingleObject(&Event,
+                                     Executive,
+                                     KernelMode,
+                                     FALSE,
+                                     NULL);
+        status = Irp->IoStatus.Status;
+    } else {
+        ASSERT3U(status, ==, Irp->IoStatus.Status);
+    }
+
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    *Information = (PVOID)Irp->IoStatus.Information;
+
+    IoFreeIrp(Irp);
+    ObDereferenceObject(DeviceObject);
+
+    return STATUS_SUCCESS;
+
+fail2:
+    Error("fail2\n");
+
+    IoFreeIrp(Irp);
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    ObDereferenceObject(DeviceObject);
+
+    return status;
+}
+
 DRIVER_ADD_DEVICE   AddDevice;
 
 NTSTATUS
 #pragma prefast(suppress:28152) // Does not clear DO_DEVICE_INITIALIZING
 AddDevice(
-    IN  PDRIVER_OBJECT  _DriverObject,
+    IN  PDRIVER_OBJECT  DriverObject,
     IN  PDEVICE_OBJECT  DeviceObject
     )
 {
+    HANDLE              ParametersKey;
+    PANSI_STRING        ActiveDeviceInstance;
+    BOOLEAN             Active;
+    PWCHAR              DeviceID;
+    PWCHAR              InstanceID;
+    UNICODE_STRING      Unicode;
+    ULONG               Length;
     NTSTATUS            status;
 
-    ASSERT3P(_DriverObject, ==, DriverObject);
+    ASSERT3P(DriverObject, ==, __DriverGetDriverObject());
 
-    status = FdoCreate(DeviceObject);
+    ParametersKey = __DriverGetParametersKey();
+
+    ActiveDeviceInstance = NULL;
+    if (ParametersKey != NULL) {
+        status = RegistryQuerySzValue(ParametersKey,
+                                      "ActiveDeviceInstance",
+                                      &ActiveDeviceInstance);
+        ASSERT(IMPLY(!NT_SUCCESS(status), ActiveDeviceInstance == NULL));
+    } else {
+        ActiveDeviceInstance = NULL;
+    }
+
+    Active = FALSE;
+
+    DeviceID = NULL;
+    InstanceID = NULL;
+
+    RtlZeroMemory(&Unicode, sizeof (UNICODE_STRING));
+
+    if (ActiveDeviceInstance == NULL)
+        goto done;
+
+    status = __DriverQueryId(DeviceObject, BusQueryDeviceID, &DeviceID);
     if (!NT_SUCCESS(status))
         goto fail1;
 
+    status = __DriverQueryId(DeviceObject, BusQueryInstanceID, &InstanceID);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    status = RtlAnsiStringToUnicodeString(&Unicode, ActiveDeviceInstance, TRUE);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    Length = (ULONG)wcslen(DeviceID);
+    if (_wcsnicmp(Unicode.Buffer,
+                  DeviceID,
+                  Length) != 0)
+        goto done;
+
+    Length = (ULONG)wcslen(InstanceID);
+    if (_wcsnicmp(Unicode.Buffer + (Unicode.Length / sizeof (WCHAR)) - Length,
+                  InstanceID,
+                  Length) != 0)
+        goto done;
+
+    Active = TRUE;
+
+    RegistryFreeSzValue(ActiveDeviceInstance);
+
+done:
+    if (Unicode.Buffer != NULL)
+        RtlFreeUnicodeString(&Unicode);
+
+    if (InstanceID != NULL)
+        ExFreePool(InstanceID);
+
+    if (DeviceID != NULL)
+        ExFreePool(DeviceID);
+
+    status = FdoCreate(DeviceObject, Active);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
     return STATUS_SUCCESS;
 
+fail3:
+    Error("fail3\n");
+
+    if (InstanceID != NULL)
+        ExFreePool(InstanceID);
+
+fail2:
+    Error("fail2\n");
+
+    if (DeviceID != NULL)
+        ExFreePool(DeviceID);
+
 fail1:
+    RegistryFreeSzValue(ActiveDeviceInstance);
+
     Error("fail1 (%08x)\n", status);
 
     return status;
@@ -168,97 +382,53 @@ DRIVER_INITIALIZE   DriverEntry;
 
 NTSTATUS
 DriverEntry(
-    IN  PDRIVER_OBJECT  _DriverObject,
+    IN  PDRIVER_OBJECT  DriverObject,
     IN  PUNICODE_STRING RegistryPath
     )
 {
+    HANDLE              ServiceKey;
     HANDLE              ParametersKey;
-    PANSI_STRING        Options;
     ULONG               Index;
     NTSTATUS            status;
 
-    ASSERT3P(DriverObject, ==, NULL);
+    ASSERT3P(__DriverGetDriverObject(), ==, NULL);
 
     ExInitializeDriverRuntime(DrvRtPoolNxOptIn);
 
-    Trace("====>\n");
+    __DbgPrintEnable();
 
-    Info("%s (%s)\n",
-         MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR,
-         DAY_STR "/" MONTH_STR "/" YEAR_STR);
+    Trace("====>\n");
 
-    DriverObject = _DriverObject;
-    DriverObject->DriverUnload = DriverUnload;
+    __DriverSetDriverObject(DriverObject);
 
     if (*InitSafeBootMode > 0)
         goto done;
 
+    Driver.DriverObject->DriverUnload = DriverUnload;
+
+    LogPrintf(LOG_LEVEL_INFO,
+              "XENBUS %d.%d.%d (%d) (%02d.%02d.%04d)\n",
+              MAJOR_VERSION,
+              MINOR_VERSION,
+              MICRO_VERSION,
+              BUILD_NUMBER,
+              DAY,
+              MONTH,
+              YEAR);
+
     status = RegistryInitialize(RegistryPath);
     if (!NT_SUCCESS(status))
         goto fail1;
 
-    status = RegistryOpenServiceKey(KEY_READ, &DriverServiceKey);
+    status = RegistryOpenServiceKey(KEY_READ, &ServiceKey);
     if (!NT_SUCCESS(status))
         goto fail2;
 
-    DriverParameters.SupportedClasses = NULL;
-    DriverParameters.SyntheticClasses = NULL;
-    DriverParameters.CreatePDOs = 1;
-    DriverParameters.InterceptDmaAdapter = 0;
-
-    status = RegistryOpenSubKey(DriverServiceKey, "Parameters", KEY_READ, &ParametersKey);
-    if (NT_SUCCESS(status)) {
-        PANSI_STRING    SupportedClasses;
-        PANSI_STRING    SyntheticClasses;
-        ULONG           CreatePDOs;
-        ULONG           InterceptDmaAdapter;
+    status = RegistryOpenSubKey(ServiceKey, "Parameters", KEY_READ, &ParametersKey);
+    if (NT_SUCCESS(status))
+        __DriverSetParametersKey(ParametersKey);
 
-        status = RegistryQuerySzValue(ParametersKey,
-                                      "SupportedClasses",
-                                      &SupportedClasses);
-        if (NT_SUCCESS(status))
-            DriverParameters.SupportedClasses = SupportedClasses;
-
-        status = RegistryQuerySzValue(ParametersKey,
-                                      "SyntheticClasses",
-                                      &SyntheticClasses);
-        if (NT_SUCCESS(status))
-            DriverParameters.SyntheticClasses = SyntheticClasses;
-
-        status = RegistryQueryDwordValue(ParametersKey,
-                                         "CreatePDOs",
-                                         &CreatePDOs);
-        if (NT_SUCCESS(status))
-            DriverParameters.CreatePDOs = CreatePDOs;
-
-        status = RegistryQueryDwordValue(ParametersKey,
-                                         "InterceptDmaAdapter",
-                                         &InterceptDmaAdapter);
-        if (NT_SUCCESS(status))
-            DriverParameters.InterceptDmaAdapter = InterceptDmaAdapter;
-
-        RegistryCloseKey(ParametersKey);
-    }
-
-    DriverParameters.Balloon = 1;
-
-    status = RegistryQuerySystemStartOptions(&Options);
-    if (NT_SUCCESS(status)) {
-        const CHAR  Key[] = " XEN:BALLOON=";
-        PCHAR       Value;
-
-        Trace("Options = '%Z'\n", Options);
-
-        Value = strstr(Options->Buffer, Key);
-        if (Value != NULL) {
-            Value += sizeof (Key) - 1;
-
-            if (strcmp(Value, "OFF") == 0)
-                DriverParameters.Balloon = 0;
-        }
-
-        RegistryFreeSzValue(Options);
-    }
+    RegistryCloseKey(ServiceKey);
 
     DriverObject->DriverExtension->AddDevice = AddDevice;
 
@@ -281,5 +451,9 @@ fail2:
 fail1:
     Error("fail1 (%08x)\n", status);
 
+    __DriverSetDriverObject(NULL);
+
+    ASSERT(IsZeroMemory(&Driver, sizeof (XENBUS_DRIVER)));
+
     return status;
 }
index 251deb76000ee4fa9dffe79fc97b20c8b58dc0fe..45cbe82ad3c43782674ea8cb7bcc54adbcf77381 100644 (file)
 #ifndef _XENBUS_DRIVER_H
 #define _XENBUS_DRIVER_H
 
+extern PDRIVER_OBJECT
+DriverGetDriverObject(
+    VOID
+    );
+
+extern HANDLE
+DriverGetParametersKey(
+    VOID
+    );
+
 typedef struct _XENBUS_FDO      XENBUS_FDO, *PXENBUS_FDO;
 typedef struct _XENBUS_PDO      XENBUS_PDO, *PXENBUS_PDO;
 
 #include "pdo.h"
 #include "fdo.h"
 
-extern PDRIVER_OBJECT   DriverObject;
-
-typedef struct _XENBUS_PARAMETERS {
-    PANSI_STRING    SupportedClasses;
-    PANSI_STRING    SyntheticClasses;
-    ULONG           CreatePDOs;
-    ULONG           Balloon;
-    ULONG           InterceptDmaAdapter;
-} XENBUS_PARAMETERS, *PXENBUS_PARAMETERS;
-
-extern XENBUS_PARAMETERS    DriverParameters;
-
 #define MAX_DEVICE_ID_LEN   200
 
 #pragma warning(push)
index 7dda022ea7a0f0ef24ddcbbefe73e9839c4a4f63..bc0f8bba600340fd3604003b11ae8855464bef89 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "evtchn.h"
 #include "fdo.h"
-#include "log.h"
+#include "dbg_print.h"
 #include "assert.h"
 
 typedef struct _EVTCHN_FIXED_PARAMETERS {
index 2805d85dafc2562c3331e1b26acfb5c573576db8..9e77c7de4b0e88456727005e7d199daa64fa418d 100644 (file)
@@ -53,7 +53,7 @@
 #include "sync.h"
 #include "balloon.h"
 #include "driver.h"
-#include "log.h"
+#include "dbg_print.h"
 #include "assert.h"
 
 #define FDO_TAG 'ODF'
@@ -74,10 +74,13 @@ struct _XENBUS_FDO {
     PXENBUS_THREAD                  DevicePowerThread;
     PIRP                            DevicePowerIrp;
 
+    CHAR                            VendorName[MAXNAMELEN];
+    BOOLEAN                         Active;
+
     PXENBUS_THREAD                  ScanThread;
     KEVENT                          ScanEvent;
     PXENBUS_STORE_WATCH             ScanWatch;
-    XENBUS_MUTEX                    Mutex;
+    MUTEX                           Mutex;
     ULONG                           References;
     PXENBUS_THREAD                  SuspendThread;
     KEVENT                          SuspendEvent;
@@ -257,39 +260,50 @@ FdoGetDmaAdapter(
                                             NumberOfMapRegisters);
 }
 
-static FORCEINLINE NTSTATUS
-__FdoSetName(
+static FORCEINLINE VOID
+__FdoSetVendorName(
     IN  PXENBUS_FDO Fdo,
-    IN  PWCHAR      Name
+    IN  USHORT      DeviceID
     )
 {
-    PXENBUS_DX      Dx = Fdo->Dx;
-    UNICODE_STRING  Unicode;
-    ANSI_STRING     Ansi;
-    ULONG           Index;
     NTSTATUS        status;
 
-    RtlInitUnicodeString(&Unicode, Name);
-
-    Ansi.Buffer = Dx->Name;
-    Ansi.MaximumLength = sizeof (Dx->Name);
-    Ansi.Length = 0;
+    status = RtlStringCbPrintfA(Fdo->VendorName,
+                                MAXNAMELEN,
+                                "XS%04X",
+                                DeviceID);
+    ASSERT(NT_SUCCESS(status));
+}
 
-    status = RtlUnicodeStringToAnsiString(&Ansi, &Unicode, FALSE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-    
-    for (Index = 0; Dx->Name[Index] != '\0'; Index++) {
-        if (!isalnum((UCHAR)Dx->Name[Index]))
-            Dx->Name[Index] = '_';
-    }
+static FORCEINLINE PCHAR
+__FdoGetVendorName(
+    IN  PXENBUS_FDO Fdo
+    )
+{
+    return Fdo->VendorName;
+}
 
-    return STATUS_SUCCESS;
+PCHAR
+FdoGetVendorName(
+    IN  PXENBUS_FDO Fdo
+    )
+{
+    return __FdoGetVendorName(Fdo);
+}
 
-fail1:
-    Error("fail1 (%08x)\n", status);
+static FORCEINLINE VOID
+__FdoSetName(
+    IN  PXENBUS_FDO Fdo
+    )
+{
+    PXENBUS_DX      Dx = Fdo->Dx;
+    NTSTATUS        status;
 
-    return status;
+    status = RtlStringCbPrintfA(Dx->Name,
+                                MAXNAMELEN,
+                                "%s XEN",
+                                __FdoGetVendorName(Fdo));
+    ASSERT(NT_SUCCESS(status));
 }
 
 static FORCEINLINE PCHAR
@@ -310,6 +324,23 @@ FdoGetName(
     return __FdoGetName(Fdo);
 }
 
+static FORCEINLINE VOID
+__FdoSetActive(
+    IN  PXENBUS_FDO Fdo,
+    IN  BOOLEAN     Active
+    )
+{
+    Fdo->Active = Active;
+}
+
+static FORCEINLINE BOOLEAN
+__FdoIsActive(
+    IN  PXENBUS_FDO Fdo
+    )
+{
+    return Fdo->Active;
+}
+
 __drv_functionClass(IO_COMPLETION_ROUTINE)
 __drv_sameIRQL
 static NTSTATUS
@@ -542,9 +573,6 @@ __FdoEnumerate(
 
     NeedInvalidate = FALSE;
 
-    if (DriverParameters.CreatePDOs == 0)
-        goto done;
-
     __FdoAcquireMutex(Fdo);
 
     ListEntry = Fdo->Dx->ListEntry.Flink;
@@ -558,12 +586,14 @@ __FdoEnumerate(
         Name = PdoGetName(Pdo);
         Missing = TRUE;
 
-        // If the PDO exists in either the class list or the synthetic list
-        // from xenstore then we don't want to remove it.
-
+        // If the PDO already exists ans its name is in the class list then
+        // we don't want to remove it.
         for (Index = 0; Classes[Index].Buffer != NULL; Index++) {
             PANSI_STRING Class = &Classes[Index];
 
+            if (Class->Length == 0)
+                continue;
+
             if (strcmp(Name, Class->Buffer) == 0) {
                 Missing = FALSE;
                 Class->Length = 0;  // avoid duplication
@@ -590,31 +620,7 @@ __FdoEnumerate(
         ListEntry = Next;
     }
 
-    // Check the class list from xenstore against the supported list
-    for (Index = 0; Classes[Index].Buffer != NULL; Index++) {
-        PANSI_STRING    Class = &Classes[Index];
-        ULONG           Entry;
-        BOOLEAN         Supported;
-
-        Supported = FALSE;
-
-        for (Entry = 0;
-             DriverParameters.SupportedClasses != NULL && DriverParameters.SupportedClasses[Entry].Buffer != NULL;
-             Entry++) {
-            if (strncmp(Class->Buffer,
-                        DriverParameters.SupportedClasses[Entry].Buffer,
-                        Class->Length) == 0) {
-                Supported = TRUE;
-                break;
-            }
-        }
-
-        if (!Supported)
-            Class->Length = 0;  // avoid creation
-    }
-
     // Walk the class list and create PDOs for any new classes
-
     for (Index = 0; Classes[Index].Buffer != NULL; Index++) {
         PANSI_STRING Class = &Classes[Index];
 
@@ -629,7 +635,6 @@ __FdoEnumerate(
 
     __FdoReleaseMutex(Fdo);
 
-done:
     Trace("<====\n");
 
     return NeedInvalidate;
@@ -811,16 +816,22 @@ FdoScan(
 {
     PXENBUS_FDO         Fdo = Context;
     PKEVENT             Event;
+    HANDLE              ParametersKey;
     NTSTATUS            status;
 
     Trace("====>\n");
 
     Event = ThreadGetEvent(Self);
 
+    ParametersKey = DriverGetParametersKey();
+
     for (;;) {
         PCHAR           Buffer;
         PANSI_STRING    StoreClasses;
+        PANSI_STRING    SyntheticClasses;
+        PANSI_STRING    SupportedClasses;
         PANSI_STRING    Classes;
+        ULONG           Index;
         BOOLEAN         NeedInvalidate;
 
         Trace("waiting...\n");
@@ -857,14 +868,62 @@ FdoScan(
             StoreClasses = NULL;
         }
 
-        Classes = __FdoCombineAnsi(StoreClasses, DriverParameters.SyntheticClasses);
+        if (ParametersKey != NULL) {
+            status = RegistryQuerySzValue(ParametersKey,
+                                          "SyntheticClasses",
+                                          &SyntheticClasses);
+            ASSERT(IMPLY(!NT_SUCCESS(status), SyntheticClasses == NULL));
+        } else {
+            SyntheticClasses = NULL;
+        }
+
+        Classes = __FdoCombineAnsi(StoreClasses, SyntheticClasses);
 
         if (StoreClasses != NULL)
             __FdoFreeAnsi(StoreClasses);
 
+        if (SyntheticClasses != NULL)
+            RegistryFreeSzValue(SyntheticClasses);
+
         if (Classes == NULL)
             goto loop;
 
+        if (ParametersKey != NULL) {
+            status = RegistryQuerySzValue(ParametersKey,
+                                          "SupportedClasses",
+                                          &SupportedClasses);
+            ASSERT(IMPLY(!NT_SUCCESS(status), SyntheticClasses == NULL));
+        } else {
+            SupportedClasses = NULL;
+        }
+
+        // NULL out anything in the Classes list that not in the
+        // SupportedClasses list    
+        for (Index = 0; Classes[Index].Buffer != NULL; Index++) {
+            PANSI_STRING    Class = &Classes[Index];
+            ULONG           Entry;
+            BOOLEAN         Supported;
+
+            Supported = FALSE;
+
+            for (Entry = 0;
+                 SupportedClasses != NULL && SupportedClasses[Entry].Buffer != NULL;
+                 Entry++) {
+                if (strncmp(Class->Buffer,
+                            SupportedClasses[Entry].Buffer,
+                            Class->Length) == 0) {
+                    Supported = TRUE;
+                    break;
+                }
+            }
+
+            if (!Supported)
+                Class->Length = 0;
+        }
+
+        if (SupportedClasses != NULL)
+            RegistryFreeSzValue(SupportedClasses);
+
         NeedInvalidate = __FdoEnumerate(Fdo, Classes);
 
         __FdoFreeAnsi(Classes);
@@ -975,7 +1034,7 @@ FdoBalloon(
     PXENBUS_FDO         Fdo = Context;
     PKEVENT             Event;
     BOOLEAN             Active;
-    static ULONGLONG    Maximum;    // Should never change in the lifetime of the VM
+    ULONGLONG           Maximum = 0;
     NTSTATUS            status;
 
     Trace("====>\n");
@@ -1011,20 +1070,43 @@ FdoBalloon(
         if (__FdoGetDevicePowerState(Fdo) != PowerDeviceD0)
             goto loop;
 
+        // Only sample this if it's zero as it should never change
+        // during the lifetime of the domain.
         if (Maximum == 0) {
+            ULONGLONG   VideoRAM;
+
             status = STORE(Read,
                            &Fdo->StoreInterface,
                            NULL,
                            "memory",
                            "static-max",
                            &Buffer);
-            if (!NT_SUCCESS(status))
+            if (NT_SUCCESS(status)) {
+                Maximum = _strtoui64(Buffer, NULL, 10);
+                STORE(Free,
+                      &Fdo->StoreInterface,
+                      Buffer);
+            } else {
                 goto loop;
+            }
 
-            Maximum = _strtoui64(Buffer, NULL, 10) / 4;
-            STORE(Free,
-                  &Fdo->StoreInterface,
-                  Buffer);
+            status = STORE(Read,
+                           &Fdo->StoreInterface,
+                           NULL,
+                           "memory",
+                           "videoram",
+                           &Buffer);
+            if (NT_SUCCESS(status)) {
+                VideoRAM = _strtoui64(Buffer, NULL, 10);
+                STORE(Free,
+                      &Fdo->StoreInterface,
+                      Buffer);
+            } else {
+                VideoRAM = 0;
+            }
+
+            Maximum -= VideoRAM;
+            Maximum /= 4;   // We need the value in pages
         }
 
         status = STORE(Read,
@@ -1440,7 +1522,6 @@ __FdoD3ToD0(
     IN  PXENBUS_FDO Fdo
     )
 {
-    POWER_STATE     PowerState;
     BOOLEAN         Pending;
     NTSTATUS        status;
 
@@ -1471,8 +1552,6 @@ __FdoD3ToD0(
                &Fdo->EvtchnInterface,
                Fdo->Evtchn);
 
-    __FdoSetDevicePowerState(Fdo, PowerDeviceD0);
-
     STORE(Acquire, &Fdo->StoreInterface);
 
     status = STORE(Watch,
@@ -1520,11 +1599,6 @@ __FdoD3ToD0(
                         1);
     }
 
-    PowerState.DeviceState = PowerDeviceD0;
-    PoSetPowerState(Fdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
-
     Trace("<====\n");
 
     return STATUS_SUCCESS;
@@ -1556,8 +1630,6 @@ fail2:
 
     STORE(Release, &Fdo->StoreInterface);
 
-    __FdoSetDevicePowerState(Fdo, PowerDeviceD3);
-
     EVTCHN(Close,
            &Fdo->EvtchnInterface,
            Fdo->Evtchn);
@@ -1576,17 +1648,9 @@ __FdoD0ToD3(
     IN  PXENBUS_FDO Fdo
     )
 {
-    POWER_STATE     PowerState;
-
     Trace("====>\n");
 
     ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
-    ASSERT3U(__FdoGetDevicePowerState(Fdo), ==, PowerDeviceD0);
-
-    PowerState.DeviceState = PowerDeviceD3;
-    PoSetPowerState(Fdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
 
     if (Fdo->Balloon != NULL) {
         (VOID) STORE(Remove,
@@ -1619,8 +1683,6 @@ __FdoD0ToD3(
 
     STORE(Release, &Fdo->StoreInterface);
 
-    __FdoSetDevicePowerState(Fdo, PowerDeviceD3);
-
     EVTCHN(Close,
            &Fdo->EvtchnInterface,
            Fdo->Evtchn);
@@ -1650,11 +1712,18 @@ FdoD3ToD0(
     IN  PXENBUS_FDO Fdo
     )
 {
+    POWER_STATE     PowerState;
     KIRQL           Irql;
     PLIST_ENTRY     ListEntry;
     NTSTATUS        status;
 
     ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+    ASSERT3U(__FdoGetDevicePowerState(Fdo), ==, PowerDeviceD3);
+
+    Trace("====>\n");
+
+    if (!__FdoIsActive(Fdo))
+        goto done;
 
     KeRaiseIrql(DISPATCH_LEVEL, &Irql);
 
@@ -1675,6 +1744,14 @@ FdoD3ToD0(
 
     KeLowerIrql(Irql);
 
+done:
+    __FdoSetDevicePowerState(Fdo, PowerDeviceD0);
+
+    PowerState.DeviceState = PowerDeviceD0;
+    PoSetPowerState(Fdo->Dx->DeviceObject,
+                    DevicePowerState,
+                    PowerState);
+
     __FdoAcquireMutex(Fdo);
 
     for (ListEntry = Fdo->Dx->ListEntry.Flink;
@@ -1690,6 +1767,8 @@ FdoD3ToD0(
 
     __FdoReleaseMutex(Fdo);
 
+    Trace("<====\n");
+
     return STATUS_SUCCESS;
 
 fail2:
@@ -1740,10 +1819,14 @@ FdoD0ToD3(
     IN  PXENBUS_FDO Fdo
     )
 {
+    POWER_STATE     PowerState;
     PLIST_ENTRY     ListEntry;
     KIRQL           Irql;
 
     ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+    ASSERT3U(__FdoGetDevicePowerState(Fdo), ==, PowerDeviceD0);
+
+    Trace("====>\n");
 
     __FdoAcquireMutex(Fdo);
 
@@ -1764,6 +1847,16 @@ FdoD0ToD3(
 
     __FdoReleaseMutex(Fdo);
 
+    PowerState.DeviceState = PowerDeviceD3;
+    PoSetPowerState(Fdo->Dx->DeviceObject,
+                    DevicePowerState,
+                    PowerState);
+
+    __FdoSetDevicePowerState(Fdo, PowerDeviceD3);
+
+    if (!__FdoIsActive(Fdo))
+        goto done;
+
     KeRaiseIrql(DISPATCH_LEVEL, &Irql);
 
     SUSPEND(Deregister,
@@ -1800,6 +1893,8 @@ FdoD0ToD3(
                                  KernelMode,
                                  FALSE,
                                  NULL);
+done:
+    Trace("<====\n");
 }
 
 static DECLSPEC_NOINLINE NTSTATUS
@@ -1815,6 +1910,9 @@ FdoS4ToS3(
     ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
     ASSERT3U(__FdoGetSystemPowerState(Fdo), ==, PowerSystemHibernate);
 
+    if (!__FdoIsActive(Fdo))
+        goto done;
+
     KeRaiseIrql(DISPATCH_LEVEL, &Irql); // Flush out any attempt to use pageable memory
 
     status = DebugInitialize(Fdo, &Fdo->DebugInterface);
@@ -1847,6 +1945,7 @@ FdoS4ToS3(
 
     KeLowerIrql(Irql);
 
+done:
     Trace("<====\n");
 
     return STATUS_SUCCESS;
@@ -1894,6 +1993,9 @@ FdoS3ToS4(
     ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
     ASSERT3U(__FdoGetSystemPowerState(Fdo), ==, PowerSystemSleeping3);
 
+    if (!__FdoIsActive(Fdo))
+        goto done;
+
     __FdoDisableInterrupt(Fdo);
 
     __FdoSetSystemPowerState(Fdo, PowerSystemHibernate);
@@ -1910,6 +2012,7 @@ FdoS3ToS4(
 
     DebugTeardown(&Fdo->DebugInterface);
 
+done:
     Trace("<====\n");
 }
 
@@ -1934,6 +2037,9 @@ FdoStartDevice(
                       StackLocation->Parameters.StartDevice.AllocatedResources,
                       StackLocation->Parameters.StartDevice.AllocatedResourcesTranslated);
 
+    if (!__FdoIsActive(Fdo))
+        goto done;
+
     status = FdoConnectInterrupt(Fdo);
     if (!NT_SUCCESS(status))
         goto fail2;
@@ -1958,6 +2064,7 @@ FdoStartDevice(
             goto fail5;
     }
 
+done:
     __FdoSetSystemPowerState(Fdo, PowerSystemHibernate);
 
     status = FdoS4ToS3(Fdo);
@@ -1973,6 +2080,8 @@ FdoStartDevice(
     if (Fdo->Balloon != NULL) {
         BOOLEAN Warned;
 
+        ASSERT(__FdoIsActive(Fdo));
+
         Warned = FALSE;
 
         for (;;) {
@@ -1996,7 +2105,9 @@ FdoStartDevice(
     }
 
     __FdoSetDevicePnpState(Fdo, Started);
-    ThreadWake(Fdo->ScanThread);
+
+    if (__FdoIsActive(Fdo))
+        ThreadWake(Fdo->ScanThread);
 
     status = Irp->IoStatus.Status;
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
@@ -2014,6 +2125,9 @@ fail6:
 
     __FdoSetSystemPowerState(Fdo, PowerSystemShutdown);
 
+    if (!__FdoIsActive(Fdo))
+        goto fail2;
+    
     if (Fdo->Balloon != NULL) {
         ThreadAlert(Fdo->BalloonThread);
         ThreadJoin(Fdo->BalloonThread);
@@ -2115,6 +2229,9 @@ FdoStopDevice(
 {
     NTSTATUS        status;
 
+    if (__FdoGetDevicePowerState(Fdo) != PowerDeviceD0)
+        goto done;
+
     FdoD0ToD3(Fdo);
 
     __FdoSetSystemPowerState(Fdo, PowerSystemSleeping3);
@@ -2129,6 +2246,9 @@ FdoStopDevice(
         RtlZeroMemory(&Fdo->BalloonEvent, sizeof (KEVENT));
     }
 
+    if (!__FdoIsActive(Fdo))
+        goto done;
+
     ThreadAlert(Fdo->SuspendThread);
     ThreadJoin(Fdo->SuspendThread);
     Fdo->SuspendThread = NULL;
@@ -2143,6 +2263,7 @@ FdoStopDevice(
 
     FdoDisconnectInterrupt(Fdo);
 
+done:
     RtlZeroMemory(&Fdo->Resource, sizeof (XENBUS_RESOURCE) * RESOURCE_COUNT);
 
     __FdoSetDevicePnpState(Fdo, Stopped);
@@ -2250,16 +2371,18 @@ FdoRemoveDevice(
     if (__FdoGetDevicePowerState(Fdo) != PowerDeviceD0)
         goto done;
 
-    KeClearEvent(&Fdo->ScanEvent);
-    ThreadWake(Fdo->ScanThread);
+    if (__FdoIsActive(Fdo)) {
+        KeClearEvent(&Fdo->ScanEvent);
+        ThreadWake(Fdo->ScanThread);
 
-    Trace("waiting for scan thread\n");
+        Trace("waiting for scan thread\n");
 
-    (VOID) KeWaitForSingleObject(&Fdo->ScanEvent,
-                                 Executive,
-                                 KernelMode,
-                                 FALSE,
-                                 NULL);
+        (VOID) KeWaitForSingleObject(&Fdo->ScanEvent,
+                                     Executive,
+                                     KernelMode,
+                                     FALSE,
+                                     NULL);
+    }
 
     __FdoAcquireMutex(Fdo);
 
@@ -2299,6 +2422,9 @@ FdoRemoveDevice(
         RtlZeroMemory(&Fdo->BalloonEvent, sizeof (KEVENT));
     }
 
+    if (!__FdoIsActive(Fdo))
+        goto done;
+
     ThreadAlert(Fdo->SuspendThread);
     ThreadJoin(Fdo->SuspendThread);
     Fdo->SuspendThread = NULL;
@@ -2313,9 +2439,9 @@ FdoRemoveDevice(
 
     FdoDisconnectInterrupt(Fdo);
 
+done:
     RtlZeroMemory(&Fdo->Resource, sizeof (XENBUS_RESOURCE) * RESOURCE_COUNT);
 
-done:
     __FdoSetDevicePnpState(Fdo, Deleted);
 
     Irp->IoStatus.Status = STATUS_SUCCESS;
@@ -2368,6 +2494,9 @@ FdoQueryDeviceRelations(
     for (;;) {
         LARGE_INTEGER   Timeout;
 
+        if (!__FdoIsActive(Fdo))
+            break;
+
         Timeout.QuadPart = TIME_RELATIVE(TIME_S(SCAN_PAUSE));
 
         status = KeWaitForSingleObject(&Fdo->ScanEvent,
@@ -3510,20 +3639,49 @@ __FdoReleaseLowerBusInterface(
     RtlZeroMemory(BusInterface, sizeof (BUS_INTERFACE_STANDARD));
 }
 
+static FORCEINLINE BOOLEAN
+__FdoIsBalloonEnabled(
+    VOID
+    )
+{
+    CHAR            Key[] = "XEN:BALLOON=";
+    PANSI_STRING    Option;
+    PCHAR           Value;
+    BOOLEAN         Enabled;
+    NTSTATUS        status;
+
+    Enabled = TRUE;
+
+    status = RegistryQuerySystemStartOption(Key, &Option);
+    if (!NT_SUCCESS(status))
+        goto done;
+
+    Value = Option->Buffer + sizeof (Key) - 1;
+
+    if (strcmp(Value, "OFF") == 0)
+        Enabled = FALSE;
+
+    RegistryFreeSzValue(Option);
+
+done:
+    return Enabled;
+}
+
 NTSTATUS
 FdoCreate(
-    IN  PDEVICE_OBJECT  PhysicalDeviceObject
+    IN  PDEVICE_OBJECT      PhysicalDeviceObject,
+    IN  BOOLEAN             Active      
     )
 {
-    PDEVICE_OBJECT      FunctionDeviceObject;
-    PXENBUS_DX          Dx;
-    PXENBUS_FDO         Fdo;
-    WCHAR               Name[MAXNAMELEN * sizeof (WCHAR)];
-    ULONG               Size;
-    NTSTATUS            status;
+    PDEVICE_OBJECT          FunctionDeviceObject;
+    PXENBUS_DX              Dx;
+    PXENBUS_FDO             Fdo;
+    PBUS_INTERFACE_STANDARD BusInterface;
+    USHORT                  DeviceID;
+    NTSTATUS                status;
 
 #pragma prefast(suppress:28197) // Possibly leaking memory 'FunctionDeviceObject'
-    status = IoCreateDevice(DriverObject,
+    status = IoCreateDevice(DriverGetDriverObject(),
                             sizeof (XENBUS_DX),
                             NULL,
                             FILE_DEVICE_BUS_EXTENDER,
@@ -3561,28 +3719,31 @@ FdoCreate(
     if (!NT_SUCCESS(status))
         goto fail4;
 
-    status = IoGetDeviceProperty(PhysicalDeviceObject,
-                                 DevicePropertyLocationInformation,
-                                 sizeof (Name),
-                                 Name,
-                                 &Size);
+    status = __FdoAcquireLowerBusInterface(Fdo);
     if (!NT_SUCCESS(status))
         goto fail5;
 
-    status = __FdoSetName(Fdo, Name);
-    if (!NT_SUCCESS(status))
+    BusInterface = &Fdo->LowerBusInterface;
+
+    status = STATUS_UNSUCCESSFUL;
+    if (BusInterface->GetBusData(BusInterface->Context,
+                                 PCI_WHICHSPACE_CONFIG,
+                                 &DeviceID,
+                                 FIELD_OFFSET(PCI_COMMON_HEADER, DeviceID),
+                                 FIELD_SIZE(PCI_COMMON_HEADER, DeviceID)) == 0)
         goto fail6;
 
-    status = __FdoAcquireLowerBusInterface(Fdo);
-    if (!NT_SUCCESS(status))
-        goto fail7;
+    __FdoSetVendorName(Fdo, DeviceID);
+
+    __FdoSetName(Fdo);
 
-    if (DriverParameters.Balloon != 0) {
+    __FdoSetActive(Fdo, Active);
+
+    if (__FdoIsActive(Fdo) &&
+        __FdoIsBalloonEnabled()) {
         status = BalloonInitialize(&Fdo->Balloon);
         if (!NT_SUCCESS(status))
-            goto fail8;
-    } else {
-        Info("BALLOON DISABLED\n");
+            goto fail7;
     }
 
     InitializeMutex(&Fdo->Mutex);
@@ -3598,17 +3759,18 @@ FdoCreate(
 
     return STATUS_SUCCESS;
 
-fail8:
-    Error("fail8\n");
-
-    __FdoReleaseLowerBusInterface(Fdo);
-
 fail7:
     Error("fail7\n");
 
+    __FdoSetActive(Fdo, FALSE);
+
+    RtlZeroMemory(Fdo->VendorName, MAXNAMELEN);
+
 fail6:
     Error("fail6\n");
 
+    __FdoReleaseLowerBusInterface(Fdo);
+
 fail5:
     Error("fail5\n");
 
@@ -3667,13 +3829,17 @@ FdoDestroy(
 
     Dx->Fdo = NULL;
 
-    RtlZeroMemory(&Fdo->Mutex, sizeof (XENBUS_MUTEX));
+    RtlZeroMemory(&Fdo->Mutex, sizeof (MUTEX));
 
     if (Fdo->Balloon != NULL) {
         BalloonTeardown(Fdo->Balloon);
         Fdo->Balloon = NULL;
     }
 
+    __FdoSetActive(Fdo, FALSE);
+
+    RtlZeroMemory(Fdo->VendorName, MAXNAMELEN);
+
     __FdoReleaseLowerBusInterface(Fdo);
 
     ThreadAlert(Fdo->DevicePowerThread);
index cebcd98c54e76c52a6a173adb70f9109e75a3646..def509f83512580a2d0ce729adc904906a6ec646 100644 (file)
@@ -50,7 +50,8 @@ typedef struct _XENBUS_RESOURCE {
 
 extern NTSTATUS
 FdoCreate(
-    IN  PDEVICE_OBJECT  PhysicalDeviceObject
+    IN  PDEVICE_OBJECT  PhysicalDeviceObject,
+    IN  BOOLEAN         Active
     );
 
 extern VOID
@@ -60,30 +61,30 @@ FdoDestroy(
 
 extern NTSTATUS
 FdoDelegateIrp(
-    IN  PXENBUS_FDO     Fdo,
-    IN  PIRP            Irp
+    IN  PXENBUS_FDO Fdo,
+    IN  PIRP        Irp
     );
 
 extern VOID
 FdoAddPhysicalDeviceObject(
-    IN  PXENBUS_FDO     Fdo,
-    IN  PXENBUS_PDO     Pdo
+    IN  PXENBUS_FDO Fdo,
+    IN  PXENBUS_PDO Pdo
     );
 
 extern VOID
 FdoRemovePhysicalDeviceObject(
-    IN  PXENBUS_FDO     Fdo,
-    IN  PXENBUS_PDO     Pdo
+    IN  PXENBUS_FDO Fdo,
+    IN  PXENBUS_PDO Pdo
     );
 
 extern VOID
 FdoAcquireMutex(
-    IN  PXENBUS_FDO     Fdo
+    IN  PXENBUS_FDO Fdo
     );
 
 extern VOID
 FdoReleaseMutex(
-    IN  PXENBUS_FDO     Fdo
+    IN  PXENBUS_FDO Fdo
     );
 
 extern PDEVICE_OBJECT
@@ -103,6 +104,11 @@ FdoGetName(
     IN  PXENBUS_FDO Fdo
     );
 
+PCHAR
+FdoGetVendorName(
+    IN  PXENBUS_FDO Fdo
+    );
+
 extern PXENBUS_RESOURCE
 FdoGetResource(
     IN  PXENBUS_FDO             Fdo,
@@ -118,42 +124,42 @@ FdoGetInterruptObject(
 
 extern PXENBUS_SUSPEND_INTERFACE
 FdoGetSuspendInterface(
-    IN  PXENBUS_FDO     Fdo
+    IN  PXENBUS_FDO Fdo
     );
 
 #include "shared_info.h"
 
 extern PXENBUS_SHARED_INFO_INTERFACE
 FdoGetSharedInfoInterface(
-    IN  PXENBUS_FDO     Fdo
+    IN  PXENBUS_FDO Fdo
     );
 
 #include "evtchn.h"
 
 extern PXENBUS_EVTCHN_INTERFACE
 FdoGetEvtchnInterface(
-    IN  PXENBUS_FDO     Fdo
+    IN  PXENBUS_FDO Fdo
     );
 
 #include "debug.h"
 
 extern PXENBUS_DEBUG_INTERFACE
 FdoGetDebugInterface(
-    IN  PXENBUS_FDO     Fdo
+    IN  PXENBUS_FDO Fdo
     );
 
 #include "store.h"
 
 extern PXENBUS_STORE_INTERFACE
 FdoGetStoreInterface(
-    IN  PXENBUS_FDO     Fdo
+    IN  PXENBUS_FDO Fdo
     );
 
 #include "gnttab.h"
 
 extern PXENBUS_GNTTAB_INTERFACE
 FdoGetGnttabInterface(
-    IN  PXENBUS_FDO     Fdo
+    IN  PXENBUS_FDO Fdo
     );
 
 extern NTSTATUS
index f46a522ba94521f66509c3f96593f6f9d7b1a165..a6b3eb04c9c704c491c0a53188e482f0c4714a97 100644 (file)
@@ -37,7 +37,7 @@
 
 #include "gnttab.h"
 #include "fdo.h"
-#include "log.h"
+#include "dbg_print.h"
 #include "assert.h"
 
 #define GNTTAB_MAXIMUM_ENTRY_FRAME_COUNT    32
diff --git a/src/xenbus/high.h b/src/xenbus/high.h
deleted file mode 100644 (file)
index 3f67a0e..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/* 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 _XENBUS_HIGH_H
-#define _XENBUS_HIGH_H
-
-#include <ntddk.h>
-
-#pragma warning(disable:4127)   // conditional expression is constant
-
-typedef LONG    HIGH_LOCK, *PHIGH_LOCK;
-
-#define LOCK_MAGIC  0xFEEDFACE
-
-static FORCEINLINE
-__drv_maxIRQL(HIGH_LEVEL)
-__drv_raisesIRQL(HIGH_LEVEL)
-__drv_savesIRQL
-KIRQL
-__AcquireHighLock(
-    IN  PHIGH_LOCK  Lock
-    )
-{
-    KIRQL           Irql;
-
-    KeRaiseIrql(HIGH_LEVEL, &Irql);
-
-    while (InterlockedCompareExchange(Lock, LOCK_MAGIC, 0) != 0)
-        _mm_pause();
-
-    KeMemoryBarrier();
-
-    return Irql;
-}
-
-#define AcquireHighLock(_Lock, _Irql)               \
-        do {                                        \
-            *(_Irql) = __AcquireHighLock(_Lock);    \
-        } while (FALSE)
-
-static FORCEINLINE
-__drv_maxIRQL(HIGH_LEVEL)
-__drv_requiresIRQL(HIGH_LEVEL)
-VOID
-ReleaseHighLock(
-    IN  PHIGH_LOCK                  Lock,
-    IN  __drv_restoresIRQL KIRQL    Irql
-    )
-{
-    KeMemoryBarrier();
-
-    InterlockedExchange(Lock, 0);
-    KeLowerIrql(Irql);
-}
-
-static FORCEINLINE
-VOID
-InitializeHighLock(
-    IN  PHIGH_LOCK  Lock
-    )
-{
-    RtlZeroMemory(&Lock, sizeof (HIGH_LOCK));
-}
-
-#endif  // _XENBUS_HIGH_H
diff --git a/src/xenbus/log.h b/src/xenbus/log.h
deleted file mode 100644 (file)
index 8799ce7..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/* 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 _XENBUS_LOG_H
-#define _XENBUS_LOG_H
-
-#define __MODULE__ "XENBUS"
-
-#include <ntddk.h>
-#include <stdarg.h>
-
-#pragma warning(disable:4127)   // conditional expression is constant
-
-static __inline VOID
-__Error(
-    IN  const CHAR  *Prefix,
-    IN  const CHAR  *Format,
-    ...
-    )
-{
-    va_list         Arguments;
-
-    va_start(Arguments, Format);
-
-#pragma prefast(suppress:6001) // Using uninitialized memory
-    vDbgPrintExWithPrefix(Prefix,
-                          DPFLTR_IHVDRIVER_ID,
-                          DPFLTR_ERROR_LEVEL,
-                          Format,
-                          Arguments);
-    va_end(Arguments);
-}
-
-#define Error(...)  \
-        __Error(__MODULE__ "|" __FUNCTION__ ": ", __VA_ARGS__)
-
-static __inline VOID
-__Warning(
-    IN  const CHAR  *Prefix,
-    IN  const CHAR  *Format,
-    ...
-    )
-{
-    va_list         Arguments;
-
-    va_start(Arguments, Format);
-
-#pragma prefast(suppress:6001) // Using uninitialized memory
-    vDbgPrintExWithPrefix(Prefix,
-                          DPFLTR_IHVDRIVER_ID,
-                          DPFLTR_WARNING_LEVEL,
-                          Format,
-                          Arguments);
-    va_end(Arguments);
-}
-
-#define Warning(...)  \
-        __Warning(__MODULE__ "|" __FUNCTION__ ": ", __VA_ARGS__)
-
-#if DBG
-static __inline VOID
-__Trace(
-    IN  const CHAR  *Prefix,
-    IN  const CHAR  *Format,
-    ...
-    )
-{
-    va_list         Arguments;
-
-    va_start(Arguments, Format);
-
-#pragma prefast(suppress:6001) // Using uninitialized memory
-    vDbgPrintExWithPrefix(Prefix,
-                          DPFLTR_IHVDRIVER_ID,
-                          DPFLTR_TRACE_LEVEL,
-                          Format,
-                          Arguments);
-    va_end(Arguments);
-}
-
-#define Trace(...)  \
-        __Trace(__MODULE__ "|" __FUNCTION__ ": ", __VA_ARGS__)
-#else   // DBG
-#define Trace(...)  (VOID)(__VA_ARGS__)
-#endif  // DBG
-
-static __inline VOID
-__Info(
-    IN  const CHAR  *Prefix,
-    IN  const CHAR  *Format,
-    ...
-    )
-{
-    va_list         Arguments;
-
-    va_start(Arguments, Format);
-
-#pragma prefast(suppress:6001) // Using uninitialized memory
-    vDbgPrintExWithPrefix(Prefix,
-                          DPFLTR_IHVDRIVER_ID,
-                          DPFLTR_INFO_LEVEL,
-                          Format,
-                          Arguments);
-    va_end(Arguments);
-}
-
-#define Info(...)  \
-        __Info(__MODULE__ "|"  __FUNCTION__ ": ", __VA_ARGS__)
-
-#endif  // _XENBUS_LOG_H
diff --git a/src/xenbus/mutex.h b/src/xenbus/mutex.h
deleted file mode 100644 (file)
index b12e44a..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/* 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 _XENBUS_MUTEX_H
-#define _XENBUS_MUTEX_H
-
-#include <ntddk.h>
-
-#include "assert.h"
-
-typedef struct _XENBUS_MUTEX {
-    PKTHREAD        Owner;
-    KEVENT          Event;
-} XENBUS_MUTEX, *PXENBUS_MUTEX;
-
-static FORCEINLINE VOID
-InitializeMutex(
-    IN  PXENBUS_MUTEX   Mutex
-    )
-{
-    RtlZeroMemory(Mutex, sizeof (XENBUS_MUTEX));
-
-    KeInitializeEvent(&Mutex->Event, SynchronizationEvent, TRUE);
-}
-
-static FORCEINLINE VOID
-__drv_maxIRQL(PASSIVE_LEVEL)
-AcquireMutex(
-    IN  PXENBUS_MUTEX   Mutex
-    )
-{
-    (VOID) KeWaitForSingleObject(&Mutex->Event,
-                                 Executive,
-                                 KernelMode,
-                                 FALSE,
-                                 NULL);
-
-    ASSERT3P(Mutex->Owner, ==, NULL);
-    Mutex->Owner = KeGetCurrentThread();
-}
-
-static FORCEINLINE VOID
-__drv_maxIRQL(PASSIVE_LEVEL)
-ReleaseMutex(
-    IN  PXENBUS_MUTEX   Mutex
-    )
-{
-    ASSERT3P(Mutex->Owner, ==, KeGetCurrentThread());
-    Mutex->Owner = NULL;
-
-    KeSetEvent(&Mutex->Event, IO_NO_INCREMENT, FALSE);
-}
-
-#endif  // _XENBUS_MUTEX_H
diff --git a/src/xenbus/names.h b/src/xenbus/names.h
deleted file mode 100644 (file)
index b8d7e3a..0000000
+++ /dev/null
@@ -1,367 +0,0 @@
-/* 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 _XENBUS_NAMES_H_
-#define _XENBUS_NAMES_H_
-
-#include <ntddk.h>
-
-#include "types.h"
-
-static FORCEINLINE const CHAR *
-PowerTypeName(
-    IN  POWER_STATE_TYPE    Type
-    )
-{
-#define _POWER_TYPE_NAME(_Type) \
-        case _Type:             \
-            return #_Type;
-
-    switch (Type) {
-    _POWER_TYPE_NAME(SystemPowerState);
-    _POWER_TYPE_NAME(DevicePowerState);
-    default:
-        break;
-    }
-
-    return ("UNKNOWN");
-#undef  _POWER_ACTION_NAME
-}
-
-static FORCEINLINE const CHAR *
-PowerSystemStateName(
-    IN  SYSTEM_POWER_STATE State
-    )
-{
-#define _POWER_SYSTEM_STATE_NAME(_State)    \
-        case PowerSystem ## _State:         \
-            return #_State;
-
-    switch (State) {
-    _POWER_SYSTEM_STATE_NAME(Unspecified);
-    _POWER_SYSTEM_STATE_NAME(Working);
-    _POWER_SYSTEM_STATE_NAME(Sleeping1);
-    _POWER_SYSTEM_STATE_NAME(Sleeping2);
-    _POWER_SYSTEM_STATE_NAME(Sleeping3);
-    _POWER_SYSTEM_STATE_NAME(Hibernate);
-    _POWER_SYSTEM_STATE_NAME(Shutdown);
-    _POWER_SYSTEM_STATE_NAME(Maximum);
-    default:
-        break;
-    }
-
-    return ("UNKNOWN");
-#undef  _POWER_SYSTEM_STATE_NAME
-}
-
-static FORCEINLINE const CHAR *
-PowerDeviceStateName(
-    IN  DEVICE_POWER_STATE State
-    )
-{
-#define _POWER_DEVICE_STATE_NAME(_State)    \
-        case PowerDevice ## _State:         \
-            return #_State;
-
-    switch (State) {
-    _POWER_DEVICE_STATE_NAME(Unspecified);
-    _POWER_DEVICE_STATE_NAME(D0);
-    _POWER_DEVICE_STATE_NAME(D1);
-    _POWER_DEVICE_STATE_NAME(D2);
-    _POWER_DEVICE_STATE_NAME(D3);
-    _POWER_DEVICE_STATE_NAME(Maximum);
-    default:
-        break;
-    }
-
-    return ("UNKNOWN");
-#undef  _POWER_DEVICE_STATE_NAME
-}
-
-static FORCEINLINE const CHAR *
-PowerActionName(
-    IN  POWER_ACTION    Type
-    )
-{
-#define _POWER_ACTION_NAME(_Type)   \
-        case PowerAction ## _Type:  \
-            return #_Type;
-
-    switch (Type) {
-    _POWER_ACTION_NAME(None);
-    _POWER_ACTION_NAME(Reserved);
-    _POWER_ACTION_NAME(Sleep);
-    _POWER_ACTION_NAME(Hibernate);
-    _POWER_ACTION_NAME(Shutdown);
-    _POWER_ACTION_NAME(ShutdownReset);
-    _POWER_ACTION_NAME(ShutdownOff);
-    _POWER_ACTION_NAME(WarmEject);
-    default:
-        break;
-    }
-
-    return ("UNKNOWN");
-#undef  _POWER_ACTION_NAME
-}
-
-static FORCEINLINE const CHAR *
-PowerMinorFunctionName(
-    IN  ULONG   MinorFunction
-    )
-{
-#define _POWER_MINOR_FUNCTION_NAME(_Function)   \
-    case IRP_MN_ ## _Function:                  \
-        return #_Function;
-
-    switch (MinorFunction) {
-    _POWER_MINOR_FUNCTION_NAME(WAIT_WAKE);
-    _POWER_MINOR_FUNCTION_NAME(POWER_SEQUENCE);
-    _POWER_MINOR_FUNCTION_NAME(SET_POWER);
-    _POWER_MINOR_FUNCTION_NAME(QUERY_POWER);
-
-    default:
-        return "UNKNOWN";
-    }
-
-#undef  _POWER_MINOR_FUNCTION_NAME
-}
-
-static FORCEINLINE const CHAR *
-PnpDeviceStateName(
-    IN  DEVICE_PNP_STATE    State
-    )
-{
-#define _PNP_DEVICE_STATE_NAME(_State) \
-    case  _State:               \
-        return #_State;
-
-    switch (State) {
-    _PNP_DEVICE_STATE_NAME(Invalid);
-    _PNP_DEVICE_STATE_NAME(Present);
-    _PNP_DEVICE_STATE_NAME(Enumerated);
-    _PNP_DEVICE_STATE_NAME(Added);
-    _PNP_DEVICE_STATE_NAME(Started);
-    _PNP_DEVICE_STATE_NAME(StopPending);
-    _PNP_DEVICE_STATE_NAME(Stopped);
-    _PNP_DEVICE_STATE_NAME(RemovePending);
-    _PNP_DEVICE_STATE_NAME(SurpriseRemovePending);
-    _PNP_DEVICE_STATE_NAME(Deleted);
-    default:
-        break;
-    }
-
-    return "UNKNOWN";
-
-#undef  _STATE_NAME
-}
-
-static FORCEINLINE const CHAR *
-PnpMinorFunctionName(
-    IN  ULONG   Function
-    )
-{
-#define _PNP_MINOR_FUNCTION_NAME(_Function) \
-    case IRP_MN_ ## _Function:              \
-        return #_Function;
-
-    switch (Function) {
-    _PNP_MINOR_FUNCTION_NAME(START_DEVICE);
-    _PNP_MINOR_FUNCTION_NAME(QUERY_REMOVE_DEVICE);
-    _PNP_MINOR_FUNCTION_NAME(REMOVE_DEVICE);
-    _PNP_MINOR_FUNCTION_NAME(CANCEL_REMOVE_DEVICE);
-    _PNP_MINOR_FUNCTION_NAME(STOP_DEVICE);
-    _PNP_MINOR_FUNCTION_NAME(QUERY_STOP_DEVICE);
-    _PNP_MINOR_FUNCTION_NAME(CANCEL_STOP_DEVICE);
-    _PNP_MINOR_FUNCTION_NAME(QUERY_DEVICE_RELATIONS);
-    _PNP_MINOR_FUNCTION_NAME(QUERY_INTERFACE);
-    _PNP_MINOR_FUNCTION_NAME(QUERY_CAPABILITIES);
-    _PNP_MINOR_FUNCTION_NAME(QUERY_RESOURCES);
-    _PNP_MINOR_FUNCTION_NAME(QUERY_RESOURCE_REQUIREMENTS);
-    _PNP_MINOR_FUNCTION_NAME(QUERY_DEVICE_TEXT);
-    _PNP_MINOR_FUNCTION_NAME(FILTER_RESOURCE_REQUIREMENTS);
-    _PNP_MINOR_FUNCTION_NAME(READ_CONFIG);
-    _PNP_MINOR_FUNCTION_NAME(WRITE_CONFIG);
-    _PNP_MINOR_FUNCTION_NAME(EJECT);
-    _PNP_MINOR_FUNCTION_NAME(SET_LOCK);
-    _PNP_MINOR_FUNCTION_NAME(QUERY_ID);
-    _PNP_MINOR_FUNCTION_NAME(QUERY_PNP_DEVICE_STATE);
-    _PNP_MINOR_FUNCTION_NAME(QUERY_BUS_INFORMATION);
-    _PNP_MINOR_FUNCTION_NAME(DEVICE_USAGE_NOTIFICATION);
-    _PNP_MINOR_FUNCTION_NAME(SURPRISE_REMOVAL);
-    _PNP_MINOR_FUNCTION_NAME(QUERY_LEGACY_BUS_INFORMATION);
-    default:
-        break;
-    }
-
-    return "UNKNOWN";
-
-#undef  _PNP_MINOR_FUNCTION_NAME
-}
-
-static FORCEINLINE const CHAR *
-PartialResourceDescriptorTypeName(
-    IN  UCHAR   Type
-    )
-{
-#define _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(_Type)   \
-    case CmResourceType ## _Type:                       \
-        return #_Type;
-
-    switch (Type) {
-    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Null);
-    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Port);
-    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Interrupt);
-    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Memory);
-    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Dma);
-    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(DeviceSpecific);
-    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(BusNumber);
-    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(MemoryLarge);
-    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(ConfigData);
-    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(DevicePrivate);
-    default:
-        break;
-    }
-
-    return "UNKNOWN";
-
-#undef  _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME
-}
-
-static FORCEINLINE const CHAR *
-DeviceUsageTypeName(
-    IN  DEVICE_USAGE_NOTIFICATION_TYPE  Type
-    )
-{
-#define _DEVICE_USAGE_TYPE_NAME(_Type)  \
-    case DeviceUsageType ## _Type:      \
-        return #_Type;
-
-    switch (Type) {
-    _DEVICE_USAGE_TYPE_NAME(Paging);
-    _DEVICE_USAGE_TYPE_NAME(Hibernation);
-    _DEVICE_USAGE_TYPE_NAME(DumpFile);
-    default:
-        break;
-    }
-
-    return "UNKNOWN";
-
-#undef  _DEVICE_USAGE_TYPE_NAME
-}
-
-static FORCEINLINE const CHAR *
-InterfaceTypeName(
-    IN  INTERFACE_TYPE  Type
-    )
-{
-#define _INTERFACE_TYPE_NAME(_Type) \
-    case _Type:                     \
-        return #_Type;
-
-    switch (Type) {
-    _INTERFACE_TYPE_NAME(InterfaceTypeUndefined);
-    _INTERFACE_TYPE_NAME(Internal);
-    _INTERFACE_TYPE_NAME(Isa);
-    _INTERFACE_TYPE_NAME(Eisa);
-    _INTERFACE_TYPE_NAME(MicroChannel);
-    _INTERFACE_TYPE_NAME(TurboChannel);
-    _INTERFACE_TYPE_NAME(PCIBus);
-    _INTERFACE_TYPE_NAME(VMEBus);
-    _INTERFACE_TYPE_NAME(NuBus);
-    _INTERFACE_TYPE_NAME(PCMCIABus);
-    _INTERFACE_TYPE_NAME(CBus);
-    _INTERFACE_TYPE_NAME(MPIBus);
-    _INTERFACE_TYPE_NAME(MPSABus);
-    _INTERFACE_TYPE_NAME(ProcessorInternal);
-    _INTERFACE_TYPE_NAME(InternalPowerBus);
-    _INTERFACE_TYPE_NAME(PNPISABus);
-    _INTERFACE_TYPE_NAME(PNPBus);
-    _INTERFACE_TYPE_NAME(Vmcs);
-    _INTERFACE_TYPE_NAME(ACPIBus);
-    default:
-        break;
-    }
-
-    return "UNKNOWN";
-
-#undef  _INTERFACE_TYPE_NAME
-}
-
-static FORCEINLINE const CHAR *
-DmaWidthName(
-    IN  DMA_WIDTH   Width
-    )
-{
-#define _DMA_WIDTH_NAME(_Width) \
-    case Width ## _Width:       \
-        return #_Width;
-
-    switch (Width) {
-    _DMA_WIDTH_NAME(8Bits);
-    _DMA_WIDTH_NAME(16Bits);
-    _DMA_WIDTH_NAME(32Bits);
-    _DMA_WIDTH_NAME(64Bits);
-    _DMA_WIDTH_NAME(NoWrap);
-    default:
-        break;
-    }
-
-    return "UNKNOWN";
-
-#undef  _DMA_WIDTH_NAME
-}
-
-static FORCEINLINE const CHAR *
-DmaSpeedName(
-    IN  DMA_SPEED   Speed
-    )
-{
-#define _DMA_SPEED_NAME(_Speed) \
-    case _Speed:                \
-        return #_Speed;
-
-    switch (Speed) {
-    _DMA_SPEED_NAME(Compatible);
-    _DMA_SPEED_NAME(TypeA);
-    _DMA_SPEED_NAME(TypeB);
-    _DMA_SPEED_NAME(TypeC);
-    _DMA_SPEED_NAME(TypeF);
-    _DMA_SPEED_NAME(MaximumDmaSpeed);
-    default:
-        break;
-    }
-
-    return "UNKNOWN";
-
-#undef  _DMA_SPEED_NAME
-}
-
-#endif // _XENBUS_NAMES_H_
index e29b363f52e50d232d846b144a0c59afdb396536..c371f61f1a15ae6e8b6853d260207b7b28a52e95 100644 (file)
@@ -36,7 +36,6 @@
 #include <ntstrsafe.h>
 #include <util.h>
 
-#include <binding.h>
 #include <shared_info_interface.h>
 #include <evtchn_interface.h>
 #include <debug_interface.h>
 #include "bus.h"
 #include "driver.h"
 #include "thread.h"
-#include "log.h"
+#include "dbg_print.h"
 #include "assert.h"
 
 #define PDO_TAG 'ODP'
 
+#define MAXNAMELEN  128
+
 struct _XENBUS_PDO {
     PXENBUS_DX                  Dx;
 
@@ -62,10 +63,11 @@ struct _XENBUS_PDO {
     PXENBUS_THREAD              DevicePowerThread;
     PIRP                        DevicePowerIrp;
 
+    CHAR                        Class[MAXNAMELEN];
+
     PXENBUS_FDO                 Fdo;
     BOOLEAN                     Missing;
     const CHAR                  *Reason;
-    UCHAR                       Revision;
 
     BUS_INTERFACE_STANDARD      BusInterface;
 
@@ -222,75 +224,93 @@ PdoIsMissing(
 }
 
 static FORCEINLINE VOID
-__PdoSetName(
+__PdoSetClass(
     IN  PXENBUS_PDO     Pdo,
-    IN  PANSI_STRING    Ansi
+    IN  PANSI_STRING    Class
     )
 {
-    PXENBUS_DX          Dx = Pdo->Dx;
     NTSTATUS            status;
 
-    status = RtlStringCbPrintfA(Dx->Name, MAX_DEVICE_ID_LEN, "%Z", Ansi);
+    status = RtlStringCbPrintfA(Pdo->Class,
+                                MAXNAMELEN,
+                                "%Z",
+                                Class);
     ASSERT(NT_SUCCESS(status));
 }
 
 static FORCEINLINE PCHAR
-__PdoGetName(
+__PdoGetClass(
     IN  PXENBUS_PDO Pdo
     )
 {
-    PXENBUS_DX      Dx = Pdo->Dx;
-
-    return Dx->Name;
-}
-
-PCHAR
-PdoGetName(
-    IN  PXENBUS_PDO Pdo
-    )
-{
-    return __PdoGetName(Pdo);
+    return Pdo->Class;
 }
 
 struct _REVISION_ENTRY {
     const CHAR  *Name;
-    UCHAR       Revision;
+    ULONG       Revision;
 };
 
 static struct _REVISION_ENTRY PdoRevisionTable[] = {
-    { "VIF", 0x02 },
-    { "VBD", 0x02 },
-    { "IFACE", 0x02 },
+    { "VIF", 1 },
+    { "VBD", 1 },
+    { "IFACE", 1 },
     { NULL, 0 }
 };
 
-static FORCEINLINE VOID
-__PdoSetRevision(
-    IN  PXENBUS_PDO         Pdo,
-    IN  PANSI_STRING        Name
+static FORCEINLINE ULONG
+__PdoGetRevision(
+    IN  PXENBUS_PDO         Pdo
     )
 {
     struct _REVISION_ENTRY  *Entry;
-
-    Pdo->Revision = PCI_REVISION;
-
+    ULONG                   Revision;
+    
+    Revision = 0;
     for (Entry = PdoRevisionTable; Entry->Name != NULL; Entry++) {
-        if (strcmp(Name->Buffer, Entry->Name) == 0) {
-            Trace("%s: %02x\n",
-                  __PdoGetName(Pdo),
-                  Entry->Revision);
-            Pdo->Revision = Entry->Revision;
+        if (strcmp(__PdoGetClass(Pdo), Entry->Name) == 0) {
+            Revision = Entry->Revision;
             break;
         }
     }
+
+    return Revision;
 }
 
-static FORCEINLINE UCHAR
-__PdoGetRevision(
+static FORCEINLINE VOID
+__PdoSetName(
+    IN  PXENBUS_PDO     Pdo,
+    IN  PCHAR           VendorName
+    )
+{
+    PXENBUS_DX          Dx = Pdo->Dx;
+    NTSTATUS            status;
+
+    status = RtlStringCbPrintfA(Dx->Name,
+                                MAX_DEVICE_ID_LEN,
+                                "VEN_%s&DEV_%s&REV_%08X",
+                                VendorName,
+                                __PdoGetClass(Pdo),
+                                __PdoGetRevision(Pdo));
+    ASSERT(NT_SUCCESS(status));
+}
+
+static FORCEINLINE PCHAR
+__PdoGetName(
     IN  PXENBUS_PDO Pdo
     )
 {
-    return Pdo->Revision;
+    PXENBUS_DX      Dx = Pdo->Dx;
+
+    return Dx->Name;
+}
+
+PCHAR
+PdoGetName(
+    IN  PXENBUS_PDO Pdo
+    )
+{
+    return __PdoGetName(Pdo);
 }
 
 static FORCEINLINE PDEVICE_OBJECT
@@ -1494,7 +1514,7 @@ PdoQueryDeviceText(
                                     MAXTEXTLEN,
                                     L"%hs %hs",
                                     FdoGetName(__PdoGetFdo(Pdo)),
-                                    __PdoGetName(Pdo));
+                                    __PdoGetClass(Pdo));
         ASSERT(NT_SUCCESS(status));
 
         Buffer += wcslen(Buffer);
@@ -1505,7 +1525,7 @@ PdoQueryDeviceText(
         status = RtlStringCbPrintfW(Buffer,
                                     MAXTEXTLEN,
                                     L"%hs",
-                                    __PdoGetName(Pdo));
+                                    __PdoGetClass(Pdo));
         ASSERT(NT_SUCCESS(status));
 
         Buffer += wcslen(Buffer);
@@ -1622,9 +1642,8 @@ PdoQueryId(
 
         status = RtlStringCbPrintfW(Buffer,
                                     MAX_DEVICE_ID_LEN,
-                                    L"XENBUS\\CLASS_%hs&REV_%02X",
-                                    __PdoGetName(Pdo),
-                                    __PdoGetRevision(Pdo));
+                                    L"XENBUS\\%hs",
+                                    __PdoGetName(Pdo));
         ASSERT(NT_SUCCESS(status));
 
         Buffer += wcslen(Buffer);
@@ -1640,9 +1659,8 @@ PdoQueryId(
         Length = MAX_DEVICE_ID_LEN;
         status = RtlStringCbPrintfW(Buffer,
                                     Length,
-                                    L"XENBUS\\CLASS_%hs&REV_%02X",
-                                    __PdoGetName(Pdo),
-                                    __PdoGetRevision(Pdo));
+                                    L"XENBUS\\%hs",
+                                    __PdoGetName(Pdo));
         ASSERT(NT_SUCCESS(status));
 
         Buffer += wcslen(Buffer);
@@ -2240,7 +2258,7 @@ PdoSuspend(
 NTSTATUS
 PdoCreate(
     IN  PXENBUS_FDO     Fdo,
-    IN  PANSI_STRING    Name
+    IN  PANSI_STRING    Class
     )
 {
     PDEVICE_OBJECT      PhysicalDeviceObject;
@@ -2249,7 +2267,7 @@ PdoCreate(
     NTSTATUS            status;
 
 #pragma prefast(suppress:28197) // Possibly leaking memory 'PhysicalDeviceObject'
-    status = IoCreateDevice(DriverObject,
+    status = IoCreateDevice(DriverGetDriverObject(),
                             sizeof(XENBUS_DX),
                             NULL,
                             FILE_DEVICE_UNKNOWN,
@@ -2289,13 +2307,12 @@ PdoCreate(
     if (!NT_SUCCESS(status))
         goto fail5;
 
-    __PdoSetName(Pdo, Name);
-    __PdoSetRevision(Pdo, Name);
+    __PdoSetClass(Pdo, Class);
+    __PdoSetName(Pdo, FdoGetVendorName(Fdo));
 
-    Info("%p (XENBUS\\CLASS_%s&REV_%02X#_)\n",
+    Info("%p (%s)\n",
          PhysicalDeviceObject,
-         __PdoGetName(Pdo),
-         __PdoGetRevision(Pdo));
+         __PdoGetName(Pdo));
 
     Dx->Pdo = Pdo;
     PhysicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
@@ -2350,16 +2367,15 @@ PdoDestroy(
 
     __PdoUnlink(Pdo);
 
-    Info("%p (XENBUS\\CLASS_%s&REV_%02X) (%s)\n",
+    Info("%p (%s) (%s)\n",
          PhysicalDeviceObject,
          __PdoGetName(Pdo),
-         __PdoGetRevision(Pdo),
          Pdo->Reason);
     Pdo->Reason = NULL;
 
     Dx->Pdo = NULL;
 
-    Pdo->Revision = 0;
+    RtlZeroMemory(Pdo->Class, MAXNAMELEN);
 
     ThreadAlert(Pdo->DevicePowerThread);
     ThreadJoin(Pdo->DevicePowerThread);
index a362b3b3da36a31974b7601423beb9ceecc2890f..7e55b2d5789c6a794e474f7d0a1ee613548d803e 100644 (file)
@@ -34,7 +34,7 @@
 #include <util.h>
 
 #include "range_set.h"
-#include "log.h"
+#include "dbg_print.h"
 #include "assert.h"
 
 #define RANGE_SET_AUDIT DBG
diff --git a/src/xenbus/registry.c b/src/xenbus/registry.c
deleted file mode 100644 (file)
index 66d1f2e..0000000
+++ /dev/null
@@ -1,1068 +0,0 @@
-/* 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 "log.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
-RegistryOpenServiceKey(
-    IN  ACCESS_MASK     DesiredAccess,
-    OUT PHANDLE         Key
-    )
-{
-    OBJECT_ATTRIBUTES   Attributes;
-    NTSTATUS            status;
-
-    InitializeObjectAttributes(&Attributes,
-                               &RegistryPath,
-                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
-                               NULL,
-                               NULL);
-
-    status = ZwOpenKey(Key,
-                       DesiredAccess,
-                       &Attributes);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    return STATUS_SUCCESS;
-
-fail1:
-    return status;
-}
-
-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
-    )
-{
-    NTSTATUS            status;
-
-    status = IoOpenDeviceRegistryKey(DeviceObject,
-                                     PLUGPLAY_REGKEY_DEVICE,
-                                     DesiredAccess,
-                                     Key);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    return STATUS_SUCCESS;
-
-fail1:
-    return status;
-}
-
-NTSTATUS
-RegistryOpenSubKey(
-    IN  PHANDLE         Key,
-    IN  PCHAR           Name,
-    IN  ACCESS_MASK     DesiredAccess,
-    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 = ZwOpenKey(SubKey,
-                       DesiredAccess,
-                       &Attributes);
-    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
-    )
-{
-    ANSI_STRING         Ansi;
-    UNICODE_STRING      Unicode;
-    OBJECT_ATTRIBUTES   Attributes;
-    HANDLE              SubKey;
-    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,
-                         REG_OPTION_VOLATILE,
-                         NULL
-                         );
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    ZwClose(SubKey);
-
-    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;
-    OBJECT_ATTRIBUTES   Attributes;
-    HANDLE              SubKey;
-    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 = ZwOpenKey(&SubKey,
-                       KEY_ALL_ACCESS,
-                       &Attributes);
-    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 = 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
-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
-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
-RegistryQuerySystemStartOptions(
-    OUT PANSI_STRING                *Options
-    )
-{
-    UNICODE_STRING                  Unicode;
-    OBJECT_ATTRIBUTES               Attributes;
-    HANDLE                          Key;
-    PKEY_VALUE_PARTIAL_INFORMATION  Value;
-    ULONG                           Size;
-    NTSTATUS                        status;
-
-    RtlInitUnicodeString(&Unicode, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control");
-    
-    InitializeObjectAttributes(&Attributes,
-                               &Unicode,
-                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
-                               NULL,
-                               NULL);
-
-    status = ZwOpenKey(&Key,
-                       KEY_READ,
-                       &Attributes);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    RtlInitUnicodeString(&Unicode, L"SystemStartOptions");
-
-    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;
-
-    status = STATUS_INVALID_PARAMETER;
-    if (Value->Type != REG_SZ)
-        goto fail5;
-
-    *Options = RegistrySzToAnsi((PWCHAR)Value->Data);
-
-    status = STATUS_NO_MEMORY;
-    if (*Options == NULL)
-        goto fail6;
-
-    __RegistryFree(Value);
-
-    ZwClose(Key);
-
-    return STATUS_SUCCESS;
-
-fail6:
-fail5:
-fail4:
-    __RegistryFree(Value);
-
-fail3:
-fail2:
-    ZwClose(Key);
-
-fail1:
-    return status;
-}
-
-
-static PKEY_VALUE_PARTIAL_INFORMATION
-RegistryAnsiToSz(
-    PANSI_STRING                    Ansi
-    )
-{
-    ULONG                           Length;
-    PKEY_VALUE_PARTIAL_INFORMATION  Partial;
-    UNICODE_STRING                  Unicode;
-    NTSTATUS                        status;
-
-    Length = Ansi->Length + 1;
-    Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) +
-                                 Length * sizeof (WCHAR));
-
-    status = STATUS_NO_MEMORY;
-    if (Partial == NULL)
-        goto fail1;
-
-    Partial->TitleIndex = 0;
-    Partial->Type = REG_SZ;
-    Partial->DataLength = Length * sizeof (WCHAR);
-
-    Unicode.MaximumLength = (UCHAR)Partial->DataLength;
-    Unicode.Buffer = (PWCHAR)Partial->Data;
-    Unicode.Length = 0;
-
-    status = RtlAnsiStringToUnicodeString(&Unicode, Ansi, FALSE);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    return Partial;
-
-fail2:
-    __RegistryFree(Partial);
-
-fail1:
-    return NULL;
-}
-
-static PKEY_VALUE_PARTIAL_INFORMATION
-RegistryAnsiToMultiSz(
-    PANSI_STRING                    Ansi
-    )
-{
-    ULONG                           Length;
-    ULONG                           Index;
-    PKEY_VALUE_PARTIAL_INFORMATION  Partial;
-    UNICODE_STRING                  Unicode;
-    NTSTATUS                        status;
-
-    Length = 1;
-    for (Index = 0; Ansi[Index].Buffer != NULL; Index++)
-        Length += Ansi[Index].Length + 1;
-
-    Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) +
-                               Length * sizeof (WCHAR));
-
-    status = STATUS_NO_MEMORY;
-    if (Partial == NULL)
-        goto fail1;
-
-    Partial->TitleIndex = 0;
-    Partial->Type = REG_MULTI_SZ;
-    Partial->DataLength = Length * sizeof (WCHAR);
-
-    Unicode.MaximumLength = (USHORT)Partial->DataLength;
-    Unicode.Buffer = (PWCHAR)Partial->Data;
-    Unicode.Length = 0;
-
-    for (Index = 0; Ansi[Index].Buffer != NULL; Index++) {
-        status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi[Index], FALSE);
-        if (!NT_SUCCESS(status))
-            goto fail2;
-
-        Length = Unicode.Length / sizeof (WCHAR);
-
-        ASSERT3U(Unicode.MaximumLength, >=, (Length + 1) * sizeof (WCHAR));
-        Unicode.MaximumLength -= (USHORT)((Length + 1) * sizeof (WCHAR));
-        Unicode.Buffer += Length + 1;
-        Unicode.Length = 0;
-    }
-    *Unicode.Buffer = L'\0';
-
-    return Partial;
-
-fail2:
-    __RegistryFree(Partial);
-
-fail1:
-    return NULL;
-}
-
-NTSTATUS
-RegistryUpdateSzValue(
-    IN  HANDLE                      Key,
-    IN  PCHAR                       Name,
-    IN  ULONG                       Type,
-    ...
-    )
-{
-    ANSI_STRING                     Ansi;
-    UNICODE_STRING                  Unicode;
-    va_list                         Arguments;
-    PKEY_VALUE_PARTIAL_INFORMATION  Partial;
-    NTSTATUS                        status;
-
-    RtlInitAnsiString(&Ansi, Name);
-
-    status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-        
-    va_start(Arguments, Type);
-    switch (Type) {
-    case REG_SZ: {
-        PANSI_STRING    Argument;
-
-        Argument = va_arg(Arguments, PANSI_STRING);
-
-        status = STATUS_NO_MEMORY;
-        Partial = RegistryAnsiToSz(Argument);        
-        break;
-    }
-    case REG_MULTI_SZ: {
-        PANSI_STRING    Argument;
-
-        Argument = va_arg(Arguments, PANSI_STRING);
-
-        status = STATUS_NO_MEMORY;
-        Partial = RegistryAnsiToMultiSz(Argument);        
-        break;
-    }
-    default:
-        status = STATUS_INVALID_PARAMETER;
-        Partial = NULL;
-        break;
-    }
-    va_end(Arguments);
-
-    if (Partial == NULL)
-        goto fail2;
-
-    status = ZwSetValueKey(Key,
-                           &Unicode,
-                           Partial->TitleIndex,
-                           Partial->Type,
-                           Partial->Data,
-                           Partial->DataLength);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    __RegistryFree(Partial);
-
-    RtlFreeUnicodeString(&Unicode);
-
-    return STATUS_SUCCESS;
-
-fail3:
-    __RegistryFree(Partial);
-
-fail2:
-    RtlFreeUnicodeString(&Unicode);
-
-fail1:
-    return status;
-}
-
-VOID
-RegistryFreeSzValue(
-    IN  PANSI_STRING    Array
-    )
-{
-    ULONG               Index;
-
-    if (Array == NULL)
-        return;
-
-    for (Index = 0; Array[Index].Buffer != NULL; Index++)
-        __RegistryFree(Array[Index].Buffer);
-
-    __RegistryFree(Array);
-}
-
-VOID
-RegistryCloseKey(
-    IN  HANDLE  Key
-    )
-{
-    ZwClose(Key);
-}
diff --git a/src/xenbus/registry.h b/src/xenbus/registry.h
deleted file mode 100644 (file)
index 92ad17b..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/* 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 _XENBUS_REGISTRY_H
-#define _XENBUS_REGISTRY_H
-
-#include <ntddk.h>
-
-extern NTSTATUS
-RegistryInitialize(
-    IN PUNICODE_STRING  Path
-    );
-
-extern VOID
-RegistryTeardown(
-    VOID
-    );
-
-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
-    );
-
-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
-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
-RegistryQuerySystemStartOptions(
-    OUT PANSI_STRING    *Options
-    );
-
-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  // _XENBUS_REGISTRY_H
index 956b7a453f9dafa7942b859103062f6bf6e18d92..ae5bd6a8192313755d74a9169e44aef14c2e08fc 100644 (file)
@@ -35,7 +35,7 @@
 
 #include "shared_info.h"
 #include "fdo.h"
-#include "log.h"
+#include "dbg_print.h"
 #include "assert.h"
 
 struct _XENBUS_SHARED_INFO_CONTEXT {
index 2e8953edcd270daaf58225dede7b9b92f4882151..436b50533a0525dafc727bbc38118cae1c3a8ad5 100644 (file)
@@ -38,9 +38,8 @@
 
 #include "store.h"
 #include "evtchn.h"
-#include "debug.h"
 #include "fdo.h"
-#include "log.h"
+#include "dbg_print.h"
 #include "assert.h"
 
 #define STORE_TRANSACTION_MAGIC 'NART'
index 89aa308c8052988df42a813514d47075aa30160d..b09f79bc12be67115a2fe6b6500b277e6462f739 100644 (file)
@@ -37,8 +37,8 @@
 #include "suspend.h"
 #include "thread.h"
 #include "fdo.h"
-#include "log.h"
 #include "sync.h"
+#include "dbg_print.h"
 #include "assert.h"
 
 struct _XENBUS_SUSPEND_CALLBACK {
@@ -188,14 +188,18 @@ SuspendTrigger(
 
     KeAcquireSpinLock(&Context->Lock, &Irql);
 
-    LogQemuPrintf("SUSPEND: ====>\n");
+    LogPrintf(LOG_LEVEL_INFO,
+              "SUSPEND: ====>\n");
 
     SyncCapture();
     SyncDisableInterrupts();
 
-    LogQemuPrintf("SUSPEND: SCHEDOP_shutdown:SHUTDOWN_suspend ====>\n");
+    LogPrintf(LOG_LEVEL_INFO,
+              "SUSPEND: SCHEDOP_shutdown:SHUTDOWN_suspend ====>\n");
     status = SchedShutdown(SHUTDOWN_suspend);
-    LogQemuPrintf("SUSPEND: SCHEDOP_shutdown:SHUTDOWN_suspend <==== (%08x)\n", status);
+    LogPrintf(LOG_LEVEL_INFO,
+              "SUSPEND: SCHEDOP_shutdown:SHUTDOWN_suspend <==== (%08x)\n",
+              status);
 
     if (NT_SUCCESS(status)) {
         PLIST_ENTRY ListEntry;
@@ -217,9 +221,6 @@ SuspendTrigger(
     if (NT_SUCCESS(status)) {
         PLIST_ENTRY ListEntry;
 
-        // Make sure that emulated devices don't magically re-appear
-        UnplugReplay();
-
         for (ListEntry = Context->LateList.Flink;
              ListEntry != &Context->LateList;
              ListEntry = ListEntry->Flink) {
@@ -232,7 +233,7 @@ SuspendTrigger(
 
     SyncRelease();
 
-    LogQemuPrintf("SUSPEND: <====\n");
+    LogPrintf(LOG_LEVEL_INFO, "SUSPEND: <====\n");
 
     KeReleaseSpinLock(&Context->Lock, Irql);
 }
index ac0dba64754356703253a2fb4c50363924acdd89..41ecbf98d144e4f5d97a42b37659807d4f2ddf53 100644 (file)
@@ -35,7 +35,7 @@
 #include <util.h>
 
 #include "sync.h"
-#include "log.h"
+#include "dbg_print.h"
 #include "assert.h"
 
 // Routines to capture all CPUs in a spinning state with interrupts
@@ -321,7 +321,10 @@ again:
             } while (InterlockedCompareExchange(&SyncContext.CompletionCount, New, Old) != Old);
 
             if (Old < CpuCount) {
-                LogQemuPrintf("SYNC: %d < %d\n", Old, CpuCount);
+                LogPrintf(LOG_LEVEL_WARNING,
+                          "SYNC: %d < %d\n",
+                          Old,
+                          CpuCount);
 
 #pragma prefast(suppress:28138) // Use constant rather than variable
                 KeLowerIrql(DISPATCH_LEVEL);
index 7c6de9cb6f369cb7446b4c016c09355a9bbecb77..2ccc1aa6edf880b8ab872953a7d6bcc78449ab9b 100644 (file)
@@ -33,7 +33,7 @@
 #include <util.h>
 
 #include "thread.h"
-#include "log.h"
+#include "dbg_print.h"
 #include "assert.h"
 
 #define THREAD_POOL 'ERHT'
diff --git a/src/xenfilt/assert.h b/src/xenfilt/assert.h
deleted file mode 100644 (file)
index b69bd74..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/* 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 _XENFILT_ASSERT_H
-#define _XENFILT_ASSERT_H
-
-#include <ntddk.h>
-
-#include "log.h"
-
-static FORCEINLINE VOID
-__BugCheck(
-    IN  ULONG       Code,
-    IN  ULONG_PTR   Parameter1,
-    IN  ULONG_PTR   Parameter2,
-    IN  ULONG_PTR   Parameter3,
-    IN  ULONG_PTR   Parameter4
-    )
-{
-#pragma prefast(suppress:28159)
-    KeBugCheckEx(Code,
-                 Parameter1,
-                 Parameter2,
-                 Parameter3,
-                 Parameter4);
-}
-
-#define ASSERTION_FAILURE   0x0000DEAD
-
-#define BUG(_TEXT)                                              \
-        do {                                                    \
-            const CHAR  *_Text = (_TEXT);                       \
-            const CHAR  *_File = __FILE__;                      \
-            ULONG       _Line = __LINE__;                       \
-                                                                \
-            Error("BUG: " _TEXT "\n");                          \
-            __BugCheck(ASSERTION_FAILURE,                       \
-                       (ULONG_PTR)_Text,                        \
-                       (ULONG_PTR)_File,                        \
-                       (ULONG_PTR)_Line,                        \
-                       0);                                      \
-        } while (FALSE)
-
-#define BUG_ON(_EXP)                \
-        if (_EXP) BUG(#_EXP)
-
-#if DBG
-
-#define __NT_ASSERT(_EXP)                                       \
-        ((!(_EXP)) ?                                            \
-        (Error("ASSERTION FAILED: " #_EXP "\n"),                \
-         __annotation(L"Debug", L"AssertFail", L#_EXP),         \
-         DbgRaiseAssertionFailure(), FALSE) :                   \
-        TRUE)
-
-#define __ASSERT(_EXP)  __NT_ASSERT(_EXP)
-
-#else   // DBG
-
-#define __ASSERT(_EXP)  BUG_ON(!(_EXP))
-
-#endif  // DBG
-
-#undef  ASSERT
-
-#define ASSERT(_EXP)                    \
-        do {                            \
-            __ASSERT(_EXP);             \
-            __analysis_assume(_EXP);    \
-        } while (FALSE)
-
-#define ASSERT3U(_X, _OP, _Y)                       \
-        do {                                        \
-            ULONGLONG   _Lval = (ULONGLONG)(_X);    \
-            ULONGLONG   _Rval = (ULONGLONG)(_Y);    \
-            if (!(_Lval _OP _Rval)) {               \
-                Error("%s = %llu\n", #_X, _Lval);   \
-                Error("%s = %llu\n", #_Y, _Rval);   \
-                ASSERT(_X _OP _Y);                  \
-            }                                       \
-        } while (FALSE)
-
-#define ASSERT3S(_X, _OP, _Y)                       \
-        do {                                        \
-            LONGLONG    _Lval = (LONGLONG)(_X);     \
-            LONGLONG    _Rval = (LONGLONG)(_Y);     \
-            if (!(_Lval _OP _Rval)) {               \
-                Error("%s = %lld\n", #_X, _Lval);   \
-                Error("%s = %lld\n", #_Y, _Rval);   \
-                ASSERT(_X _OP _Y);                  \
-            }                                       \
-        } while (FALSE)
-
-#define ASSERT3P(_X, _OP, _Y)                       \
-        do {                                        \
-            PVOID   _Lval = (PVOID)(_X);            \
-            PVOID   _Rval = (PVOID)(_Y);            \
-            if (!(_Lval _OP _Rval)) {               \
-                Error("%s = %p\n", #_X, _Lval);     \
-                Error("%s = %p\n", #_Y, _Rval);     \
-                ASSERT(_X _OP _Y);                  \
-            }                                       \
-        } while (FALSE)
-
-#ifndef TEST_MEMORY
-#define TEST_MEMORY DBG
-#endif
-
-#if TEST_MEMORY
-
-static __inline BOOLEAN
-_IsZeroMemory(
-    IN  const PCHAR Caller,
-    IN  const PCHAR Name,
-    IN  PVOID       Buffer,
-    IN  ULONG       Length
-    )
-{
-    ULONG           Offset;
-
-    Offset = 0;
-    while (Offset < Length) {
-        if (*((PUCHAR)Buffer + Offset) != 0) {
-            Error("%s: non-zero byte in %s (0x%p+0x%x)\n", Caller, Name, Buffer, Offset);
-            return FALSE;
-        }
-        Offset++;
-    }
-
-    return TRUE;
-}
-
-#define IsZeroMemory(_Buffer, _Length) \
-        _IsZeroMemory(__FUNCTION__, #_Buffer, (_Buffer), (_Length))
-
-#else   // TEST_MEMORY
-
-#define IsZeroMemory(_Buffer, _Length)  TRUE
-
-#endif  // TEST_MEMORY
-
-#define IMPLY(_X, _Y)   (!(_X) || (_Y))
-#define EQUIV(_X, _Y)   (IMPLY((_X), (_Y)) && IMPLY((_Y), (_X)))
-
-#endif  // _XENFILT_ASSERT_H
-
index fdc1f64338b977a030ebe0756c7b17a33a8a43a5..540fa7c22708ee230d6095402b4b0eacb6d87fb2 100644 (file)
  */
 
 #include <ntddk.h>
+#include <xen.h>
 #include <util.h>
 
 #include "fdo.h"
 #include "pdo.h"
-#include "emulated.h"
 #include "registry.h"
 #include "driver.h"
-#include "log.h"
+#include "dbg_print.h"
 #include "assert.h"
 #include "version.h"
 
-extern const CHAR                   *XenVersion;
+extern PULONG       InitSafeBootMode;
 
-extern PULONG                       InitSafeBootMode;
+typedef struct _XENFILT_DRIVER {
+    PDRIVER_OBJECT      DriverObject;
+    HANDLE              ParametersKey;
+} XENFILT_DRIVER, *PXENFILT_DRIVER;
 
-PDRIVER_OBJECT                      DriverObject;
+static XENFILT_DRIVER   Driver;
 
-static HANDLE                       DriverServiceKey;
+static FORCEINLINE VOID
+__DriverSetDriverObject(
+    IN  PDRIVER_OBJECT  DriverObject
+    )
+{
+    Driver.DriverObject = DriverObject;
+}
 
-static PANSI_STRING                 DriverFilterDevices;
+static FORCEINLINE PDRIVER_OBJECT
+__DriverGetDriverObject(
+    VOID
+    )
+{
+    return Driver.DriverObject;
+}
 
-static XENFILT_EMULATED_INTERFACE   DriverEmulatedInterface;
+PDRIVER_OBJECT
+DriverGetDriverObject(
+    VOID
+    )
+{
+    return __DriverGetDriverObject();
+}
 
-DRIVER_UNLOAD                       DriverUnload;
+static FORCEINLINE VOID
+__DriverSetParametersKey(
+    IN  HANDLE  Key
+    )
+{
+    Driver.ParametersKey = Key;
+}
 
-PXENFILT_EMULATED_INTERFACE
-DriverGetEmulatedInterface(
+static FORCEINLINE HANDLE
+__DriverGetParametersKey(
     VOID
     )
 {
-    return &DriverEmulatedInterface;
+    return Driver.ParametersKey;
 }
 
+HANDLE
+DriverGetParametersKey(
+    VOID
+    )
+{
+    return __DriverGetParametersKey();
+}
+
+DRIVER_UNLOAD                       DriverUnload;
+
 VOID
 DriverUnload(
-    IN  PDRIVER_OBJECT  _DriverObject
+    IN  PDRIVER_OBJECT  DriverObject
     )
 {
-    ASSERT3P(_DriverObject, ==, DriverObject);
+    HANDLE              ParametersKey;
 
-    Trace("====>\n");
+    ASSERT3P(DriverObject, ==, __DriverGetDriverObject());
 
-    Info("%s (%s)\n",
-         MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR,
-         DAY_STR "/" MONTH_STR "/" YEAR_STR);
+    Trace("====>\n");
 
     if (*InitSafeBootMode > 0)
         goto done;
 
-    EmulatedTeardown(&DriverEmulatedInterface);
-
-    RegistryDeleteSubKey(DriverServiceKey, "Status");
-
-    RegistryFreeSzValue(DriverFilterDevices);
-
-    RegistryCloseKey(DriverServiceKey);
+    ParametersKey = __DriverGetParametersKey();
+    if (ParametersKey != NULL) {
+        RegistryCloseKey(ParametersKey);
+        __DriverSetParametersKey(NULL);
+    }
 
     RegistryTeardown();
 
 done:
-    DriverObject = NULL;
+    __DriverSetDriverObject(NULL);
+
+    ASSERT(IsZeroMemory(&Driver, sizeof (XENFILT_DRIVER)));
 
     Trace("<====\n");
 }
@@ -98,7 +133,7 @@ done:
 __drv_functionClass(IO_COMPLETION_ROUTINE)
 __drv_sameIRQL
 static NTSTATUS
-DriverQueryCompletion(
+DriverQueryIdCompletion(
     IN  PDEVICE_OBJECT  DeviceObject,
     IN  PIRP            Irp,
     IN  PVOID           Context
@@ -149,7 +184,7 @@ __DriverQueryId(
     KeInitializeEvent(&Event, NotificationEvent, FALSE);
 
     IoSetCompletionRoutine(Irp,
-                           DriverQueryCompletion,
+                           DriverQueryIdCompletion,
                            &Event,
                            TRUE,
                            TRUE,
@@ -198,17 +233,34 @@ DRIVER_ADD_DEVICE   AddDevice;
 NTSTATUS
 #pragma prefast(suppress:28152) // Does not clear DO_DEVICE_INITIALIZING
 AddDevice(
-    IN  PDRIVER_OBJECT  _DriverObject,
+    IN  PDRIVER_OBJECT  DriverObject,
     IN  PDEVICE_OBJECT  PhysicalDeviceObject
     )
 {
+    HANDLE              ParametersKey;
+    PANSI_STRING        FilterDevices;
     PWCHAR              DeviceID;
     UNICODE_STRING      Unicode;
     ANSI_STRING         Ansi;
     ULONG               Index;
     NTSTATUS            status;
 
-    ASSERT3P(_DriverObject, ==, DriverObject);
+    ASSERT3P(DriverObject, ==, __DriverGetDriverObject());
+
+    ParametersKey = __DriverGetParametersKey();
+
+    FilterDevices = NULL;
+    if (ParametersKey != NULL) {
+        status = RegistryQuerySzValue(ParametersKey,
+                                      "FilterDevices",
+                                      &FilterDevices);
+        ASSERT(IMPLY(!NT_SUCCESS(status), FilterDevices == NULL));
+    } else {
+        FilterDevices = NULL;
+    }
+
+    if (FilterDevices == NULL)
+        goto done;
 
     status = __DriverQueryId(PhysicalDeviceObject, BusQueryDeviceID, &DeviceID);
     if (!NT_SUCCESS(status))
@@ -220,33 +272,41 @@ AddDevice(
     if (!NT_SUCCESS(status))
         goto fail2;
 
-    for (Index = 0; 
-         DriverFilterDevices != NULL && DriverFilterDevices[Index].Buffer != NULL;
-         Index++) {
-        PANSI_STRING Device = &DriverFilterDevices[Index];
+    for (Index = 0; FilterDevices[Index].Buffer != NULL; Index++) {
+        PANSI_STRING Device = &FilterDevices[Index];
 
         if (RtlCompareString(&Ansi, Device, TRUE) == 0) {
             status = FdoCreate(PhysicalDeviceObject, &Ansi);
             if (!NT_SUCCESS(status))
                 goto fail3;
 
-            goto done;
+            break;
         }
     }
 
-done:
     RtlFreeAnsiString(&Ansi);
     ExFreePool(DeviceID);
 
+    RegistryFreeSzValue(FilterDevices);
+
+done:
     return STATUS_SUCCESS;
 
 fail3:
+    Error("fail3\n");
+
     RtlFreeAnsiString(&Ansi);
 
 fail2:
+    Error("fail2\n");
+
     ExFreePool(DeviceID);
 
 fail1:
+    RegistryFreeSzValue(FilterDevices);
+
+    Error("fail1 (%08x)\n", status);
+
     return status;
 }
 
@@ -299,53 +359,53 @@ DRIVER_INITIALIZE   DriverEntry;
 
 NTSTATUS
 DriverEntry(
-    IN  PDRIVER_OBJECT  _DriverObject,
+    IN  PDRIVER_OBJECT  DriverObject,
     IN  PUNICODE_STRING RegistryPath
     )
 {
+    HANDLE              ServiceKey;
     HANDLE              ParametersKey;
     ULONG               Index;
     NTSTATUS            status;
 
-    ASSERT3P(DriverObject, ==, NULL);
+    ASSERT3P(__DriverGetDriverObject(), ==, NULL);
 
     ExInitializeDriverRuntime(DrvRtPoolNxOptIn);
 
+    __DbgPrintEnable();
+
     Trace("====>\n");
 
-    Info("%s (%s)\n",
-         MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR,
-         DAY_STR "/" MONTH_STR "/" YEAR_STR);
+    __DriverSetDriverObject(DriverObject);
 
-    DriverObject = _DriverObject;
     DriverObject->DriverUnload = DriverUnload;
 
     if (*InitSafeBootMode > 0)
         goto done;
 
+    LogPrintf(LOG_LEVEL_INFO,
+              "XENFILT %d.%d.%d (%d) (%02d.%02d.%04d)\n",
+              MAJOR_VERSION,
+              MINOR_VERSION,
+              MICRO_VERSION,
+              BUILD_NUMBER,
+              DAY,
+              MONTH,
+              YEAR);
+
     status = RegistryInitialize(RegistryPath);
     if (!NT_SUCCESS(status))
         goto fail1;
 
-    status = RegistryOpenServiceKey(KEY_READ, &DriverServiceKey);
+    status = RegistryOpenServiceKey(KEY_READ, &ServiceKey);
     if (!NT_SUCCESS(status))
         goto fail2;
 
-    status = RegistryOpenSubKey(DriverServiceKey, "Parameters", KEY_READ, &ParametersKey);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    (VOID) RegistryQuerySzValue(ParametersKey, "FilterDevices", &DriverFilterDevices);
-
-    status = RegistryCreateSubKey(DriverServiceKey, "Status");
-    if (!NT_SUCCESS(status))
-        goto fail4;
+    status = RegistryOpenSubKey(ServiceKey, "Parameters", KEY_READ, &ParametersKey);
+    if (NT_SUCCESS(status))
+        __DriverSetParametersKey(ParametersKey);
 
-    status = EmulatedInitialize(&DriverEmulatedInterface);
-    if (!NT_SUCCESS(status))
-        goto fail5;
-
-    RegistryCloseKey(ParametersKey);
+    RegistryCloseKey(ServiceKey);
 
     DriverObject->DriverExtension->AddDevice = AddDevice;
 
@@ -359,21 +419,6 @@ done:
     Trace("<====\n");
     return STATUS_SUCCESS;
 
-fail5:
-    Error("fail5\n");
-
-    RegistryDeleteSubKey(DriverServiceKey, "Status");
-
-fail4:
-    Error("fail4\n");
-
-    RegistryCloseKey(ParametersKey);
-
-fail3:
-    Error("fail3\n");
-
-    RegistryCloseKey(DriverServiceKey);
-
 fail2:
     Error("fail2\n");
 
@@ -382,5 +427,9 @@ fail2:
 fail1:
     Error("fail1 (%08x)\n", status);
 
+    __DriverSetDriverObject(NULL);
+
+    ASSERT(IsZeroMemory(&Driver, sizeof (XENFILT_DRIVER)));
+
     return status;
 }
index 7e29da7c386d7e07d6c2909cc98a1b4a6c342621..d777bd841ab5252e2bd4906b649ccd804b2eb668 100644 (file)
 #include "pdo.h"
 #include "fdo.h"
 
-extern PDRIVER_OBJECT               DriverObject;
+extern PDRIVER_OBJECT
+DriverGetDriverObject(
+    VOID
+    );
 
-extern LONG                         DriverInitialized;
+extern HANDLE
+DriverGetParametersKey(
+    VOID
+    );
 
 #define MAX_DEVICE_ID_LEN   200
 
@@ -68,9 +74,4 @@ typedef struct _XENFILT_DX {
 
 #pragma warning(pop)
 
-extern PXENFILT_EMULATED_INTERFACE
-DriverGetEmulatedInterface(
-    VOID
-    );
-
 #endif  // _XENFILT_DRIVER_H
diff --git a/src/xenfilt/emulated.c b/src/xenfilt/emulated.c
deleted file mode 100644 (file)
index 36b1ed5..0000000
+++ /dev/null
@@ -1,559 +0,0 @@
-/* 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 <ntstrsafe.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <xen.h>
-#include <util.h>
-
-#include "registry.h"
-#include "emulated.h"
-#include "log.h"
-#include "assert.h"
-
-#define MAXIMUM_CLASS_NAME_LENGTH   32
-#define MAXIMUM_DEVICE_NAME_LENGTH  32
-#define MAXIMUM_ALIAS_LENGTH        128
-
-typedef struct _EMULATED_DEVICE {
-    CHAR    Class[MAXIMUM_CLASS_NAME_LENGTH];
-    CHAR    Device[MAXIMUM_DEVICE_NAME_LENGTH];
-    CHAR    Alias[MAXIMUM_ALIAS_LENGTH];
-    BOOLEAN Present;
-} EMULATED_DEVICE, *PEMULATED_DEVICE;
-
-struct _XENFILT_EMULATED_CONTEXT {
-    LONG                References;
-    PEMULATED_DEVICE    Table;
-};
-
-#define EMULATED_TAG    'LUME'
-
-static FORCEINLINE PVOID
-__EmulatedAllocate(
-    IN  ULONG   Length
-    )
-{
-    return __AllocateNonPagedPoolWithTag(Length, EMULATED_TAG);
-}
-
-static FORCEINLINE VOID
-__EmulatedFree(
-    IN  PVOID   Buffer
-    )
-{
-    __FreePoolWithTag(Buffer, EMULATED_TAG);
-}
-
-static BOOLEAN
-EmulatedIsPresent(
-    IN  PXENFILT_EMULATED_CONTEXT   Context,
-    IN  PCHAR                       Class,
-    IN  PCHAR                       Device
-    )
-{
-    PEMULATED_DEVICE                Entry;
-    BOOLEAN                         Present;
-
-    Present = FALSE;
-
-    if (Context->Table == NULL) {
-        Warning("no table\n");
-        goto done;
-    }
-
-    for (Entry = Context->Table; strlen(Entry->Alias) != 0; Entry++) {
-        if (_stricmp(Entry->Class, Class) == 0 &&
-            _stricmp(Entry->Device, Device) == 0)
-            break;
-    }
-
-    if (strlen(Entry->Alias) == 0) {
-        Info("%s %s NOT FOUND\n",
-             Class,
-             Device);
-        goto done;
-    }
-
-    Present = Entry->Present;
-
-    Info("%s %s %s\n",
-         Entry->Class,
-         Entry->Device,
-         (Present) ? "PRESENT" : "NOT PRESENT");
-
-done:
-    return Present;
-}
-
-static VOID
-EmulatedAcquire(
-    IN  PXENFILT_EMULATED_CONTEXT   Context
-    )
-{
-    InterlockedIncrement(&Context->References);
-}
-
-static VOID
-EmulatedRelease(
-    IN  PXENFILT_EMULATED_CONTEXT   Context
-    )
-{
-    ASSERT(Context->References != 0);
-    InterlockedDecrement(&Context->References);
-}
-
-#define EMULATED_OPERATION(_Type, _Name, _Arguments) \
-        Emulated ## _Name,
-
-static XENFILT_EMULATED_OPERATIONS  Operations = {
-    DEFINE_EMULATED_OPERATIONS
-};
-
-#undef EMULATED_OPERATION
-
-NTSTATUS
-EmulatedUpdate(
-    IN  PXENFILT_EMULATED_INTERFACE Interface,
-    IN  PCHAR                       Alias
-    )
-{
-    PXENFILT_EMULATED_CONTEXT       Context = Interface->Context;
-    PEMULATED_DEVICE                Entry;
-    HANDLE                          ServiceKey;
-    HANDLE                          StatusKey;
-    LONG                            Count;
-    LONG                            Index;
-    PANSI_STRING                    Old;
-    PANSI_STRING                    New;
-    ULONG                           Length;
-    NTSTATUS                        status;
-
-    if (Context->Table == NULL)
-        goto done;
-
-    for (Entry = Context->Table; strlen(Entry->Alias) != 0; Entry++) {
-        if (strcmp(Entry->Alias, Alias) == 0)
-            break;
-    }
-
-    if (strlen(Entry->Alias) == 0)
-        goto done;
-
-    Info("%s %s\n", Entry->Class, Entry->Device);
-
-    Entry->Present = TRUE;
-
-    status = RegistryOpenServiceKey(KEY_ALL_ACCESS, &ServiceKey);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status = RegistryOpenSubKey(ServiceKey, "Status", KEY_ALL_ACCESS, &StatusKey);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status = RegistryQuerySzValue(StatusKey, Entry->Class, &Old);
-    if (!NT_SUCCESS(status))
-        Old = NULL;
-
-    Count = 0;
-    for (Index = 0; Old != NULL && Old[Index].Buffer != NULL; Index++)
-        Count++;
-
-    New = __EmulatedAllocate(sizeof (ANSI_STRING) * (Count + 2));
-
-    status = STATUS_NO_MEMORY;
-    if (New == NULL)
-        goto fail3;
-
-    for (Index = 0; Index < Count; Index++) {
-        Length = Old[Index].Length;
-
-        New[Index].MaximumLength = (USHORT)Length + sizeof (CHAR);
-        New[Index].Buffer = __EmulatedAllocate(New[Index].MaximumLength);
-
-        status = STATUS_NO_MEMORY;
-        if (New[Index].Buffer == NULL)
-            goto fail4;
-
-        RtlCopyMemory(New[Index].Buffer, Old[Index].Buffer, Length);
-        New[Index].Length = (USHORT)Length;
-    }
-
-    Length = (ULONG)strlen(Entry->Device);
-
-    New[Count].MaximumLength = (USHORT)Length + sizeof (CHAR);
-    New[Count].Buffer = __EmulatedAllocate(New[Count].MaximumLength);
-
-    status = STATUS_NO_MEMORY;
-    if (New[Count].Buffer == NULL)
-        goto fail5;
-
-    RtlCopyMemory(New[Count].Buffer, Entry->Device, Length);
-    New[Count].Length = (USHORT)Length;
-
-    status = RegistryUpdateSzValue(StatusKey, Entry->Class, REG_MULTI_SZ, New);
-    if (!NT_SUCCESS(status))
-        goto fail6;
-
-    RegistryFreeSzValue(Old);
-
-    for (Index = 0; Index < Count + 1; Index++)
-        __EmulatedFree(New[Index].Buffer);
-
-    __EmulatedFree(New);
-
-    RegistryCloseKey(StatusKey);
-
-    RegistryCloseKey(ServiceKey);
-
-done:
-    return STATUS_SUCCESS;
-
-fail6:
-    Error("fail6\n");
-
-    __EmulatedFree(New[Count].Buffer);
-
-fail5:
-    Error("fail5\n");
-
-    Index = Count;
-
-fail4:
-    Error("fail4\n");
-
-    while (--Index >= 0)
-        __EmulatedFree(New[Index].Buffer);
-
-    __EmulatedFree(New);
-
-fail3:
-    Error("fail3\n");
-
-    RegistryFreeSzValue(Old);
-
-    RegistryCloseKey(StatusKey);
-
-fail2:
-    Error("fail2\n");
-
-    RegistryCloseKey(ServiceKey);
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;    
-}
-
-static NTSTATUS
-EmulatedCountDevices(
-    IN  PVOID   Context,
-    IN  HANDLE  Key,
-    IN  PCHAR   Name
-    )
-{
-    PULONG      Count = Context;
-
-    UNREFERENCED_PARAMETER(Key);
-    UNREFERENCED_PARAMETER(Name);
-
-    (*Count)++;
-
-    return STATUS_SUCCESS;
-}
-
-static NTSTATUS
-EmulatedCountClasses(
-    IN  PVOID   Context,
-    IN  HANDLE  Key,
-    IN  PCHAR   Name
-    )
-{
-    HANDLE      ClassKey;
-    NTSTATUS    status;
-
-    status = RegistryOpenSubKey(Key, Name, KEY_ALL_ACCESS, &ClassKey);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status = RegistryEnumerateValues(ClassKey, EmulatedCountDevices, Context);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    RegistryCloseKey(ClassKey);
-
-    return STATUS_SUCCESS;
-
-fail2:
-    RegistryCloseKey(ClassKey);
-    
-fail1:
-    return status;
-}
-
-static NTSTATUS
-EmulatedAddDevices(
-    IN  PVOID           Context,
-    IN  HANDLE          Key,
-    IN  PCHAR           Name
-    )
-{
-    PEMULATED_DEVICE    Entry = *(PEMULATED_DEVICE *)Context;
-    PCHAR               Class = Entry->Class;
-    PANSI_STRING        Alias;
-    NTSTATUS            status;
-
-    status = RtlStringCchPrintfA(Entry->Device,
-                                 MAXIMUM_DEVICE_NAME_LENGTH,
-                                 "%s",
-                                 Name);
-    ASSERT(NT_SUCCESS(status));
-
-    status = RegistryQuerySzValue(Key, Name, &Alias);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status = RtlStringCchPrintfA(Entry->Alias,
-                                 MAXIMUM_ALIAS_LENGTH,
-                                 "%s",
-                                 Alias[0].Buffer);
-    ASSERT(NT_SUCCESS(status));
-
-    RegistryFreeSzValue(Alias);
-
-    Entry++;
-    
-    status = RtlStringCchPrintfA(Entry->Class,
-                                 MAXIMUM_CLASS_NAME_LENGTH,
-                                 "%s",
-                                 Class);
-    ASSERT(NT_SUCCESS(status));
-
-    *(PEMULATED_DEVICE *)Context = Entry;
-
-    return STATUS_SUCCESS;
-
-fail1:
-    return status;
-}
-
-
-static NTSTATUS
-EmulatedAddClasses(
-    IN  PVOID           Context,
-    IN  HANDLE          Key,
-    IN  PCHAR           Name
-    )
-{
-    PEMULATED_DEVICE    Entry = *(PEMULATED_DEVICE *)Context;
-    HANDLE              ClassKey;
-    NTSTATUS            status;
-
-    status = RtlStringCchPrintfA(Entry->Class,
-                                 MAXIMUM_CLASS_NAME_LENGTH,
-                                 "%s",
-                                 Name);
-    ASSERT(NT_SUCCESS(status));
-
-    status = RegistryOpenSubKey(Key, Name, KEY_ALL_ACCESS, &ClassKey);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status = RegistryEnumerateValues(ClassKey, EmulatedAddDevices, &Entry);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    RegistryCloseKey(ClassKey);
-
-    *(PEMULATED_DEVICE *)Context = Entry;
-
-    return STATUS_SUCCESS;
-
-fail2:
-    RegistryCloseKey(ClassKey);
-    
-fail1:
-    return status;
-}
-
-static FORCEINLINE NTSTATUS
-__EmulatedGetDeviceTable(
-    IN  PXENFILT_EMULATED_CONTEXT   Context
-    )
-{
-    HANDLE                          ServiceKey;
-    HANDLE                          AliasesKey;
-    ULONG                           Count;
-    PEMULATED_DEVICE                Table;
-    PEMULATED_DEVICE                Entry;
-    ULONG                           Index;
-    NTSTATUS                        status;
-
-    status = RegistryOpenServiceKey(KEY_ALL_ACCESS, &ServiceKey);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status = RegistryOpenSubKey(ServiceKey, "Aliases", KEY_ALL_ACCESS, &AliasesKey);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    Count = 0;
-
-    status = RegistryEnumerateSubKeys(AliasesKey, EmulatedCountClasses, &Count);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    Table = NULL;
-
-    if (Count == 0)
-        goto done;
-
-    Table = __EmulatedAllocate(sizeof (EMULATED_DEVICE) * (Count + 1));
-
-    status = STATUS_NO_MEMORY;
-    if (Table == NULL)
-        goto fail4;
-
-    Entry = Table;
-
-    status = RegistryEnumerateSubKeys(AliasesKey, EmulatedAddClasses, &Entry);
-    if (!NT_SUCCESS(status))
-        goto fail5;
-
-    ASSERT3U((ULONG)(Entry - Table), ==, Count);
-    RtlZeroMemory(Entry, sizeof (EMULATED_DEVICE));
-
-    for (Index = 0; strlen(Table[Index].Alias) != 0; Index++) {
-        Entry = &Table[Index];
-
-        Info("[%u]: %s %s -> %s\n",
-             Index,
-             Entry->Class,
-             Entry->Device,
-             Entry->Alias);
-    }
-
-done:
-    Context->Table = Table;
-
-    RegistryCloseKey(AliasesKey);
-
-    RegistryCloseKey(ServiceKey);
-
-    return STATUS_SUCCESS;
-
-fail5:
-    Error("fail5\n");
-
-    __EmulatedFree(Table);
-
-fail4:
-    Error("fail4\n");
-
-fail3:
-    Error("fail3\n");
-
-    RegistryCloseKey(AliasesKey);
-
-fail2:
-    Error("fail2\n");
-
-    RegistryCloseKey(ServiceKey);
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
-}
-
-NTSTATUS
-EmulatedInitialize(
-    OUT PXENFILT_EMULATED_INTERFACE Interface
-    )
-{
-    PXENFILT_EMULATED_CONTEXT       Context;
-    NTSTATUS                        status;
-
-    Trace("====>\n");
-
-    Context = __EmulatedAllocate(sizeof (XENFILT_EMULATED_CONTEXT));
-
-    status = STATUS_NO_MEMORY;
-    if (Context == NULL)
-        goto fail1;
-
-    status = __EmulatedGetDeviceTable(Context);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    Interface->Context = Context;
-    Interface->Operations = &Operations;
-
-    Trace("<====\n");
-
-    return STATUS_SUCCESS;
-
-fail2:
-    Error("fail2\n");
-
-    ASSERT(IsZeroMemory(Context, sizeof (XENFILT_EMULATED_CONTEXT)));
-    __EmulatedFree(Context);
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
-}
-
-VOID
-EmulatedTeardown(
-    IN OUT  PXENFILT_EMULATED_INTERFACE Interface
-    )
-{
-    PXENFILT_EMULATED_CONTEXT           Context = Interface->Context;
-
-    Trace("====>\n");
-
-    if (Context->Table != NULL) {
-        __EmulatedFree(Context->Table);
-        Context->Table = NULL;
-    }
-
-    ASSERT(IsZeroMemory(Context, sizeof (XENFILT_EMULATED_CONTEXT)));
-    __EmulatedFree(Context);
-
-    RtlZeroMemory(Interface, sizeof (XENFILT_EMULATED_INTERFACE));
-
-    Trace("<====\n");
-}
diff --git a/src/xenfilt/emulated.h b/src/xenfilt/emulated.h
deleted file mode 100644 (file)
index aea4598..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/* 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 _XENFILT_EMULATED_H
-#define _XENFILT_EMULATED_H
-
-#include <ntddk.h>
-#include <xen.h>
-#include <emulated_interface.h>
-
-struct _XENFILT_EMULATED_INTERFACE {
-    PXENFILT_EMULATED_OPERATIONS    Operations;
-    PXENFILT_EMULATED_CONTEXT       Context;
-};
-
-C_ASSERT(FIELD_OFFSET(XENFILT_EMULATED_INTERFACE, Operations) == (ULONG_PTR)EMULATED_OPERATIONS(NULL));
-C_ASSERT(FIELD_OFFSET(XENFILT_EMULATED_INTERFACE, Context) == (ULONG_PTR)EMULATED_CONTEXT(NULL));
-
-extern NTSTATUS
-EmulatedInitialize(
-    OUT PXENFILT_EMULATED_INTERFACE Interface
-    );
-
-extern NTSTATUS
-EmulatedUpdate(
-    IN  PXENFILT_EMULATED_INTERFACE Interface,
-    IN  PCHAR                       Alias
-    );
-
-extern VOID
-EmulatedTeardown(
-    IN OUT  PXENFILT_EMULATED_INTERFACE Interface
-    );
-
-#endif  // _XENFILT_EMULATED_H
index 6507f2fc399e5adfca379e55b89f7f1d744731af..8b0e259162398de38f87616caa1e75cb993ce40b 100644 (file)
@@ -38,8 +38,6 @@
 #include <util.h>
 #include <xen.h>
 
-#include <emulated_interface.h>
-
 #include "names.h"
 #include "fdo.h"
 #include "pdo.h"
@@ -47,7 +45,7 @@
 #include "driver.h"
 #include "registry.h"
 #include "mutex.h"
-#include "log.h"
+#include "dbg_print.h"
 #include "assert.h"
 
 #define FDO_TAG 'ODF'
@@ -65,7 +63,7 @@ struct _XENFILT_FDO {
     PIRP                        DevicePowerIrp;
 
     PANSI_STRING                Classes;
-    XENFILT_MUTEX               Mutex;
+    MUTEX                       Mutex;
     ULONG                       References;
 };
 
@@ -337,8 +335,6 @@ __FdoS4ToS3(
 {
     ASSERT3U(__FdoGetSystemPowerState(Fdo), ==, PowerSystemHibernate);
 
-    UnplugReplay();
-
     __FdoSetSystemPowerState(Fdo, PowerSystemSleeping3);
 }
 
@@ -352,141 +348,6 @@ __FdoS3ToS4(
     __FdoSetSystemPowerState(Fdo, PowerSystemHibernate);
 }
 
-static FORCEINLINE VOID
-__FdoUnplugClass(
-    IN  HANDLE          Key,
-    IN  PANSI_STRING    Class
-    )
-{
-    PANSI_STRING        Classes;
-    PANSI_STRING        Devices;
-    ULONG               Index;
-    BOOLEAN             Match;
-    NTSTATUS            status;
-
-    status = RegistryQuerySzValue(Key, "UnplugClasses", &Classes);
-    if (!NT_SUCCESS(status))
-        Classes = NULL;
-
-    Match = FALSE;
-    for (Index = 0; Classes != NULL && Classes[Index].Buffer != NULL; Index++) {
-        if (strncmp(Classes[Index].Buffer,
-                    Class->Buffer,
-                    Classes[Index].Length) == 0) {
-            Match = TRUE;
-            break;
-        }
-    }
-
-    RegistryFreeSzValue(Classes);
-
-    if (!Match)
-        return;
-
-    status = RegistryQuerySzValue(Key, Class->Buffer, &Devices);
-    if (!NT_SUCCESS(status))
-        Devices = NULL;
-
-    for (Index = 0; Devices != NULL && Devices[Index].Buffer != NULL; Index++) {
-        PANSI_STRING    Device = &Devices[Index];
-
-        (VOID) UnplugDevice(Class->Buffer, Device->Buffer);
-    }
-}
-
-static FORCEINLINE VOID
-__FdoUnplugDevices(
-    IN  HANDLE          Key,
-    IN  PANSI_STRING    Class
-    )
-{
-    PANSI_STRING        Devices;
-    ULONG               Index;
-    NTSTATUS            status;
-
-    status = RegistryQuerySzValue(Key, "UnplugDevices", &Devices);
-    if (!NT_SUCCESS(status))
-        Devices = NULL;
-
-    for (Index = 0; Devices != NULL && Devices[Index].Buffer != NULL; Index++) {
-        PCHAR   Device;
-
-        Device = strchr(Devices->Buffer, '#');
-        if (Device == NULL)
-            continue;
-
-        *Device++ = '\0';
-
-        if (strncmp(Class->Buffer,
-                    Devices->Buffer,
-                    Class->Length) != 0)
-            continue;
-
-        (VOID) UnplugDevice(Class->Buffer, Device);
-    }
-}
-
-static FORCEINLINE NTSTATUS
-__FdoUnplugStart(
-    IN  PXENFILT_FDO    Fdo
-    )
-{
-    HANDLE              ServiceKey;
-    HANDLE              ParametersKey;
-    ULONG               Index;
-    NTSTATUS            status;
-
-    status = UnplugReference();
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status = RegistryOpenServiceKey(KEY_READ, &ServiceKey);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status = RegistryOpenSubKey(ServiceKey, "Parameters", KEY_READ, &ParametersKey);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    for (Index = 0; Fdo->Classes != NULL && Fdo->Classes[Index].Buffer != NULL; Index++) {
-        PANSI_STRING    Class = &Fdo->Classes[Index];
-
-        __FdoUnplugClass(ParametersKey, Class);
-        __FdoUnplugDevices(ParametersKey, Class);
-    }
-
-    RegistryCloseKey(ParametersKey);
-
-    RegistryCloseKey(ServiceKey);
-
-    return STATUS_SUCCESS;
-
-fail3:
-    Error("fail3\n");
-
-    RegistryCloseKey(ServiceKey);
-
-fail2:
-    Error("fail2\n");
-
-    UnplugDereference();
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
-}
-
-static FORCEINLINE VOID
-__FdoUnplugStop(
-    IN  PXENFILT_FDO    Fdo
-    )
-{
-    UNREFERENCED_PARAMETER(Fdo);
-
-    UnplugDereference();
-}
-
 __drv_functionClass(IO_COMPLETION_ROUTINE)
 __drv_sameIRQL
 static NTSTATUS
@@ -555,8 +416,6 @@ FdoStartDevice(
     if (!NT_SUCCESS(status))
         goto fail1;
 
-    (VOID) __FdoUnplugStart(Fdo);
-
     status = FdoForwardIrpSynchronously(Fdo, Irp);
     if (!NT_SUCCESS(status))
         goto fail2;
@@ -583,8 +442,6 @@ FdoStartDevice(
     return status;
 
 fail2:
-    __FdoUnplugStop(Fdo);
-
     IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
 
 fail1:
@@ -718,8 +575,6 @@ __FdoStopDevice(
 
     UNREFERENCED_PARAMETER(DeviceObject);
 
-    __FdoUnplugStop(Fdo);
-
     if (Irp->PendingReturned)
         IoMarkIrpPending(Irp);
 
@@ -973,8 +828,6 @@ FdoRemoveDevice(
 done:
     __FdoSetDevicePnpState(Fdo, Deleted);
 
-    __FdoUnplugStop(Fdo);
-
     IoReleaseRemoveLockAndWait(&Fdo->Dx->RemoveLock, Irp);
 
     status = FdoForwardIrpSynchronously(Fdo, Irp);
@@ -1930,7 +1783,7 @@ FdoCreate(
     ObDereferenceObject(LowerDeviceObject);
 
 #pragma prefast(suppress:28197) // Possibly leaking memory 'FilterDeviceObject'
-    status = IoCreateDevice(DriverObject,
+    status = IoCreateDevice(DriverGetDriverObject(),
                             sizeof (XENFILT_DX),
                             NULL,
                             DeviceType,
@@ -2077,7 +1930,7 @@ FdoDestroy(
 
     Dx->Fdo = NULL;
 
-    RtlZeroMemory(&Fdo->Mutex, sizeof (XENFILT_MUTEX));
+    RtlZeroMemory(&Fdo->Mutex, sizeof (MUTEX));
 
     if (Fdo->Classes != NULL) {
         RegistryFreeSzValue(Fdo->Classes);
index 06fa1cf700014e4170a9416eac7f5530d10c6a11..0f66fc16134853cc3e335724e4abbd9bca02b563 100644 (file)
@@ -34,8 +34,6 @@
 
 #include <ntddk.h>
 
-#include <emulated_interface.h>
-
 #include "types.h"
 
 typedef struct _XENFILT_FDO XENFILT_FDO, *PXENFILT_FDO;
diff --git a/src/xenfilt/log.h b/src/xenfilt/log.h
deleted file mode 100644 (file)
index 69e1819..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/* 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 _XENFILT_LOG_H
-#define _XENFILT_LOG_H
-
-#define __MODULE__ "XENFILT"
-
-#include <ntddk.h>
-#include <stdarg.h>
-
-#pragma warning(disable:4127)   // conditional expression is constant
-
-static __inline VOID
-__Error(
-    IN  const CHAR  *Prefix,
-    IN  const CHAR  *Format,
-    ...
-    )
-{
-    va_list         Arguments;
-
-    va_start(Arguments, Format);
-
-#pragma prefast(suppress:6001) // Using uninitialized memory
-    vDbgPrintExWithPrefix(Prefix,
-                          DPFLTR_IHVDRIVER_ID,
-                          DPFLTR_ERROR_LEVEL,
-                          Format,
-                          Arguments);
-    va_end(Arguments);
-}
-
-#define Error(...)  \
-        __Error(__MODULE__ "|" __FUNCTION__ ": ", __VA_ARGS__)
-
-static __inline VOID
-__Warning(
-    IN  const CHAR  *Prefix,
-    IN  const CHAR  *Format,
-    ...
-    )
-{
-    va_list         Arguments;
-
-    va_start(Arguments, Format);
-
-#pragma prefast(suppress:6001) // Using uninitialized memory
-    vDbgPrintExWithPrefix(Prefix,
-                          DPFLTR_IHVDRIVER_ID,
-                          DPFLTR_WARNING_LEVEL,
-                          Format,
-                          Arguments);
-    va_end(Arguments);
-}
-
-#define Warning(...)  \
-        __Warning(__MODULE__ "|" __FUNCTION__ ": ", __VA_ARGS__)
-
-#if DBG
-static __inline VOID
-__Trace(
-    IN  const CHAR  *Prefix,
-    IN  const CHAR  *Format,
-    ...
-    )
-{
-    va_list         Arguments;
-
-    va_start(Arguments, Format);
-
-#pragma prefast(suppress:6001) // Using uninitialized memory
-    vDbgPrintExWithPrefix(Prefix,
-                          DPFLTR_IHVDRIVER_ID,
-                          DPFLTR_TRACE_LEVEL,
-                          Format,
-                          Arguments);
-    va_end(Arguments);
-}
-
-#define Trace(...)  \
-        __Trace(__MODULE__ "|" __FUNCTION__ ": ", __VA_ARGS__)
-#else   // DBG
-#define Trace(...)  (VOID)(__VA_ARGS__)
-#endif  // DBG
-
-static __inline VOID
-__Info(
-    IN  const CHAR  *Prefix,
-    IN  const CHAR  *Format,
-    ...
-    )
-{
-    va_list         Arguments;
-
-    va_start(Arguments, Format);
-
-#pragma prefast(suppress:6001) // Using uninitialized memory
-    vDbgPrintExWithPrefix(Prefix,
-                          DPFLTR_IHVDRIVER_ID,
-                          DPFLTR_INFO_LEVEL,
-                          Format,
-                          Arguments);
-    va_end(Arguments);
-}
-
-#define Info(...)  \
-        __Info(__MODULE__ "|"  __FUNCTION__ ": ", __VA_ARGS__)
-
-#endif  // _XENFILT_LOG_H
diff --git a/src/xenfilt/mutex.h b/src/xenfilt/mutex.h
deleted file mode 100644 (file)
index d6ca94a..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/* 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 _XENFILT_MUTEX_H
-#define _XENFILT_MUTEX_H
-
-#include <ntddk.h>
-
-#include "assert.h"
-
-typedef struct _XENFILT_MUTEX {
-    PKTHREAD        Owner;
-    KEVENT          Event;
-} XENFILT_MUTEX, *PXENFILT_MUTEX;
-
-static FORCEINLINE VOID
-InitializeMutex(
-    IN  PXENFILT_MUTEX  Mutex
-    )
-{
-    RtlZeroMemory(Mutex, sizeof (XENFILT_MUTEX));
-
-    KeInitializeEvent(&Mutex->Event, SynchronizationEvent, TRUE);
-}
-
-static FORCEINLINE VOID
-__drv_maxIRQL(PASSIVE_LEVEL)
-AcquireMutex(
-    IN  PXENFILT_MUTEX  Mutex
-    )
-{
-    (VOID) KeWaitForSingleObject(&Mutex->Event,
-                                 Executive,
-                                 KernelMode,
-                                 FALSE,
-                                 NULL);
-
-    ASSERT3P(Mutex->Owner, ==, NULL);
-    Mutex->Owner = KeGetCurrentThread();
-}
-
-static FORCEINLINE VOID
-__drv_maxIRQL(PASSIVE_LEVEL)
-ReleaseMutex(
-    IN  PXENFILT_MUTEX  Mutex
-    )
-{
-    ASSERT3P(Mutex->Owner, ==, KeGetCurrentThread());
-    Mutex->Owner = NULL;
-
-    KeSetEvent(&Mutex->Event, IO_NO_INCREMENT, FALSE);
-}
-
-#endif  // _XENFILT_MUTEX_H
diff --git a/src/xenfilt/names.h b/src/xenfilt/names.h
deleted file mode 100644 (file)
index 8c9ff17..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-/* 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 _XENFILT_NAMES_H_
-#define _XENFILT_NAMES_H_
-
-#include <ntddk.h>
-
-#include "types.h"
-
-static FORCEINLINE const PCHAR
-PowerTypeName(
-    IN  POWER_STATE_TYPE    Type
-    )
-{
-#define _POWER_TYPE_NAME(_Type) \
-        case _Type:             \
-            return #_Type;
-
-    switch (Type) {
-    _POWER_TYPE_NAME(SystemPowerState);
-    _POWER_TYPE_NAME(DevicePowerState);
-    default:
-        break;
-    }
-
-    return ("UNKNOWN");
-#undef  _POWER_ACTION_NAME
-}
-
-static FORCEINLINE const PCHAR
-PowerSystemStateName(
-    IN  SYSTEM_POWER_STATE State
-    )
-{
-#define _POWER_SYSTEM_STATE_NAME(_State)    \
-        case PowerSystem ## _State:         \
-            return #_State;
-
-    switch (State) {
-    _POWER_SYSTEM_STATE_NAME(Unspecified);
-    _POWER_SYSTEM_STATE_NAME(Working);
-    _POWER_SYSTEM_STATE_NAME(Sleeping1);
-    _POWER_SYSTEM_STATE_NAME(Sleeping2);
-    _POWER_SYSTEM_STATE_NAME(Sleeping3);
-    _POWER_SYSTEM_STATE_NAME(Hibernate);
-    _POWER_SYSTEM_STATE_NAME(Shutdown);
-    _POWER_SYSTEM_STATE_NAME(Maximum);
-    default:
-        break;
-    }
-
-    return ("UNKNOWN");
-#undef  _POWER_SYSTEM_STATE_NAME
-}
-
-static FORCEINLINE const PCHAR
-PowerDeviceStateName(
-    IN  DEVICE_POWER_STATE State
-    )
-{
-#define _POWER_DEVICE_STATE_NAME(_State)    \
-        case PowerDevice ## _State:         \
-            return #_State;
-
-    switch (State) {
-    _POWER_DEVICE_STATE_NAME(Unspecified);
-    _POWER_DEVICE_STATE_NAME(D0);
-    _POWER_DEVICE_STATE_NAME(D1);
-    _POWER_DEVICE_STATE_NAME(D2);
-    _POWER_DEVICE_STATE_NAME(D3);
-    _POWER_DEVICE_STATE_NAME(Maximum);
-    default:
-        break;
-    }
-
-    return ("UNKNOWN");
-#undef  _POWER_DEVICE_STATE_NAME
-}
-
-static FORCEINLINE const PCHAR
-PowerActionName(
-    IN  POWER_ACTION    Type
-    )
-{
-#define _POWER_ACTION_NAME(_Type)   \
-        case PowerAction ## _Type:  \
-            return #_Type;
-
-    switch (Type) {
-    _POWER_ACTION_NAME(None);
-    _POWER_ACTION_NAME(Reserved);
-    _POWER_ACTION_NAME(Sleep);
-    _POWER_ACTION_NAME(Hibernate);
-    _POWER_ACTION_NAME(Shutdown);
-    _POWER_ACTION_NAME(ShutdownReset);
-    _POWER_ACTION_NAME(ShutdownOff);
-    _POWER_ACTION_NAME(WarmEject);
-    default:
-        break;
-    }
-
-    return ("UNKNOWN");
-#undef  _POWER_ACTION_NAME
-}
-
-static FORCEINLINE const PCHAR
-PowerMinorFunctionName(
-    IN  ULONG   MinorFunction
-    )
-{
-#define _POWER_MINOR_FUNCTION_NAME(_Function)   \
-    case IRP_MN_ ## _Function:                  \
-        return #_Function;
-
-    switch (MinorFunction) {
-    _POWER_MINOR_FUNCTION_NAME(WAIT_WAKE);
-    _POWER_MINOR_FUNCTION_NAME(POWER_SEQUENCE);
-    _POWER_MINOR_FUNCTION_NAME(SET_POWER);
-    _POWER_MINOR_FUNCTION_NAME(QUERY_POWER);
-
-    default:
-        return "UNKNOWN";
-    }
-
-#undef  _POWER_MINOR_FUNCTION_NAME
-}
-
-static FORCEINLINE const PCHAR
-PnpDeviceStateName(
-    IN  DEVICE_PNP_STATE    State
-    )
-{
-#define _PNP_DEVICE_STATE_NAME(_State) \
-    case  _State:               \
-        return #_State;
-
-    switch (State) {
-    _PNP_DEVICE_STATE_NAME(Invalid);
-    _PNP_DEVICE_STATE_NAME(Present);
-    _PNP_DEVICE_STATE_NAME(Enumerated);
-    _PNP_DEVICE_STATE_NAME(Added);
-    _PNP_DEVICE_STATE_NAME(Started);
-    _PNP_DEVICE_STATE_NAME(StopPending);
-    _PNP_DEVICE_STATE_NAME(Stopped);
-    _PNP_DEVICE_STATE_NAME(RemovePending);
-    _PNP_DEVICE_STATE_NAME(SurpriseRemovePending);
-    _PNP_DEVICE_STATE_NAME(Deleted);
-    default:
-        break;
-    }
-
-    return "UNKNOWN";
-
-#undef  _STATE_NAME
-}
-
-static FORCEINLINE const PCHAR
-PnpMinorFunctionName(
-    IN  ULONG   Function
-    )
-{
-#define _PNP_MINOR_FUNCTION_NAME(_Function) \
-    case IRP_MN_ ## _Function:              \
-        return #_Function;
-
-    switch (Function) {
-    _PNP_MINOR_FUNCTION_NAME(START_DEVICE);
-    _PNP_MINOR_FUNCTION_NAME(QUERY_REMOVE_DEVICE);
-    _PNP_MINOR_FUNCTION_NAME(REMOVE_DEVICE);
-    _PNP_MINOR_FUNCTION_NAME(CANCEL_REMOVE_DEVICE);
-    _PNP_MINOR_FUNCTION_NAME(STOP_DEVICE);
-    _PNP_MINOR_FUNCTION_NAME(QUERY_STOP_DEVICE);
-    _PNP_MINOR_FUNCTION_NAME(CANCEL_STOP_DEVICE);
-    _PNP_MINOR_FUNCTION_NAME(QUERY_DEVICE_RELATIONS);
-    _PNP_MINOR_FUNCTION_NAME(QUERY_INTERFACE);
-    _PNP_MINOR_FUNCTION_NAME(QUERY_CAPABILITIES);
-    _PNP_MINOR_FUNCTION_NAME(QUERY_RESOURCES);
-    _PNP_MINOR_FUNCTION_NAME(QUERY_RESOURCE_REQUIREMENTS);
-    _PNP_MINOR_FUNCTION_NAME(QUERY_DEVICE_TEXT);
-    _PNP_MINOR_FUNCTION_NAME(FILTER_RESOURCE_REQUIREMENTS);
-    _PNP_MINOR_FUNCTION_NAME(READ_CONFIG);
-    _PNP_MINOR_FUNCTION_NAME(WRITE_CONFIG);
-    _PNP_MINOR_FUNCTION_NAME(EJECT);
-    _PNP_MINOR_FUNCTION_NAME(SET_LOCK);
-    _PNP_MINOR_FUNCTION_NAME(QUERY_ID);
-    _PNP_MINOR_FUNCTION_NAME(QUERY_PNP_DEVICE_STATE);
-    _PNP_MINOR_FUNCTION_NAME(QUERY_BUS_INFORMATION);
-    _PNP_MINOR_FUNCTION_NAME(DEVICE_USAGE_NOTIFICATION);
-    _PNP_MINOR_FUNCTION_NAME(SURPRISE_REMOVAL);
-    _PNP_MINOR_FUNCTION_NAME(QUERY_LEGACY_BUS_INFORMATION);
-    default:
-        break;
-    }
-
-    return "UNKNOWN";
-
-#undef  _PNP_MINOR_FUNCTION_NAME
-}
-
-static FORCEINLINE const PCHAR
-PartialResourceDescriptorTypeName(
-    IN  UCHAR   Type
-    )
-{
-#define _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(_Type)   \
-    case CmResourceType ## _Type:                       \
-        return #_Type;
-
-    switch (Type) {
-    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Null);
-    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Port);
-    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Interrupt);
-    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Memory);
-    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Dma);
-    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(DeviceSpecific);
-    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(BusNumber);
-    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(MemoryLarge);
-    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(ConfigData);
-    _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(DevicePrivate);
-    default:
-        break;
-    }
-
-    return "UNKNOWN";
-
-#undef  _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME
-}
-
-#endif // _XENFILT_NAMES_H_
index 8bb1dfb32abb5bf231c5dab4d152e9fbf1e6d30e..702432c1f21566f50182a63c086b7687ad2728c1 100644 (file)
@@ -41,8 +41,7 @@
 #include "pdo.h"
 #include "thread.h"
 #include "driver.h"
-#include "emulated.h"
-#include "log.h"
+#include "dbg_print.h"
 #include "assert.h"
 
 #define PDO_TAG 'ODP'
@@ -357,7 +356,7 @@ __PdoSetName(
 
     ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
 
-    status = RtlStringCbPrintfA(Dx->Name, MAX_DEVICE_ID_LEN, "%ws#%ws", DeviceID, InstanceID);
+    status = RtlStringCbPrintfA(Dx->Name, MAX_DEVICE_ID_LEN, "%ws\\%ws", DeviceID, InstanceID);
     ASSERT(NT_SUCCESS(status));
 }
 
@@ -866,50 +865,6 @@ fail1:
     return status;
 }
 
-static NTSTATUS
-PdoQueryEmulatedInterface(
-    IN  PXENFILT_PDO            Pdo,
-    IN  PIRP                    Irp
-    )
-{
-    PIO_STACK_LOCATION          StackLocation;
-    USHORT                      Size;
-    USHORT                      Version;
-    PXENFILT_EMULATED_INTERFACE EmulatedInterface;
-    PINTERFACE                  Interface;
-    NTSTATUS                    status;
-
-    UNREFERENCED_PARAMETER(Pdo);
-
-    status = Irp->IoStatus.Status;        
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    Size = StackLocation->Parameters.QueryInterface.Size;
-    Version = StackLocation->Parameters.QueryInterface.Version;
-    Interface = StackLocation->Parameters.QueryInterface.Interface;
-
-    if (StackLocation->Parameters.QueryInterface.Version != EMULATED_INTERFACE_VERSION)
-        goto done;
-
-    status = STATUS_BUFFER_TOO_SMALL;        
-    if (StackLocation->Parameters.QueryInterface.Size < sizeof (INTERFACE))
-        goto done;
-
-    EmulatedInterface = DriverGetEmulatedInterface();
-
-    Interface->Size = sizeof (INTERFACE);
-    Interface->Version = EMULATED_INTERFACE_VERSION;
-    Interface->Context = EmulatedInterface;
-    Interface->InterfaceReference = NULL;
-    Interface->InterfaceDereference = NULL;
-
-    Irp->IoStatus.Information = 0;
-    status = STATUS_SUCCESS;
-
-done:
-    return status;
-}
-
 __drv_functionClass(IO_COMPLETION_ROUTINE)
 __drv_sameIRQL
 static NTSTATUS
@@ -941,7 +896,6 @@ struct _INTERFACE_ENTRY {
         { &GUID_ ## _Guid, #_Guid, (_Function) }
 
 struct _INTERFACE_ENTRY PdoInterfaceTable[] = {
-    DEFINE_HANDLER(EMULATED_INTERFACE, PdoQueryEmulatedInterface),
     { NULL, NULL, NULL }
 };
 
@@ -1812,7 +1766,6 @@ PdoCreate(
     PXENFILT_PDO                Pdo;
     PWCHAR                      DeviceID;
     PWCHAR                      InstanceID;
-    PXENFILT_EMULATED_INTERFACE EmulatedInterface;
     NTSTATUS                    status;
 
     LowerDeviceObject = IoGetAttachedDeviceReference(PhysicalDeviceObject);
@@ -1820,7 +1773,7 @@ PdoCreate(
     ObDereferenceObject(LowerDeviceObject);
 
 #pragma prefast(suppress:28197) // Possibly leaking memory 'PhysicalDeviceObject'
-    status = IoCreateDevice(DriverObject,
+    status = IoCreateDevice(DriverGetDriverObject(),
                             sizeof(XENFILT_DX),
                             NULL,
                             DeviceType,
@@ -1878,16 +1831,6 @@ PdoCreate(
                  (DeviceID != NULL) ? DeviceID : L"UNKNOWN",
                  (InstanceID != NULL) ? InstanceID : L"UNKNOWN");
 
-    EmulatedInterface = DriverGetEmulatedInterface();
-
-    EMULATED(Acquire, EmulatedInterface);
-
-    status = EmulatedUpdate(EmulatedInterface, __PdoGetName(Pdo));
-    if (!NT_SUCCESS(status))
-        goto fail6;
-
-    EMULATED(Release, EmulatedInterface);
-
     Info("%p (%s)\n",
           FilterDeviceObject,
           __PdoGetName(Pdo));
@@ -1911,15 +1854,6 @@ PdoCreate(
 
     return STATUS_SUCCESS;
 
-fail6:
-    Error("fail6\n");
-
-    EMULATED(Release, EmulatedInterface);
-
-    ThreadAlert(Pdo->DevicePowerThread);
-    ThreadJoin(Pdo->DevicePowerThread);
-    Pdo->DevicePowerThread = NULL;
-
 fail5:
     Error("fail5\n");
 
diff --git a/src/xenfilt/registry.c b/src/xenfilt/registry.c
deleted file mode 100644 (file)
index 4abd1cd..0000000
+++ /dev/null
@@ -1,986 +0,0 @@
-/* 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 "log.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
-RegistryOpenServiceKey(
-    IN  ACCESS_MASK     DesiredAccess,
-    OUT PHANDLE         Key
-    )
-{
-    OBJECT_ATTRIBUTES   Attributes;
-    NTSTATUS            status;
-
-    InitializeObjectAttributes(&Attributes,
-                               &RegistryPath,
-                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
-                               NULL,
-                               NULL);
-
-    status = ZwOpenKey(Key,
-                       DesiredAccess,
-                       &Attributes);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    return STATUS_SUCCESS;
-
-fail1:
-    return status;
-}
-
-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
-    )
-{
-    NTSTATUS            status;
-
-    status = IoOpenDeviceRegistryKey(DeviceObject,
-                                     PLUGPLAY_REGKEY_DEVICE,
-                                     DesiredAccess,
-                                     Key);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    return STATUS_SUCCESS;
-
-fail1:
-    return status;
-}
-
-NTSTATUS
-RegistryOpenSubKey(
-    IN  PHANDLE         Key,
-    IN  PCHAR           Name,
-    IN  ACCESS_MASK     DesiredAccess,
-    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 = ZwOpenKey(SubKey,
-                       DesiredAccess,
-                       &Attributes);
-    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
-    )
-{
-    ANSI_STRING         Ansi;
-    UNICODE_STRING      Unicode;
-    OBJECT_ATTRIBUTES   Attributes;
-    HANDLE              SubKey;
-    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,
-                         REG_OPTION_VOLATILE,
-                         NULL
-                         );
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    ZwClose(SubKey);
-
-    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;
-    OBJECT_ATTRIBUTES   Attributes;
-    HANDLE              SubKey;
-    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 = ZwOpenKey(&SubKey,
-                       KEY_ALL_ACCESS,
-                       &Attributes);
-    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 = 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
-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
-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;
-}
-
-static PKEY_VALUE_PARTIAL_INFORMATION
-RegistryAnsiToSz(
-    PANSI_STRING                    Ansi
-    )
-{
-    ULONG                           Length;
-    PKEY_VALUE_PARTIAL_INFORMATION  Partial;
-    UNICODE_STRING                  Unicode;
-    NTSTATUS                        status;
-
-    Length = Ansi->Length + 1;
-    Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) +
-                                 Length * sizeof (WCHAR));
-
-    status = STATUS_NO_MEMORY;
-    if (Partial == NULL)
-        goto fail1;
-
-    Partial->TitleIndex = 0;
-    Partial->Type = REG_SZ;
-    Partial->DataLength = Length * sizeof (WCHAR);
-
-    Unicode.MaximumLength = (UCHAR)Partial->DataLength;
-    Unicode.Buffer = (PWCHAR)Partial->Data;
-    Unicode.Length = 0;
-
-    status = RtlAnsiStringToUnicodeString(&Unicode, Ansi, FALSE);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    return Partial;
-
-fail2:
-    __RegistryFree(Partial);
-
-fail1:
-    return NULL;
-}
-
-static PKEY_VALUE_PARTIAL_INFORMATION
-RegistryAnsiToMultiSz(
-    PANSI_STRING                    Ansi
-    )
-{
-    ULONG                           Length;
-    ULONG                           Index;
-    PKEY_VALUE_PARTIAL_INFORMATION  Partial;
-    UNICODE_STRING                  Unicode;
-    NTSTATUS                        status;
-
-    Length = 1;
-    for (Index = 0; Ansi[Index].Buffer != NULL; Index++)
-        Length += Ansi[Index].Length + 1;
-
-    Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) +
-                               Length * sizeof (WCHAR));
-
-    status = STATUS_NO_MEMORY;
-    if (Partial == NULL)
-        goto fail1;
-
-    Partial->TitleIndex = 0;
-    Partial->Type = REG_MULTI_SZ;
-    Partial->DataLength = Length * sizeof (WCHAR);
-
-    Unicode.MaximumLength = (USHORT)Partial->DataLength;
-    Unicode.Buffer = (PWCHAR)Partial->Data;
-    Unicode.Length = 0;
-
-    for (Index = 0; Ansi[Index].Buffer != NULL; Index++) {
-        status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi[Index], FALSE);
-        if (!NT_SUCCESS(status))
-            goto fail2;
-
-        Length = Unicode.Length / sizeof (WCHAR);
-
-        ASSERT3U(Unicode.MaximumLength, >=, (Length + 1) * sizeof (WCHAR));
-        Unicode.MaximumLength -= (USHORT)((Length + 1) * sizeof (WCHAR));
-        Unicode.Buffer += Length + 1;
-        Unicode.Length = 0;
-    }
-    *Unicode.Buffer = L'\0';
-
-    return Partial;
-
-fail2:
-    __RegistryFree(Partial);
-
-fail1:
-    return NULL;
-}
-
-NTSTATUS
-RegistryUpdateSzValue(
-    IN  HANDLE                      Key,
-    IN  PCHAR                       Name,
-    IN  ULONG                       Type,
-    ...
-    )
-{
-    ANSI_STRING                     Ansi;
-    UNICODE_STRING                  Unicode;
-    va_list                         Arguments;
-    PKEY_VALUE_PARTIAL_INFORMATION  Partial;
-    NTSTATUS                        status;
-
-    RtlInitAnsiString(&Ansi, Name);
-
-    status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-        
-    va_start(Arguments, Type);
-    switch (Type) {
-    case REG_SZ: {
-        PANSI_STRING    Argument;
-
-        Argument = va_arg(Arguments, PANSI_STRING);
-
-        status = STATUS_NO_MEMORY;
-        Partial = RegistryAnsiToSz(Argument);        
-        break;
-    }
-    case REG_MULTI_SZ: {
-        PANSI_STRING    Argument;
-
-        Argument = va_arg(Arguments, PANSI_STRING);
-
-        status = STATUS_NO_MEMORY;
-        Partial = RegistryAnsiToMultiSz(Argument);        
-        break;
-    }
-    default:
-        status = STATUS_INVALID_PARAMETER;
-        Partial = NULL;
-        break;
-    }
-    va_end(Arguments);
-
-    if (Partial == NULL)
-        goto fail2;
-
-    status = ZwSetValueKey(Key,
-                           &Unicode,
-                           Partial->TitleIndex,
-                           Partial->Type,
-                           Partial->Data,
-                           Partial->DataLength);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    __RegistryFree(Partial);
-
-    RtlFreeUnicodeString(&Unicode);
-
-    return STATUS_SUCCESS;
-
-fail3:
-    __RegistryFree(Partial);
-
-fail2:
-    RtlFreeUnicodeString(&Unicode);
-
-fail1:
-    return status;
-}
-
-VOID
-RegistryFreeSzValue(
-    IN  PANSI_STRING    Array
-    )
-{
-    ULONG               Index;
-
-    if (Array == NULL)
-        return;
-
-    for (Index = 0; Array[Index].Buffer != NULL; Index++)
-        __RegistryFree(Array[Index].Buffer);
-
-    __RegistryFree(Array);
-}
-
-VOID
-RegistryCloseKey(
-    IN  HANDLE  Key
-    )
-{
-    ZwClose(Key);
-}
diff --git a/src/xenfilt/registry.h b/src/xenfilt/registry.h
deleted file mode 100644 (file)
index a787901..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/* 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 _XENFILT_REGISTRY_H
-#define _XENFILT_REGISTRY_H
-
-#include <ntddk.h>
-
-extern NTSTATUS
-RegistryInitialize(
-    IN PUNICODE_STRING  Path
-    );
-
-extern VOID
-RegistryTeardown(
-    VOID
-    );
-
-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
-    );
-
-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
-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 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  // _XENFILT_REGISTRY_H
index 1095b2f8dc2462fa454fca54cbd1d8262c3e3380..f85a240fe8dfeb85200497d909a230243f1fe210 100644 (file)
@@ -33,7 +33,7 @@
 #include <util.h>
 
 #include "thread.h"
-#include "log.h"
+#include "dbg_print.h"
 #include "assert.h"
 
 #define THREAD_POOL 'ERHT'