[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [RFC PATCH 6/6] Remove XenDisk


  • To: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>, "win-pv-devel@xxxxxxxxxxxxxxxxxxxx" <win-pv-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Owen Smith <owen.smith@xxxxxxxxxx>
  • Date: Wed, 4 Mar 2026 08:32:13 +0000
  • Accept-language: en-GB, en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=iux+kzWjZspfpVyP5lYO8Spjq4LZOm+7qf22ONcLl/8=; b=hg1qTnDLd6ceGc3vs+EaDOzgqM9d/IaIjvdm0eGIfx8HlbVNJddwEYEarur6+Aa95ZCNRTTnUgYTOqiZTgrs9Gu4bx4Ct/B1YVq9g5XUSI76HhK7tckcSle30/XbbUIIhpHuXgP9bS9c7XAE018w5K9EKFEQgazTvYsI6XKK6a89yuC645IuJGvZlXX0JRfmk/ZdSIbOhEkII9ni/LgPijJRrDa3josmusdLkBvye6soFC3/rhI+g9AU05TCfIWaVmuMhuKFjLCRKQ6ofQzX9Gj2mCYmwZwdTV/7fEScPKmG9djfQwLCITUzsxofdDWKp3qumk9O/nYZIVgfZpdrMQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=e+ypMoZSN+h3EGkw4MMfgZWKTS3s5clccVrG//OFJkiP3T1uM6aFhqogffJyFd+Di3UtfVuNdVvvwGfL+m5rchJuQQfb7N3nbub7xnu4yXf5W0+CbyC39GlZmL/s0l4zt5Zu/fTViY/A9r5etBgXjYDNuWRP1fV6QBcRowyRsSacprWni/6mQWUwuLuhIRSyfdlPz9VJEE56qWBfbg7HPdV0uZUyTGbA4uWk86rBHfBBCo2eNSqQDrxyJxbP2banKW7eCuamibO8FgSKmfG684MHU32p0Rqs3Fz+z0ujKIB36Zbb01yjpzjbrhOaPO4NluGYrWx8pEHCBYaCftGosQ==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=citrix.com;
  • Delivery-date: Wed, 04 Mar 2026 08:32:25 +0000
  • List-id: Developer list for the Windows PV Drivers subproject <win-pv-devel.lists.xenproject.org>
  • Msip_labels:
  • Thread-index: AQHcpw8J8/5r9gR8eEeS2Wh4JDfN6rWeE4JZ
  • Thread-topic: [RFC PATCH 6/6] Remove XenDisk

This patch was prepared on the v1 of my series, refactoring the features and 
disk info,
it did not apply correctly to the v2 of that series. As this is a 'deletion' 
patch, the main
changes needed were updating the to-be-deleted files, and my refactor lost some 
of
the whitespace fixes.

This would likely need replacing should the v2 Refactor Features and DiskInfo 
be applied,
but the general intent is good.

I've run some testing with these patches applied to XenServer's queue, and had 
good
results.

Owen

________________________________________
From: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
Sent: 26 February 2026 10:59 AM
To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx
Cc: Tu Dinh; Owen Smith
Subject: [RFC PATCH 6/6] Remove XenDisk

Windows 8/Server 2012 natively support SCSIOP_UNMAP. XenVbd now also
correctly handles the reporting to enable unmap support. As such, the
functionality provided by XenDisk is no longer needed.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
---
 msbuild.ps1                         |    2 +-
 src/xendisk/assert.h                |  220 ---
 src/xendisk/debug.h                 |   95 --
 src/xendisk/driver.c                |  283 ----
 src/xendisk/driver.h                |   76 -
 src/xendisk/fdo.c                   | 1618 ----------------------
 src/xendisk/fdo.h                   |   84 --
 src/xendisk/mutex.h                 |  114 --
 src/xendisk/pdo.c                   | 2000 ---------------------------
 src/xendisk/pdo.h                   |   77 --
 src/xendisk/registry.c              | 1564 ---------------------
 src/xendisk/registry.h              |  211 ---
 src/xendisk/thread.c                |  226 ---
 src/xendisk/thread.h                |   75 -
 src/xendisk/types.h                 |   54 -
 src/xendisk/xendisk.rc              |   57 -
 src/xenvbd.inf                      |  118 +-
 src/xenvbd/target.c                 |    6 +-
 vs2019/package/package.vcxproj      |    3 -
 vs2019/xendisk/xendisk.vcxproj      |   83 --
 vs2019/xendisk/xendisk.vcxproj.user |    8 -
 vs2019/xenvbd.sln                   |   14 -
 vs2022/package/package.vcxproj      |    3 -
 vs2022/xendisk/xendisk.vcxproj      |   76 -
 vs2022/xendisk/xendisk.vcxproj.user |    8 -
 vs2022/xenvbd.sln                   |   10 -
 26 files changed, 52 insertions(+), 7033 deletions(-)
 delete mode 100644 src/xendisk/assert.h
 delete mode 100644 src/xendisk/debug.h
 delete mode 100644 src/xendisk/driver.c
 delete mode 100644 src/xendisk/driver.h
 delete mode 100644 src/xendisk/fdo.c
 delete mode 100644 src/xendisk/fdo.h
 delete mode 100644 src/xendisk/mutex.h
 delete mode 100644 src/xendisk/pdo.c
 delete mode 100644 src/xendisk/pdo.h
 delete mode 100644 src/xendisk/registry.c
 delete mode 100644 src/xendisk/registry.h
 delete mode 100644 src/xendisk/thread.c
 delete mode 100644 src/xendisk/thread.h
 delete mode 100644 src/xendisk/types.h
 delete mode 100644 src/xendisk/xendisk.rc
 delete mode 100644 vs2019/xendisk/xendisk.vcxproj
 delete mode 100644 vs2019/xendisk/xendisk.vcxproj.user
 delete mode 100644 vs2022/xendisk/xendisk.vcxproj
 delete mode 100644 vs2022/xendisk/xendisk.vcxproj.user

diff --git a/msbuild.ps1 b/msbuild.ps1
index f904873..493aac9 100644
--- a/msbuild.ps1
+++ b/msbuild.ps1
@@ -18,7 +18,7 @@ param(
 #
 $SolutionName = "xenvbd.sln"
 $ArchivePath = "xenvbd"
-$ProjectList = @( "xencrsh", "xendisk", "xenvbd" )
+$ProjectList = @( "xencrsh", "xenvbd" )

 #
 # Functions
diff --git a/src/xendisk/assert.h b/src/xendisk/assert.h
deleted file mode 100644
index 6b17c12..0000000
--- a/src/xendisk/assert.h
+++ /dev/null
@@ -1,220 +0,0 @@
-/* Copyright (c) Xen Project.
- * Copyright (c) Cloud Software Group, 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 _XENDISK_ASSERT_H
-#define _XENDISK_ASSERT_H
-
-#include <ntddk.h>
-
-#include "debug.h"
-
-static FORCEINLINE VOID
-__BugCheck(
-    __in  ULONG       Code,
-    __in_opt ULONG_PTR   Parameter1,
-    __in_opt ULONG_PTR   Parameter2,
-    __in_opt ULONG_PTR   Parameter3,
-    __in_opt 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_MSG(_TEXT1, _TEXT2)                                 \
-        do {                                                    \
-            const CHAR  *_Text1 = (_TEXT1);                     \
-            const CHAR  *_Text2 = (_TEXT2);                     \
-            const CHAR  *_File = __FILE__;                      \
-            ULONG       _Line = __LINE__;                       \
-                                                                \
-            Error("BUG: " _TEXT1 " %s\n", _Text2);              \
-            __BugCheck(ASSERTION_FAILURE,                       \
-                       (ULONG_PTR)_Text1,                       \
-                       (ULONG_PTR)_File,                        \
-                       (ULONG_PTR)_Line,                        \
-                       (ULONG_PTR)_Text2);                      \
-        } while (FALSE)
-
-#define BUG_ON(_EXP)                           \
-        if (_EXP) BUG(#_EXP)
-
-#define BUG_ON_MSG(_EXP, _TEXT)                \
-        if (_EXP) BUG_MSG(#_EXP, _TEXT)
-
-#if DBG
-
-#define __NT_ASSERT(_EXP)                                       \
-        ((!(_EXP)) ?                                            \
-        (Error("ASSERTION FAILED: " #_EXP "\n"),                \
-         __annotation(L"Debug", L"AssertFail", L#_EXP),         \
-         DbgRaiseAssertionFailure(), FALSE) :                   \
-        TRUE)
-
-#define __NT_ASSERT_MSG(_EXP, _TEXT)                            \
-        ((!(_EXP)) ?                                            \
-        (Error("ASSERTION FAILED: " #_EXP " " #_TEXT "\n"),     \
-         __annotation(L"Debug", L"AssertFail", L#_EXP),         \
-         DbgRaiseAssertionFailure(), FALSE) :                   \
-        TRUE)
-
-#define __ASSERT(_EXP)              __NT_ASSERT(_EXP)
-#define __ASSERT_MSG(_EXP, _TEXT)   __NT_ASSERT_MSG(_EXP, _TEXT)
-
-#else   // DBG
-
-#define __ASSERT(_EXP)              BUG_ON(!(_EXP))
-#define __ASSERT_MSG(_EXP, _TEXT)   BUG_ON_MSG(!(_EXP), _TEXT)
-
-#endif  // DBG
-
-#undef  ASSERT
-
-#define ASSERT(_EXP)                    \
-        do {                            \
-            __ASSERT(_EXP);             \
-            __analysis_assume(_EXP);    \
-        } while (FALSE)
-
-#define ASSERT_MSG(_EXP, _TEXT)         \
-        do {                            \
-            __ASSERT_MSG(_EXP, _TEXT);  \
-            __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)
-
-#define ASSERTREFCOUNT(_X, _OP, _Y, _Z)             \
-        do {                                        \
-            LONG    _L = (LONG)(_X);                \
-            LONG    _R = (LONG)(_Y);                \
-            if (!(_L _OP _R)) {                     \
-                Error("%s:%s = %d\n", (_Z), #_X, _L); \
-                Error("%s:%s = %d\n", (_Z), #_Y, _R); \
-                ASSERT_MSG(_X _OP _Y, (_Z));        \
-            }                                       \
-        } while (FALSE)
-
-#ifndef TEST_MEMORY
-#define TEST_MEMORY DBG
-#endif
-
-#if TEST_MEMORY
-
-__checkReturn
-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  // _XENDISK_ASSERT_H
diff --git a/src/xendisk/debug.h b/src/xendisk/debug.h
deleted file mode 100644
index f921fec..0000000
--- a/src/xendisk/debug.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Copyright (c) Xen Project.
- * Copyright (c) Cloud Software Group, 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 _DEBUG_H
-#define _DEBUG_H
-
-#include <ntddk.h>
-#include <stdarg.h>
-
-#define stringify_literal(_text) #_text
-#define stringify(_text) stringify_literal(_text)
-#define __MODULE__ stringify(PROJECT)
-
-// DEBUG_FILTER_MASKs
-// Set these to see relevant output
-// ERROR        0x00000001
-// WARNING      0x00000002
-// TRACE        0x00000004
-// INFO         0x00000008
-
-#pragma warning(disable:4127)   // conditional expression is constant
-
-//
-// Debug Output and Logging
-//
-static __inline VOID
-__DebugMessage(
-    __in    ULONG       Level,
-    __in __nullterminated const CHAR  *Prefix,
-    __in __nullterminated const CHAR  *Format,
-    ...
-    )
-{
-    va_list         Arguments;
-
-    va_start(Arguments, Format);
-
-#pragma prefast(suppress:6001) // Using uninitialized memory
-    vDbgPrintExWithPrefix(Prefix,
-                          DPFLTR_IHVDRIVER_ID,
-                          Level,
-                          Format,
-                          Arguments);
-    va_end(Arguments);
-}
-
-#define Error(...)  \
-        __DebugMessage(DPFLTR_ERROR_LEVEL, __MODULE__ "|" __FUNCTION__ ":", 
__VA_ARGS__)
-
-#define Warning(...)  \
-        __DebugMessage(DPFLTR_WARNING_LEVEL, __MODULE__ "|" __FUNCTION__ ":", 
__VA_ARGS__)
-
-#if DBG
-#define Trace(...)  \
-        __DebugMessage(DPFLTR_TRACE_LEVEL, __MODULE__ "|" __FUNCTION__ ":", 
__VA_ARGS__)
-#else   // DBG
-#define Trace(...) \
-        (VOID)(__VA_ARGS__)
-#endif  // DBG
-
-#define Verbose(...) \
-        __DebugMessage(DPFLTR_INFO_LEVEL, __MODULE__ "|" __FUNCTION__ ":", 
__VA_ARGS__)
-
-#include "assert.h"
-
-#endif  // _DEBUG_H
diff --git a/src/xendisk/driver.c b/src/xendisk/driver.c
deleted file mode 100644
index e30b75c..0000000
--- a/src/xendisk/driver.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/* Copyright (c) Xen Project.
- * Copyright (c) Cloud Software Group, 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 "registry.h"
-#include "driver.h"
-#include "util.h"
-#include "debug.h"
-#include "assert.h"
-
-#include <version.h>
-
-typedef struct _XENDISK_DRIVER {
-    PDRIVER_OBJECT  DriverObject;
-    HANDLE          ParametersKey;
-} XENDISK_DRIVER, *PXENDISK_DRIVER;
-
-static XENDISK_DRIVER   Driver;
-
-static FORCEINLINE VOID
-__DriverSetDriverObject(
-    IN  PDRIVER_OBJECT  DriverObject
-    )
-{
-    Driver.DriverObject = DriverObject;
-}
-
-static FORCEINLINE PDRIVER_OBJECT
-__DriverGetDriverObject(
-    VOID
-    )
-{
-    return Driver.DriverObject;
-}
-
-PDRIVER_OBJECT
-DriverGetDriverObject(
-    VOID
-    )
-{
-    return __DriverGetDriverObject();
-}
-
-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
-    )
-{
-    HANDLE              ParametersKey;
-
-    ASSERT3P(DriverObject, ==, __DriverGetDriverObject());
-
-    Trace("====>\n");
-
-    ParametersKey = __DriverGetParametersKey();
-    __DriverSetParametersKey(NULL);
-
-    RegistryCloseKey(ParametersKey);
-
-    RegistryTeardown();
-
-    Verbose("XENDISK %d.%d.%d (%d) (%02d.%02d.%04d)\n",
-            MAJOR_VERSION,
-            MINOR_VERSION,
-            MICRO_VERSION,
-            BUILD_NUMBER,
-            DAY,
-            MONTH,
-            YEAR);
-
-    __DriverSetDriverObject(NULL);
-
-    ASSERT(IsZeroMemory(&Driver, sizeof (XENDISK_DRIVER)));
-
-    Trace("<====\n");
-}
-
-DRIVER_ADD_DEVICE   AddDevice;
-
-NTSTATUS
-#pragma prefast(suppress:28152) // Does not clear DO_DEVICE_INITIALIZING
-AddDevice(
-    IN  PDRIVER_OBJECT  DriverObject,
-    IN  PDEVICE_OBJECT  PhysicalDeviceObject
-    )
-{
-    NTSTATUS            status;
-
-    ASSERT3P(DriverObject, ==, __DriverGetDriverObject());
-
-    status = FdoCreate(PhysicalDeviceObject);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    return STATUS_SUCCESS;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
-}
-
-DRIVER_DISPATCH Dispatch;
-
-NTSTATUS
-Dispatch(
-    IN PDEVICE_OBJECT   DeviceObject,
-    IN PIRP             Irp
-    )
-{
-    PXENDISK_DX         Dx;
-    NTSTATUS            status;
-
-    Dx = (PXENDISK_DX)DeviceObject->DeviceExtension;
-    ASSERT3P(Dx->DeviceObject, ==, DeviceObject);
-
-    if (Dx->DevicePnpState == Deleted) {
-        PIO_STACK_LOCATION  StackLocation = IoGetCurrentIrpStackLocation(Irp);
-        UCHAR               MajorFunction = StackLocation->MajorFunction;
-        UCHAR               MinorFunction = StackLocation->MinorFunction;
-
-        status = STATUS_NO_SUCH_DEVICE;
-
-        if (MajorFunction == IRP_MJ_PNP) {
-            /* FDO and PDO deletions can block after being marked deleted, but 
before IoDeleteDevice */
-            if (MinorFunction == IRP_MN_SURPRISE_REMOVAL || MinorFunction == 
IRP_MN_REMOVE_DEVICE)
-                status = STATUS_SUCCESS;
-
-            ASSERT((MinorFunction != IRP_MN_CANCEL_REMOVE_DEVICE) && 
(MinorFunction != IRP_MN_CANCEL_STOP_DEVICE));
-        }
-
-        Irp->IoStatus.Status = status;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
-        goto done;
-    }
-
-    status = STATUS_NOT_SUPPORTED;
-    switch (Dx->Type) {
-    case PHYSICAL_DEVICE_OBJECT: {
-        PXENDISK_PDO    Pdo = Dx->Pdo;
-
-        status = PdoDispatch(Pdo, Irp);
-        break;
-    }
-    case FUNCTION_DEVICE_OBJECT: {
-        PXENDISK_FDO    Fdo = Dx->Fdo;
-
-        status = FdoDispatch(Fdo, Irp);
-        break;
-    }
-    default:
-        ASSERT(FALSE);
-        break;
-    }
-
-done:
-    return status;
-}
-
-DRIVER_INITIALIZE   DriverEntry;
-
-NTSTATUS
-DriverEntry(
-    IN  PDRIVER_OBJECT  DriverObject,
-    IN  PUNICODE_STRING RegistryPath
-    )
-{
-    HANDLE              ParametersKey;
-    ULONG               Index;
-    NTSTATUS            status;
-
-    ASSERT3P(__DriverGetDriverObject(), ==, NULL);
-    UNREFERENCED_PARAMETER(RegistryPath);
-
-    ExInitializeDriverRuntime(DrvRtPoolNxOptIn);
-
-    Trace("====>\n");
-
-    __DriverSetDriverObject(DriverObject);
-
-    DriverObject->DriverUnload = DriverUnload;
-
-    Verbose("XENDISK %d.%d.%d (%d) (%02d.%02d.%04d)\n",
-            MAJOR_VERSION,
-            MINOR_VERSION,
-            MICRO_VERSION,
-            BUILD_NUMBER,
-            DAY,
-            MONTH,
-            YEAR);
-
-    status = RegistryInitialize(DriverObject, RegistryPath);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status = RegistryOpenParametersKey(KEY_READ, &ParametersKey);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    __DriverSetParametersKey(ParametersKey);
-
-    DriverObject->DriverExtension->AddDevice = AddDevice;
-
-    for (Index = 0; Index <= IRP_MJ_MAXIMUM_FUNCTION; Index++) {
-#pragma prefast(suppress:28169) // No __drv_dispatchType annotation
-#pragma prefast(suppress:28168) // No matching __drv_dispatchType annotation 
for IRP_MJ_CREATE
-        DriverObject->MajorFunction[Index] = Dispatch;
-    }
-
-    Trace("<====\n");
-
-    return STATUS_SUCCESS;
-
-fail2:
-    Error("fail2\n");
-
-    RegistryTeardown();
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    __DriverSetDriverObject(NULL);
-
-    ASSERT(IsZeroMemory(&Driver, sizeof (XENDISK_DRIVER)));
-
-    return status;
-}
diff --git a/src/xendisk/driver.h b/src/xendisk/driver.h
deleted file mode 100644
index 7e2c20c..0000000
--- a/src/xendisk/driver.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Copyright (c) Xen Project.
- * Copyright (c) Cloud Software Group, 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 _XENDISK_DRIVER_H
-#define _XENDISK_DRIVER_H
-
-#include "fdo.h"
-#include "pdo.h"
-
-extern PDRIVER_OBJECT
-DriverGetDriverObject(
-    VOID
-    );
-
-extern HANDLE
-DriverGetParametersKey(
-    VOID
-    );
-
-#define MAX_DEVICE_ID_LEN   200
-
-#pragma warning(push)
-#pragma warning(disable:4201) // nonstandard extension used : nameless 
struct/union
-
-typedef struct _XENDISK_DX {
-    PDEVICE_OBJECT      DeviceObject;
-    DEVICE_OBJECT_TYPE  Type;
-
-    DEVICE_PNP_STATE    DevicePnpState;
-    DEVICE_PNP_STATE    PreviousDevicePnpState;
-
-    SYSTEM_POWER_STATE  SystemPowerState;
-    DEVICE_POWER_STATE  DevicePowerState;
-
-    IO_REMOVE_LOCK      RemoveLock;
-
-    LIST_ENTRY          ListEntry;
-
-    union {
-        PXENDISK_FDO    Fdo;
-        PXENDISK_PDO    Pdo;
-    };
-} XENDISK_DX, *PXENDISK_DX;
-
-#pragma warning(pop)
-
-#endif // _XENDISK_DRIVER_H
diff --git a/src/xendisk/fdo.c b/src/xendisk/fdo.c
deleted file mode 100644
index ef8b30d..0000000
--- a/src/xendisk/fdo.c
+++ /dev/null
@@ -1,1618 +0,0 @@
-/* Copyright (c) Xen Project.
- * Copyright (c) Cloud Software Group, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms,
- * with or without modification, are permitted provided
- * that the following conditions are met:
- *
- * *   Redistributions of source code must retain the above
- *     copyright notice, this list of conditions and the
- *     following disclaimer.
- * *   Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the
- *     following disclaimer in the documentation and/or other
- *     materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#define INITGUID 1
-
-#include <ntddk.h>
-#include <wdmguid.h>
-#include <ntstrsafe.h>
-#include <stdlib.h>
-#include <names.h>
-
-#include "driver.h"
-#include "fdo.h"
-#include "pdo.h"
-#include "thread.h"
-#include "mutex.h"
-#include "debug.h"
-#include "assert.h"
-#include "util.h"
-
-#define FDO_TAG 'ODF'
-
-struct _XENDISK_FDO {
-    PXENDISK_DX                     Dx;
-    PDEVICE_OBJECT                  LowerDeviceObject;
-    PDEVICE_OBJECT                  PhysicalDeviceObject;
-
-    MUTEX                           Mutex;
-    ULONG                           References;
-};
-
-static FORCEINLINE PVOID
-__FdoAllocate(
-    IN  ULONG   Length
-    )
-{
-    return __AllocatePoolWithTag(NonPagedPool, Length, FDO_TAG);
-}
-
-static FORCEINLINE VOID
-__FdoFree(
-    IN  PVOID   Buffer
-    )
-{
-    __FreePoolWithTag(Buffer, FDO_TAG);
-}
-
-static FORCEINLINE VOID
-__FdoSetDevicePnpState(
-    IN  PXENDISK_FDO        Fdo,
-    IN  DEVICE_PNP_STATE    State
-    )
-{
-    PXENDISK_DX             Dx = Fdo->Dx;
-
-    // We can never transition out of the deleted state
-    ASSERT(Dx->DevicePnpState != Deleted || State == Deleted);
-
-    Dx->PreviousDevicePnpState = Dx->DevicePnpState;
-    Dx->DevicePnpState = State;
-}
-
-static FORCEINLINE VOID
-__FdoRestoreDevicePnpState(
-    IN  PXENDISK_FDO        Fdo,
-    IN  DEVICE_PNP_STATE    State
-    )
-{
-    PXENDISK_DX             Dx = Fdo->Dx;
-
-    if (Dx->DevicePnpState == State)
-        Dx->DevicePnpState = Dx->PreviousDevicePnpState;
-}
-
-static FORCEINLINE DEVICE_PNP_STATE
-__FdoGetDevicePnpState(
-    IN  PXENDISK_FDO    Fdo
-    )
-{
-    PXENDISK_DX         Dx = Fdo->Dx;
-
-    return Dx->DevicePnpState;
-}
-
-static FORCEINLINE VOID
-__FdoSetDevicePowerState(
-    IN  PXENDISK_FDO        Fdo,
-    IN  DEVICE_POWER_STATE  State
-    )
-{
-    PXENDISK_DX             Dx = Fdo->Dx;
-
-    Dx->DevicePowerState = State;
-}
-
-static FORCEINLINE DEVICE_POWER_STATE
-__FdoGetDevicePowerState(
-    IN  PXENDISK_FDO    Fdo
-    )
-{
-    PXENDISK_DX         Dx = Fdo->Dx;
-
-    return Dx->DevicePowerState;
-}
-
-static FORCEINLINE VOID
-__FdoSetSystemPowerState(
-    IN  PXENDISK_FDO        Fdo,
-    IN  SYSTEM_POWER_STATE  State
-    )
-{
-    PXENDISK_DX              Dx = Fdo->Dx;
-
-    Dx->SystemPowerState = State;
-}
-
-static FORCEINLINE SYSTEM_POWER_STATE
-__FdoGetSystemPowerState(
-    IN  PXENDISK_FDO    Fdo
-    )
-{
-    PXENDISK_DX         Dx = Fdo->Dx;
-
-    return Dx->SystemPowerState;
-}
-
-static FORCEINLINE PDEVICE_OBJECT
-__FdoGetPhysicalDeviceObject(
-    IN  PXENDISK_FDO    Fdo
-    )
-{
-    return Fdo->PhysicalDeviceObject;
-}
-
-PDEVICE_OBJECT
-FdoGetPhysicalDeviceObject(
-    IN  PXENDISK_FDO    Fdo
-    )
-{
-    return __FdoGetPhysicalDeviceObject(Fdo);
-}
-
-VOID
-FdoAddPhysicalDeviceObject(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PDEVICE_OBJECT  DeviceObject
-    )
-{
-    PXENDISK_DX         Dx;
-
-    Dx = (PXENDISK_DX)DeviceObject->DeviceExtension;
-    ASSERT3U(Dx->Type, ==, PHYSICAL_DEVICE_OBJECT);
-
-    InsertTailList(&Fdo->Dx->ListEntry, &Dx->ListEntry);
-    ASSERT3U(Fdo->References, !=, 0);
-    Fdo->References++;
-}
-
-VOID
-FdoRemovePhysicalDeviceObject(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PDEVICE_OBJECT  DeviceObject
-    )
-{
-    PXENDISK_DX         Dx;
-
-    Dx = (PXENDISK_DX)DeviceObject->DeviceExtension;
-    ASSERT3U(Dx->Type, ==, PHYSICAL_DEVICE_OBJECT);
-
-    RemoveEntryList(&Dx->ListEntry);
-    ASSERT3U(Fdo->References, !=, 0);
-    --Fdo->References;
-}
-
-static FORCEINLINE VOID
-__FdoAcquireMutex(
-    IN  PXENDISK_FDO     Fdo
-    )
-{
-    AcquireMutex(&Fdo->Mutex);
-}
-
-VOID
-FdoAcquireMutex(
-    IN  PXENDISK_FDO     Fdo
-    )
-{
-    __FdoAcquireMutex(Fdo);
-}
-
-static FORCEINLINE VOID
-__FdoReleaseMutex(
-    IN  PXENDISK_FDO     Fdo
-    )
-{
-    ReleaseMutex(&Fdo->Mutex);
-}
-
-VOID
-FdoReleaseMutex(
-    IN  PXENDISK_FDO     Fdo
-    )
-{
-    __FdoReleaseMutex(Fdo);
-
-    if (Fdo->References == 0)
-        FdoDestroy(Fdo);
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-FdoQueryIdCompletion(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PKEVENT             Event = Context;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-    UNREFERENCED_PARAMETER(Irp);
-
-    KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
-
-    return STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-static NTSTATUS
-FdoQueryId(
-    IN  PXENDISK_FDO        Fdo,
-    IN  PDEVICE_OBJECT      DeviceObject,
-    IN  BUS_QUERY_ID_TYPE   Type,
-    OUT PCHAR               Id
-    )
-{
-    PIRP                    Irp;
-    KEVENT                  Event;
-    PIO_STACK_LOCATION      StackLocation;
-    NTSTATUS                status;
-
-    UNREFERENCED_PARAMETER(Fdo);
-
-    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
-
-    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 = Type;
-    StackLocation->DeviceObject = DeviceObject;
-    StackLocation->FileObject = NULL;
-
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
-    IoSetCompletionRoutine(Irp,
-                           FdoQueryIdCompletion,
-                           &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;
-
-    status = RtlStringCbPrintfA(Id,
-                                MAX_DEVICE_ID_LEN,
-                                "%ws",
-                                (PWCHAR)Irp->IoStatus.Information);
-    ASSERT(NT_SUCCESS(status));
-
-    ExFreePool((PVOID)Irp->IoStatus.Information);
-
-    IoFreeIrp(Irp);
-
-    return STATUS_SUCCESS;
-
-fail2:
-    IoFreeIrp(Irp);
-
-fail1:
-    return status;
-}
-
-static NTSTATUS
-FdoAddDevice(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PDEVICE_OBJECT  PhysicalDeviceObject
-    )
-{
-    CHAR                DeviceID[MAX_DEVICE_ID_LEN];
-    CHAR                InstanceID[MAX_DEVICE_ID_LEN];
-    NTSTATUS            status;
-
-    status = FdoQueryId(Fdo,
-                        PhysicalDeviceObject,
-                        BusQueryDeviceID,
-                        DeviceID);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status = FdoQueryId(Fdo,
-                        PhysicalDeviceObject,
-                        BusQueryInstanceID,
-                        InstanceID);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status = PdoCreate(Fdo,
-                       PhysicalDeviceObject,
-                       DeviceID,
-                       InstanceID);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    return STATUS_SUCCESS;
-
-fail3:
-fail2:
-fail1:
-    return status;
-}
-
-static FORCEINLINE VOID
-__FdoEnumerate(
-    IN  PXENDISK_FDO        Fdo,
-    IN  PDEVICE_RELATIONS   Relations
-    )
-{
-    PDEVICE_OBJECT          *PhysicalDeviceObject;
-    ULONG                   Count;
-    PLIST_ENTRY             ListEntry;
-    ULONG                   Index;
-    NTSTATUS                status;
-
-    Count = Relations->Count;
-    ASSERT(Count != 0);
-
-    PhysicalDeviceObject = __FdoAllocate(sizeof (PDEVICE_OBJECT) * Count);
-
-    status = STATUS_NO_MEMORY;
-    if (PhysicalDeviceObject == NULL)
-        goto fail1;
-
-    RtlCopyMemory(PhysicalDeviceObject,
-                  Relations->Objects,
-                  sizeof (PDEVICE_OBJECT) * Count);
-
-    // Remove any PDOs that do not appear in the device list
-    ListEntry = Fdo->Dx->ListEntry.Flink;
-    while (ListEntry != &Fdo->Dx->ListEntry) {
-        PLIST_ENTRY     Next = ListEntry->Flink;
-        PXENDISK_DX     Dx = CONTAINING_RECORD(ListEntry, XENDISK_DX, 
ListEntry);
-        PXENDISK_PDO    Pdo = Dx->Pdo;
-
-        for (Index = 0; Index < Count; Index++) {
-            if (PdoGetPhysicalDeviceObject(Pdo) == 
PhysicalDeviceObject[Index]) {
-#pragma prefast(suppress:6387)  // PhysicalDeviceObject[Index] could be NULL
-                PhysicalDeviceObject[Index] = NULL; // avoid duplication
-                break;
-            }
-        }
-
-        ListEntry = Next;
-    }
-
-    // Walk the list and create PDO filters for any new devices
-    for (Index = 0; Index < Count; Index++) {
-#pragma warning(suppress:6385)  // Reading invalid data from 
'PhysicalDeviceObject'
-        if (PhysicalDeviceObject[Index] != NULL) {
-            (VOID) FdoAddDevice(Fdo,
-                                PhysicalDeviceObject[Index]);
-        }
-    }
-
-    __FdoFree(PhysicalDeviceObject);
-    return;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__FdoForwardIrpSynchronously(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PKEVENT             Event = Context;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-    UNREFERENCED_PARAMETER(Irp);
-
-    KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
-
-    return STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-static NTSTATUS
-FdoForwardIrpSynchronously(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    KEVENT              Event;
-    NTSTATUS            status;
-
-    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
-
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoForwardIrpSynchronously,
-                           &Event,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-    if (status == STATUS_PENDING) {
-        (VOID) KeWaitForSingleObject(&Event,
-                                     Executive,
-                                     KernelMode,
-                                     FALSE,
-                                     NULL);
-        status = Irp->IoStatus.Status;
-    } else {
-        ASSERT3U(status, ==, Irp->IoStatus.Status);
-    }
-
-    return status;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-FdoStartDevice(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    POWER_STATE         PowerState;
-    NTSTATUS            status;
-
-    status = IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status = FdoForwardIrpSynchronously(Fdo, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    __FdoSetSystemPowerState(Fdo, PowerSystemWorking);
-    __FdoSetDevicePowerState(Fdo, PowerDeviceD0);
-
-    PowerState.DeviceState = PowerDeviceD0;
-    PoSetPowerState(Fdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
-
-    __FdoSetDevicePnpState(Fdo, Started);
-
-    IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-
-fail2:
-    Error("fail2\n");
-
-    IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__FdoQueryStopDevice(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_FDO        Fdo = Context;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-
-    return STATUS_SUCCESS;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-FdoQueryStopDevice(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    NTSTATUS            status;
-
-    status = IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    __FdoSetDevicePnpState(Fdo, StopPending);
-    Irp->IoStatus.Status = STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoQueryStopDevice,
-                           Fdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__FdoCancelStopDevice(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_FDO        Fdo = Context;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-
-    return STATUS_SUCCESS;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-FdoCancelStopDevice(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    NTSTATUS            status;
-
-    status = IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    Irp->IoStatus.Status = STATUS_SUCCESS;
-
-    __FdoRestoreDevicePnpState(Fdo, StopPending);
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoCancelStopDevice,
-                           Fdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__FdoStopDevice(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_FDO        Fdo = Context;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-
-    return STATUS_SUCCESS;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-FdoStopDevice(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    POWER_STATE         PowerState;
-    NTSTATUS            status;
-
-    status = IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    if (__FdoGetDevicePowerState(Fdo) != PowerDeviceD0)
-        goto done;
-
-    PowerState.DeviceState = PowerDeviceD3;
-    PoSetPowerState(Fdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
-
-    __FdoSetDevicePowerState(Fdo, PowerDeviceD3);
-    __FdoSetSystemPowerState(Fdo, PowerSystemShutdown);
-
-done:
-    __FdoSetDevicePnpState(Fdo, Stopped);
-    Irp->IoStatus.Status = STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoStopDevice,
-                           Fdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__FdoQueryRemoveDevice(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_FDO        Fdo = Context;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-
-    return STATUS_SUCCESS;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-FdoQueryRemoveDevice(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    NTSTATUS            status;
-
-    status = IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    __FdoSetDevicePnpState(Fdo, RemovePending);
-    Irp->IoStatus.Status = STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoQueryRemoveDevice,
-                           Fdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__FdoCancelRemoveDevice(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_FDO        Fdo = Context;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-
-    return STATUS_SUCCESS;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-FdoCancelRemoveDevice(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    NTSTATUS            status;
-
-    status = IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    __FdoRestoreDevicePnpState(Fdo, RemovePending);
-    Irp->IoStatus.Status = STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoCancelRemoveDevice,
-                           Fdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__FdoSurpriseRemoval(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_FDO        Fdo = Context;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-
-    return STATUS_SUCCESS;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-FdoSurpriseRemoval(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    NTSTATUS            status;
-
-    status = IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    __FdoSetDevicePnpState(Fdo, SurpriseRemovePending);
-    Irp->IoStatus.Status = STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoSurpriseRemoval,
-                           Fdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-FdoRemoveDevice(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    POWER_STATE         PowerState;
-    NTSTATUS            status;
-
-    status = IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    if (__FdoGetDevicePowerState(Fdo) != PowerDeviceD0)
-        goto done;
-
-    PowerState.DeviceState = PowerDeviceD3;
-    PoSetPowerState(Fdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
-
-    __FdoSetDevicePowerState(Fdo, PowerDeviceD3);
-    __FdoSetSystemPowerState(Fdo, PowerSystemShutdown);
-
-done:
-    __FdoSetDevicePnpState(Fdo, Deleted);
-
-    IoReleaseRemoveLockAndWait(&Fdo->Dx->RemoveLock, Irp);
-
-    status = FdoForwardIrpSynchronously(Fdo, Irp);
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    __FdoAcquireMutex(Fdo);
-    ASSERT3U(Fdo->References, !=, 0);
-    --Fdo->References;
-    __FdoReleaseMutex(Fdo);
-
-    if (Fdo->References == 0)
-        FdoDestroy(Fdo);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__FdoQueryDeviceRelations(
-    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 DECLSPEC_NOINLINE NTSTATUS
-FdoQueryDeviceRelations(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    KEVENT              Event;
-    PIO_STACK_LOCATION  StackLocation;
-    PDEVICE_RELATIONS   Relations;
-    PLIST_ENTRY         ListEntry;
-    NTSTATUS            status;
-
-    status = IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoQueryDeviceRelations,
-                           &Event,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-    if (status == STATUS_PENDING) {
-        (VOID) KeWaitForSingleObject(&Event,
-                                     Executive,
-                                     KernelMode,
-                                     FALSE,
-                                     NULL);
-        status = Irp->IoStatus.Status;
-    } else {
-        ASSERT3U(status, ==, Irp->IoStatus.Status);
-    }
-
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    if (StackLocation->Parameters.QueryDeviceRelations.Type != BusRelations)
-        goto done;
-
-    Relations = (PDEVICE_RELATIONS)Irp->IoStatus.Information;
-
-    __FdoAcquireMutex(Fdo);
-
-    if (Relations->Count != 0)
-        __FdoEnumerate(Fdo, Relations);
-
-    for (ListEntry = Fdo->Dx->ListEntry.Flink;
-         ListEntry != &Fdo->Dx->ListEntry;
-         ListEntry = ListEntry->Flink) {
-        PXENDISK_DX     Dx = CONTAINING_RECORD(ListEntry, XENDISK_DX, 
ListEntry);
-        PXENDISK_PDO    Pdo = Dx->Pdo;
-
-        ASSERT3U(Dx->Type, ==, PHYSICAL_DEVICE_OBJECT);
-
-        if (PdoGetDevicePnpState(Pdo) == Present)
-            PdoSetDevicePnpState(Pdo, Enumerated);
-    }
-
-    __FdoReleaseMutex(Fdo);
-
-    Trace("%d PDO(s)\n", Relations->Count);
-
-    status = STATUS_SUCCESS;
-
-done:
-    IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-
-fail2:
-    IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-
-fail1:
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__FdoDispatchPnp(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_FDO        Fdo = Context;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    return STATUS_SUCCESS;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-FdoDispatchPnp(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    UCHAR               MinorFunction;
-    NTSTATUS            status;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    MinorFunction = StackLocation->MinorFunction;
-
-    switch (StackLocation->MinorFunction) {
-    case IRP_MN_START_DEVICE:
-        status = FdoStartDevice(Fdo, Irp);
-        break;
-
-    case IRP_MN_QUERY_STOP_DEVICE:
-        status = FdoQueryStopDevice(Fdo, Irp);
-        break;
-
-    case IRP_MN_CANCEL_STOP_DEVICE:
-        status = FdoCancelStopDevice(Fdo, Irp);
-        break;
-
-    case IRP_MN_STOP_DEVICE:
-        status = FdoStopDevice(Fdo, Irp);
-        break;
-
-    case IRP_MN_QUERY_REMOVE_DEVICE:
-        status = FdoQueryRemoveDevice(Fdo, Irp);
-        break;
-
-    case IRP_MN_SURPRISE_REMOVAL:
-        status = FdoSurpriseRemoval(Fdo, Irp);
-        break;
-
-    case IRP_MN_REMOVE_DEVICE:
-        status = FdoRemoveDevice(Fdo, Irp);
-        break;
-
-    case IRP_MN_CANCEL_REMOVE_DEVICE:
-        status = FdoCancelRemoveDevice(Fdo, Irp);
-        break;
-
-    case IRP_MN_QUERY_DEVICE_RELATIONS:
-        status = FdoQueryDeviceRelations(Fdo, Irp);
-        break;
-
-    default:
-        status = IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-        if (!NT_SUCCESS(status))
-            goto fail1;
-
-        IoCopyCurrentIrpStackLocationToNext(Irp);
-        IoSetCompletionRoutine(Irp,
-                               __FdoDispatchPnp,
-                               Fdo,
-                               TRUE,
-                               TRUE,
-                               TRUE);
-
-        status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-        break;
-    }
-
-    return status;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-FdoSetDevicePowerUpComplete(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_FDO        Fdo = (PXENDISK_FDO) Context;
-    PIO_STACK_LOCATION  StackLocation;
-    POWER_STATE         PowerState;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    PowerState = StackLocation->Parameters.Power.State;
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    __FdoSetDevicePowerState(Fdo, PowerState.DeviceState);
-    PoSetPowerState(Fdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
-
-    return STATUS_CONTINUE_COMPLETION;
-}
-
-static FORCEINLINE NTSTATUS
-__FdoSetDevicePowerUp(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           FdoSetDevicePowerUpComplete,
-                           Fdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    return IoCallDriver(Fdo->LowerDeviceObject, Irp);
-}
-
-static FORCEINLINE NTSTATUS
-__FdoSetDevicePowerDown(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    POWER_STATE         PowerState;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    PowerState = StackLocation->Parameters.Power.State;
-
-    __FdoSetDevicePowerState(Fdo, PowerState.DeviceState);
-    PoSetPowerState(Fdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
-
-    IoSkipCurrentIrpStackLocation(Irp);
-    return IoCallDriver(Fdo->LowerDeviceObject, Irp);
-}
-
-/* IRQL argnostic code, just mark power states.*/
-static FORCEINLINE NTSTATUS
-__FdoSetDevicePower(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    DEVICE_POWER_STATE  DeviceState;
-    POWER_ACTION        PowerAction;
-    NTSTATUS            status;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    DeviceState = StackLocation->Parameters.Power.State.DeviceState;
-    PowerAction = StackLocation->Parameters.Power.ShutdownType;
-
-    Trace("====> (%s:%s)\n",
-          PowerDeviceStateName(DeviceState),
-          PowerActionName(PowerAction));
-
-    if (DeviceState == __FdoGetDevicePowerState(Fdo)) {
-        IoSkipCurrentIrpStackLocation(Irp);
-        status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-        goto done;
-    }
-
-    status = (DeviceState < __FdoGetDevicePowerState(Fdo)) ?
-             __FdoSetDevicePowerUp(Fdo, Irp) :
-             __FdoSetDevicePowerDown(Fdo, Irp);
-
-done:
-    Trace("<==== (%s:%s)(%08x)\n",
-          PowerDeviceStateName(DeviceState),
-          PowerActionName(PowerAction),
-          status);
-
-    return status;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-FdoSetSystemPowerUpComplete(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_FDO        Fdo = (PXENDISK_FDO) Context;
-    PIO_STACK_LOCATION  StackLocation;
-    SYSTEM_POWER_STATE  SystemState;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    SystemState = StackLocation->Parameters.Power.State.SystemState;
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    __FdoSetSystemPowerState(Fdo, SystemState);
-
-    return STATUS_CONTINUE_COMPLETION;
-}
-
-static FORCEINLINE NTSTATUS
-__FdoSetSystemPowerUp(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           FdoSetSystemPowerUpComplete,
-                           Fdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    return IoCallDriver(Fdo->LowerDeviceObject, Irp);
-}
-
-static FORCEINLINE NTSTATUS
-__FdoSetSystemPowerDown(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    SYSTEM_POWER_STATE  SystemState;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    SystemState = StackLocation->Parameters.Power.State.SystemState;
-
-    __FdoSetSystemPowerState(Fdo, SystemState);
-
-    IoSkipCurrentIrpStackLocation(Irp);
-    return IoCallDriver(Fdo->LowerDeviceObject, Irp);
-}
-
-static FORCEINLINE NTSTATUS
-__FdoSetSystemPower(
-    IN  PXENDISK_FDO     Fdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    SYSTEM_POWER_STATE  SystemState;
-    POWER_ACTION        PowerAction;
-    NTSTATUS            status;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    SystemState = StackLocation->Parameters.Power.State.SystemState;
-    PowerAction = StackLocation->Parameters.Power.ShutdownType;
-
-    Trace("====> (%s:%s)\n",
-          PowerSystemStateName(SystemState),
-          PowerActionName(PowerAction));
-
-    if (SystemState == __FdoGetSystemPowerState(Fdo)) {
-        IoSkipCurrentIrpStackLocation(Irp);
-        status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-        goto done;
-    }
-
-    status = (SystemState < __FdoGetSystemPowerState(Fdo)) ?
-             __FdoSetSystemPowerUp(Fdo, Irp) :
-             __FdoSetSystemPowerDown(Fdo, Irp);
-
-done:
-    Trace("<==== (%s:%s)(%08x)\n",
-          PowerSystemStateName(SystemState),
-          PowerActionName(PowerAction),
-          status);
-
-    return status;
-}
-
-static NTSTATUS
-FdoDevicePower(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    NTSTATUS            status;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-
-    switch (StackLocation->MinorFunction) {
-    case IRP_MN_SET_POWER:
-        status = __FdoSetDevicePower(Fdo, Irp);
-        break;
-
-    default:
-        IoSkipCurrentIrpStackLocation(Irp);
-        status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-        break;
-    }
-
-    return status;
-}
-
-static NTSTATUS
-FdoSystemPower(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    NTSTATUS            status;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-
-    switch (StackLocation->MinorFunction) {
-    case IRP_MN_SET_POWER:
-        status = __FdoSetSystemPower(Fdo, Irp);
-        break;
-
-    default:
-        IoSkipCurrentIrpStackLocation(Irp);
-        status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-        break;
-    }
-
-    return status;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-FdoDispatchPower(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    POWER_STATE_TYPE    PowerType;
-    NTSTATUS            status;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    PowerType = StackLocation->Parameters.Power.Type;
-
-    switch (PowerType) {
-    case DevicePowerState:
-        status = FdoDevicePower(Fdo, Irp);
-        break;
-
-    case SystemPowerState:
-        status = FdoSystemPower(Fdo, Irp);
-        break;
-
-    default:
-        IoSkipCurrentIrpStackLocation(Irp);
-        status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-        break;
-    }
-
-    return status;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__FdoDispatchDefault(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_FDO        Fdo = Context;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-
-    return STATUS_SUCCESS;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-FdoDispatchDefault(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    NTSTATUS            status;
-
-    status = IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoDispatchDefault,
-                           Fdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-NTSTATUS
-FdoDispatch(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    NTSTATUS            status;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-
-    switch (StackLocation->MajorFunction) {
-    case IRP_MJ_PNP:
-        status = FdoDispatchPnp(Fdo, Irp);
-        break;
-
-    case IRP_MJ_POWER:
-        status = FdoDispatchPower(Fdo, Irp);
-        break;
-
-    default:
-        status = FdoDispatchDefault(Fdo, Irp);
-        break;
-    }
-
-    return status;
-}
-
-NTSTATUS
-FdoCreate(
-    IN  PDEVICE_OBJECT  PhysicalDeviceObject
-    )
-{
-    PDEVICE_OBJECT      LowerDeviceObject;
-    ULONG               DeviceType;
-    PDEVICE_OBJECT      FilterDeviceObject;
-    PXENDISK_DX         Dx;
-    PXENDISK_FDO        Fdo;
-    NTSTATUS            status;
-
-    LowerDeviceObject = IoGetAttachedDeviceReference(PhysicalDeviceObject);
-    DeviceType = LowerDeviceObject->DeviceType;
-    ObDereferenceObject(LowerDeviceObject);
-
-#pragma prefast(suppress:28197) // Possibly leaking memory 'FilterDeviceObject'
-    status = IoCreateDevice(DriverGetDriverObject(),
-                            sizeof (XENDISK_DX),
-                            NULL,
-                            DeviceType,
-                            FILE_DEVICE_SECURE_OPEN,
-                            FALSE,
-                            &FilterDeviceObject);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    Dx = (PXENDISK_DX)FilterDeviceObject->DeviceExtension;
-    RtlZeroMemory(Dx, sizeof (XENDISK_DX));
-
-    Dx->Type = FUNCTION_DEVICE_OBJECT;
-    Dx->DeviceObject = FilterDeviceObject;
-    Dx->DevicePnpState = Added;
-    Dx->SystemPowerState = PowerSystemShutdown;
-    Dx->DevicePowerState = PowerDeviceD3;
-
-    IoInitializeRemoveLock(&Dx->RemoveLock, FDO_TAG, 0, 0);
-
-    Fdo = __FdoAllocate(sizeof (XENDISK_FDO));
-
-    status = STATUS_NO_MEMORY;
-    if (Fdo == NULL)
-        goto fail2;
-
-    LowerDeviceObject = IoAttachDeviceToDeviceStack(FilterDeviceObject,
-                                                    PhysicalDeviceObject);
-
-    status = STATUS_UNSUCCESSFUL;
-    if (LowerDeviceObject == NULL)
-        goto fail3;
-
-    Fdo->Dx = Dx;
-    Fdo->PhysicalDeviceObject = PhysicalDeviceObject;
-    Fdo->LowerDeviceObject = LowerDeviceObject;
-
-    InitializeMutex(&Fdo->Mutex);
-    InitializeListHead(&Dx->ListEntry);
-    Fdo->References = 1;
-
-    Verbose("%p\n", FilterDeviceObject);
-
-    Dx->Fdo = Fdo;
-
-#pragma prefast(suppress:28182)  // Dereferencing NULL pointer
-    FilterDeviceObject->DeviceType = LowerDeviceObject->DeviceType;
-    FilterDeviceObject->Characteristics = LowerDeviceObject->Characteristics;
-
-    FilterDeviceObject->Flags |= LowerDeviceObject->Flags;
-    FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
-
-    return STATUS_SUCCESS;
-
-fail3:
-    Error("fail3\n");
-
-    ASSERT(IsZeroMemory(Fdo, sizeof (XENDISK_FDO)));
-    __FdoFree(Fdo);
-
-fail2:
-    Error("fail2\n");
-
-    IoDeleteDevice(FilterDeviceObject);
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
-}
-
-VOID
-FdoDestroy(
-    IN  PXENDISK_FDO    Fdo
-    )
-{
-    PDEVICE_OBJECT      LowerDeviceObject = Fdo->LowerDeviceObject;
-    PXENDISK_DX         Dx = Fdo->Dx;
-    PDEVICE_OBJECT      FilterDeviceObject = Dx->DeviceObject;
-
-    ASSERT(IsListEmpty(&Dx->ListEntry));
-    ASSERT3U(Fdo->References, ==, 0);
-    ASSERT3U(__FdoGetDevicePnpState(Fdo), ==, Deleted);
-
-    Dx->Fdo = NULL;
-
-    RtlZeroMemory(&Fdo->Mutex, sizeof (MUTEX));
-
-    Fdo->LowerDeviceObject = NULL;
-    Fdo->PhysicalDeviceObject = NULL;
-    Fdo->Dx = NULL;
-
-    IoDetachDevice(LowerDeviceObject);
-
-    ASSERT(IsZeroMemory(Fdo, sizeof (XENDISK_FDO)));
-    __FdoFree(Fdo);
-
-    IoDeleteDevice(FilterDeviceObject);
-}
diff --git a/src/xendisk/fdo.h b/src/xendisk/fdo.h
deleted file mode 100644
index dad27ea..0000000
--- a/src/xendisk/fdo.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* Copyright (c) Xen Project.
- * Copyright (c) Cloud Software Group, 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 _XENDISK_FDO_H
-#define _XENDISK_FDO_H
-
-#include <ntddk.h>
-#include "types.h"
-
-typedef struct _XENDISK_FDO XENDISK_FDO, *PXENDISK_FDO;
-
-extern VOID
-FdoAddPhysicalDeviceObject(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PDEVICE_OBJECT  DeviceObject
-    );
-
-extern VOID
-FdoRemovePhysicalDeviceObject(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PDEVICE_OBJECT  DeviceObject
-    );
-
-extern VOID
-FdoAcquireMutex(
-    IN  PXENDISK_FDO     Fdo
-    );
-
-extern VOID
-FdoReleaseMutex(
-    IN  PXENDISK_FDO     Fdo
-    );
-
-extern PDEVICE_OBJECT
-FdoGetPhysicalDeviceObject(
-    IN  PXENDISK_FDO    Fdo
-    );
-
-extern NTSTATUS
-FdoDispatch(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    );
-
-extern NTSTATUS
-FdoCreate(
-    IN  PDEVICE_OBJECT  PhysicalDeviceObject
-    );
-
-extern VOID
-FdoDestroy(
-    IN  PXENDISK_FDO    Fdo
-    );
-
-#endif // _XENDISK_FDO_H
diff --git a/src/xendisk/mutex.h b/src/xendisk/mutex.h
deleted file mode 100644
index e8a82ba..0000000
--- a/src/xendisk/mutex.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/* Copyright (c) Xen Project.
- * Copyright (c) Cloud Software Group, 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 _XENDISK_MUTEX_H
-#define _XENDISK_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 BOOLEAN
-__drv_maxIRQL(PASSIVE_LEVEL)
-TryAcquireMutex(
-    IN  PMUTEX      Mutex
-    )
-{
-    LARGE_INTEGER   Timeout;
-    NTSTATUS        status;
-
-    Timeout.QuadPart = 0;
-
-    status = KeWaitForSingleObject(&Mutex->Event,
-                                   Executive,
-                                   KernelMode,
-                                   FALSE,
-                                   &Timeout);
-    if (status == STATUS_TIMEOUT)
-        return FALSE;
-
-    ASSERT(NT_SUCCESS(status));
-
-    ASSERT3P(Mutex->Owner, ==, NULL);
-    Mutex->Owner = KeGetCurrentThread();
-
-    return TRUE;
-}
-
-static FORCEINLINE VOID
-__drv_maxIRQL(PASSIVE_LEVEL)
-AcquireMutex(
-    IN  PMUTEX  Mutex
-    )
-{
-    NTSTATUS    status;
-
-    status = KeWaitForSingleObject(&Mutex->Event,
-                                   Executive,
-                                   KernelMode,
-                                   FALSE,
-                                   NULL);
-
-    ASSERT(NT_SUCCESS(status));
-
-    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  // _XENDISK_MUTEX_H
diff --git a/src/xendisk/pdo.c b/src/xendisk/pdo.c
deleted file mode 100644
index 9ff8733..0000000
--- a/src/xendisk/pdo.c
+++ /dev/null
@@ -1,2000 +0,0 @@
-/* Copyright (c) Xen Project.
- * Copyright (c) Cloud Software Group, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms,
- * with or without modification, are permitted provided
- * that the following conditions are met:
- *
- * *   Redistributions of source code must retain the above
- *     copyright notice, this list of conditions and the
- *     following disclaimer.
- * *   Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the
- *     following disclaimer in the documentation and/or other
- *     materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#define INITGUID 1
-
-#include <ntddk.h>
-#include <wdmguid.h>
-#include <ntstrsafe.h>
-#include <stdlib.h>
-#include <storport.h>
-#include <Ntddstor.h>
-#include <Ntddscsi.h>
-#include <names.h>
-
-#include "fdo.h"
-#include "pdo.h"
-#include "driver.h"
-#include "registry.h"
-#include "thread.h"
-#include "debug.h"
-#include "assert.h"
-#include "util.h"
-
-#define PDO_TAG 'ODP'
-
-#define MAXNAMELEN  128
-
-struct _XENDISK_PDO {
-    PXENDISK_DX                 Dx;
-    PDEVICE_OBJECT              LowerDeviceObject;
-    PDEVICE_OBJECT              PhysicalDeviceObject;
-    CHAR                        Name[MAXNAMELEN];
-
-    PXENDISK_FDO                Fdo;
-
-    BOOLEAN                     InterceptTrim;
-    BOOLEAN                     DiscardSupported;
-    ULONG                       SectorSize;
-    ULONG                       PhysSectorSize;
-};
-
-static FORCEINLINE PVOID
-__PdoAllocate(
-    IN  ULONG   Length
-    )
-{
-    return __AllocatePoolWithTag(NonPagedPool, Length, PDO_TAG);
-}
-
-static FORCEINLINE VOID
-__PdoFree(
-    IN  PVOID   Buffer
-    )
-{
-    __FreePoolWithTag(Buffer, PDO_TAG);
-}
-
-static FORCEINLINE VOID
-__PdoSetDevicePnpState(
-    IN  PXENDISK_PDO        Pdo,
-    IN  DEVICE_PNP_STATE    State
-    )
-{
-    PXENDISK_DX             Dx = Pdo->Dx;
-
-    // We can never transition out of the deleted state
-    ASSERT(Dx->DevicePnpState != Deleted || State == Deleted);
-
-    Dx->PreviousDevicePnpState = Dx->DevicePnpState;
-    Dx->DevicePnpState = State;
-}
-
-VOID
-PdoSetDevicePnpState(
-    IN  PXENDISK_PDO        Pdo,
-    IN  DEVICE_PNP_STATE    State
-    )
-{
-    __PdoSetDevicePnpState(Pdo, State);
-}
-
-static FORCEINLINE VOID
-__PdoRestoreDevicePnpState(
-    IN  PXENDISK_PDO        Pdo,
-    IN  DEVICE_PNP_STATE    State
-    )
-{
-    PXENDISK_DX             Dx = Pdo->Dx;
-
-    if (Dx->DevicePnpState == State)
-        Dx->DevicePnpState = Dx->PreviousDevicePnpState;
-}
-
-static FORCEINLINE DEVICE_PNP_STATE
-__PdoGetDevicePnpState(
-    IN  PXENDISK_PDO    Pdo
-    )
-{
-    PXENDISK_DX         Dx = Pdo->Dx;
-
-    return Dx->DevicePnpState;
-}
-
-DEVICE_PNP_STATE
-PdoGetDevicePnpState(
-    IN  PXENDISK_PDO    Pdo
-    )
-{
-    return __PdoGetDevicePnpState(Pdo);
-}
-
-static FORCEINLINE VOID
-__PdoSetDevicePowerState(
-    IN  PXENDISK_PDO        Pdo,
-    IN  DEVICE_POWER_STATE  State
-    )
-{
-    PXENDISK_DX             Dx = Pdo->Dx;
-
-    Dx->DevicePowerState = State;
-}
-
-static FORCEINLINE DEVICE_POWER_STATE
-__PdoGetDevicePowerState(
-    IN  PXENDISK_PDO    Pdo
-    )
-{
-    PXENDISK_DX         Dx = Pdo->Dx;
-
-    return Dx->DevicePowerState;
-}
-
-static FORCEINLINE VOID
-__PdoSetSystemPowerState(
-    IN  PXENDISK_PDO        Pdo,
-    IN  SYSTEM_POWER_STATE  State
-    )
-{
-    PXENDISK_DX             Dx = Pdo->Dx;
-
-    Dx->SystemPowerState = State;
-}
-
-static FORCEINLINE SYSTEM_POWER_STATE
-__PdoGetSystemPowerState(
-    IN  PXENDISK_PDO    Pdo
-    )
-{
-    PXENDISK_DX         Dx = Pdo->Dx;
-
-    return Dx->SystemPowerState;
-}
-
-PDEVICE_OBJECT
-PdoGetPhysicalDeviceObject(
-    IN  PXENDISK_PDO    Pdo
-    )
-{
-    return Pdo->PhysicalDeviceObject;
-}
-
-static FORCEINLINE VOID
-__PdoLink(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PXENDISK_FDO    Fdo
-    )
-{
-    Pdo->Fdo = Fdo;
-    FdoAddPhysicalDeviceObject(Fdo, Pdo->Dx->DeviceObject);
-}
-
-static FORCEINLINE VOID
-__PdoUnlink(
-    IN  PXENDISK_PDO    Pdo
-    )
-{
-    PXENDISK_FDO        Fdo = Pdo->Fdo;
-
-    ASSERT(Fdo != NULL);
-
-    FdoRemovePhysicalDeviceObject(Fdo, Pdo->Dx->DeviceObject);
-
-    Pdo->Fdo = NULL;
-}
-
-static FORCEINLINE PXENDISK_FDO
-__PdoGetFdo(
-    IN  PXENDISK_PDO Pdo
-    )
-{
-    return Pdo->Fdo;
-}
-
-static FORCEINLINE VOID
-__PdoSetName(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PCHAR           DeviceID,
-    IN  PCHAR           InstanceID
-    )
-{
-    NTSTATUS            status;
-
-    status = RtlStringCbPrintfA(Pdo->Name,
-                                MAXNAMELEN,
-                                "%s\\%s",
-                                DeviceID,
-                                InstanceID);
-    ASSERT(NT_SUCCESS(status));
-}
-
-static FORCEINLINE PCHAR
-__PdoGetName(
-    IN  PXENDISK_PDO    Pdo
-    )
-{
-    return Pdo->Name;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__PdoForwardIrpSynchronously(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PKEVENT             Event = Context;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-    UNREFERENCED_PARAMETER(Irp);
-
-    KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
-
-    return STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-static NTSTATUS
-PdoForwardIrpSynchronously(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    KEVENT              Event;
-    NTSTATUS            status;
-
-    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
-
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __PdoForwardIrpSynchronously,
-                           &Event,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
-    if (status == STATUS_PENDING) {
-        (VOID) KeWaitForSingleObject(&Event,
-                                     Executive,
-                                     KernelMode,
-                                     FALSE,
-                                     NULL);
-        status = Irp->IoStatus.Status;
-    } else {
-        ASSERT3U(status, ==, Irp->IoStatus.Status);
-    }
-
-    return status;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__PdoForwardIrpAndForget(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_PDO        Pdo = Context;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-
-    return STATUS_SUCCESS;
-}
-
-static NTSTATUS
-PdoForwardIrpAndForget(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                            __PdoForwardIrpAndForget,
-                            Pdo,
-                            TRUE,
-                            TRUE,
-                            TRUE);
-
-    return IoCallDriver(Pdo->LowerDeviceObject, Irp);
-}
-
-static NTSTATUS
-PdoCompleteIrp(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp,
-    IN  NTSTATUS        Status
-    )
-{
-    Irp->IoStatus.Status = Status;
-    IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-    return Status;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__PdoSendAwaitSrb(
-    IN  PDEVICE_OBJECT          DeviceObject,
-    IN  PIRP                    Irp,
-    IN  PVOID                   Context
-    )
-{
-    UNREFERENCED_PARAMETER(DeviceObject);
-    UNREFERENCED_PARAMETER(Context);
-
-    *(Irp->UserIosb) = Irp->IoStatus;
-
-    if (Irp->MdlAddress) {
-        MmUnlockPages(Irp->MdlAddress);
-        IoFreeMdl(Irp->MdlAddress);
-    }
-
-    KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, FALSE);
-
-    IoFreeIrp(Irp);
-    return STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-static NTSTATUS
-PdoSendAwaitSrb(
-    IN  PXENDISK_PDO            Pdo,
-    IN  PSCSI_REQUEST_BLOCK     Srb
-    )
-{
-    PIRP                        Irp;
-    IO_STATUS_BLOCK             IoStatus;
-    KEVENT                      Event;
-    PIO_STACK_LOCATION          Stack;
-    NTSTATUS                    status;
-
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
-    status = STATUS_NO_MEMORY;
-    Irp = IoAllocateIrp((CCHAR)(Pdo->LowerDeviceObject->StackSize + 1), FALSE);
-    if (Irp == NULL)
-        goto fail1;
-
-    Stack = IoGetNextIrpStackLocation(Irp);
-    Stack->MajorFunction = IRP_MJ_SCSI;
-    Stack->Parameters.Scsi.Srb = Srb;
-
-    IoSetCompletionRoutine(Irp,
-                            __PdoSendAwaitSrb,
-                            Srb,
-                            TRUE,
-                            TRUE,
-                            TRUE);
-    Irp->UserIosb = &IoStatus;
-    Irp->UserEvent = &Event;
-
-    Irp->MdlAddress = IoAllocateMdl(Srb->DataBuffer,
-                                    Srb->DataTransferLength,
-                                    FALSE,
-                                    FALSE,
-                                    Irp);
-    if (Irp->MdlAddress == NULL)
-        goto fail2;
-
-#pragma warning(disable:6320)
-    __try {
-        MmProbeAndLockPages(Irp->MdlAddress, KernelMode, IoWriteAccess);
-    } __except (EXCEPTION_EXECUTE_HANDLER) {
-        status = GetExceptionCode();
-
-        goto fail3;
-    }
-#pragma warning(default:6320)
-
-    Srb->OriginalRequest = Irp;
-
-    status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
-    if (status == STATUS_PENDING) {
-        (VOID) KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, 
NULL);
-        status = IoStatus.Status;
-    }
-
-    return status;
-
-fail3:
-    Error("fail3\n");
-
-    IoFreeMdl(Irp->MdlAddress);
-
-fail2:
-    Error("fail2\n");
-
-    IoFreeIrp(Irp);
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
-}
-
-static NTSTATUS
-PdoSendReadCapacity16Synchronous(
-    IN  PXENDISK_PDO        Pdo,
-    OUT PULONG              SectorSize,
-    OUT PULONG              PhysSectorSize,
-    OUT PULONG64            SectorCount
-    )
-{
-    SCSI_REQUEST_BLOCK       Srb;
-    PCDB                     Cdb;
-    PREAD_CAPACITY16_DATA    Capacity;
-    ULONG                    Length;
-    NTSTATUS                 status;
-
-    Trace("====>\n");
-
-    Length = sizeof(READ_CAPACITY16_DATA);
-
-    status = STATUS_NO_MEMORY;
-    Capacity = __PdoAllocate(Length);
-    if (Capacity == NULL)
-        goto fail1;
-
-    RtlZeroMemory(&Srb, sizeof(SCSI_REQUEST_BLOCK));
-    Srb.Length = sizeof(SCSI_REQUEST_BLOCK);
-    Srb.SrbFlags = 0;
-    Srb.Function = SRB_FUNCTION_EXECUTE_SCSI;
-    Srb.DataBuffer = Capacity;
-    Srb.DataTransferLength = Length;
-    Srb.TimeOutValue = (ULONG)-1;
-    Srb.CdbLength = 16;
-
-    Cdb = (PCDB)&Srb.Cdb[0];
-    Cdb->READ_CAPACITY16.OperationCode = SCSIOP_READ_CAPACITY16;
-    Cdb->READ_CAPACITY16.ServiceAction = SERVICE_ACTION_READ_CAPACITY16;
-    *(PULONG)Cdb->READ_CAPACITY16.AllocationLength = _byteswap_ulong(Length);
-
-    status = PdoSendAwaitSrb(Pdo, &Srb);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status = STATUS_UNSUCCESSFUL;
-    if (Srb.DataTransferLength < Length)
-        goto fail3;
-
-    *SectorSize = _byteswap_ulong(Capacity->BytesPerBlock);
-    *PhysSectorSize = *SectorSize << Capacity->LogicalPerPhysicalExponent;
-    *SectorCount = _byteswap_uint64(Capacity->LogicalBlockAddress.QuadPart) + 
1;
-
-    __PdoFree(Capacity);
-
-    Trace("<====\n");
-    return STATUS_SUCCESS;
-
-fail3:
-    Error("fail3\n");
-
-fail2:
-    Error("fail2\n");
-
-    __PdoFree(Capacity);
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
-}
-
-static NTSTATUS
-PdoSendInquiryB0Synchronous(
-    IN  PXENDISK_PDO        Pdo,
-    OUT PBOOLEAN            Supported
-    )
-{
-    SCSI_REQUEST_BLOCK      Srb;
-    PCDB                    Cdb;
-    PVPD_BLOCK_LIMITS_PAGE  BlockLimits;
-    ULONG                   Length;
-    NTSTATUS                status;
-
-    Trace("====>\n");
-
-    Length = sizeof(VPD_BLOCK_LIMITS_PAGE);
-    *Supported = FALSE;
-
-    status = STATUS_NO_MEMORY;
-    BlockLimits = __PdoAllocate(Length);
-    if (BlockLimits == NULL)
-        goto fail1;
-
-    RtlZeroMemory(&Srb, sizeof(SCSI_REQUEST_BLOCK));
-    Srb.Length = sizeof(SCSI_REQUEST_BLOCK);
-    Srb.SrbFlags = 0;
-    Srb.Function = SRB_FUNCTION_EXECUTE_SCSI;
-    Srb.DataBuffer = BlockLimits;
-    Srb.DataTransferLength = Length;
-    Srb.TimeOutValue = (ULONG)-1;
-    Srb.CdbLength = 6;
-
-    Cdb = (PCDB)&Srb.Cdb[0];
-    Cdb->CDB6INQUIRY3.OperationCode = SCSIOP_INQUIRY;
-    Cdb->CDB6INQUIRY3.PageCode = 0xB0;
-    Cdb->CDB6INQUIRY3.EnableVitalProductData = 1;
-    Cdb->CDB6INQUIRY3.AllocationLength = (UCHAR)Length;
-
-    status = PdoSendAwaitSrb(Pdo, &Srb);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status = STATUS_UNSUCCESSFUL;
-    if (Srb.DataTransferLength < Length)
-        goto fail3;
-
-    *Supported = BlockLimits->UGAValid;
-
-    __PdoFree(BlockLimits);
-
-    Trace("<====\n");
-    return STATUS_SUCCESS;
-
-fail3:
-    Error("fail3\n");
-
-fail2:
-    Error("fail2\n");
-
-    __PdoFree(BlockLimits);
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
-}
-
-static NTSTATUS
-PdoSendTrimSynchronous(
-    IN  PXENDISK_PDO            Pdo,
-    IN  PDEVICE_DATA_SET_RANGE  Ranges,
-    IN  ULONG                   Count
-    )
-{
-    SCSI_REQUEST_BLOCK          Srb;
-    PCDB                        Cdb;
-    PUNMAP_LIST_HEADER          Unmap;
-    ULONG                       Length;
-    ULONG                       Index;
-    NTSTATUS                    status;
-
-    Length = sizeof(UNMAP_LIST_HEADER) +
-             (Count * sizeof(UNMAP_BLOCK_DESCRIPTOR));
-
-    status = STATUS_NO_MEMORY;
-    Unmap = __PdoAllocate(Length);
-    if (Unmap == NULL)
-        goto fail1;
-
-    RtlZeroMemory(&Srb, sizeof(SCSI_REQUEST_BLOCK));
-    Srb.Length = sizeof(SCSI_REQUEST_BLOCK);
-    Srb.SrbFlags = 0;
-    Srb.Function = SRB_FUNCTION_EXECUTE_SCSI;
-    Srb.DataBuffer = Unmap;
-    Srb.DataTransferLength = Length;
-    Srb.TimeOutValue = (ULONG)-1;
-    Srb.CdbLength = 10;
-
-    Cdb = (PCDB)&Srb.Cdb[0];
-    Cdb->UNMAP.OperationCode = SCSIOP_UNMAP;
-    *(PUSHORT)Cdb->UNMAP.AllocationLength = _byteswap_ushort((USHORT)Length);
-
-    *(PUSHORT)Unmap->DataLength = _byteswap_ushort((USHORT)(Length - 
FIELD_OFFSET(UNMAP_LIST_HEADER, BlockDescrDataLength)));
-    *(PUSHORT)Unmap->BlockDescrDataLength = _byteswap_ushort((USHORT)(Length - 
FIELD_OFFSET(UNMAP_LIST_HEADER, Descriptors[0])));
-
-    for (Index = 0; Index < Count; ++Index) {
-        PUNMAP_BLOCK_DESCRIPTOR Block = &Unmap->Descriptors[Index];
-        PDEVICE_DATA_SET_RANGE  Range = &Ranges[Index];
-
-        ULONG   LengthInSectors = (ULONG)(Range->LengthInBytes / 
Pdo->SectorSize);
-        ULONG64 OffsetInSectors = (ULONG64)(Range->StartingOffset / 
Pdo->SectorSize);
-
-        *(PULONG64)Block->StartingLba = _byteswap_uint64(OffsetInSectors);
-        *(PULONG)Block->LbaCount = _byteswap_ulong(LengthInSectors);
-    }
-
-    status = PdoSendAwaitSrb(Pdo, &Srb);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    __PdoFree(Unmap);
-    return status;
-
-fail2:
-    Error("fail2\n");
-
-    __PdoFree(Unmap);
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
-}
-
-static const CHAR *
-PropertyIdName(
-    IN  STORAGE_PROPERTY_ID Id
-    )
-{
-#define _STORAGE_PROPERTY_NAME(_Id) \
-    case Storage ## _Id:            \
-        return #_Id;
-
-    switch (Id) {
-    _STORAGE_PROPERTY_NAME(DeviceProperty);
-    _STORAGE_PROPERTY_NAME(AdapterProperty);
-    _STORAGE_PROPERTY_NAME(DeviceIdProperty);
-    _STORAGE_PROPERTY_NAME(DeviceUniqueIdProperty);
-    _STORAGE_PROPERTY_NAME(DeviceWriteCacheProperty);
-    _STORAGE_PROPERTY_NAME(MiniportProperty);
-    _STORAGE_PROPERTY_NAME(AccessAlignmentProperty);
-    _STORAGE_PROPERTY_NAME(DeviceSeekPenaltyProperty);
-    _STORAGE_PROPERTY_NAME(DeviceTrimProperty);
-    _STORAGE_PROPERTY_NAME(DeviceWriteAggregationProperty);
-    _STORAGE_PROPERTY_NAME(DeviceDeviceTelemetryProperty);
-    _STORAGE_PROPERTY_NAME(DeviceLBProvisioningProperty);
-    _STORAGE_PROPERTY_NAME(DevicePowerProperty);
-    _STORAGE_PROPERTY_NAME(DeviceCopyOffloadProperty);
-    _STORAGE_PROPERTY_NAME(DeviceResiliencyProperty);
-    _STORAGE_PROPERTY_NAME(DeviceMediumProductType);
-    _STORAGE_PROPERTY_NAME(AdapterCryptoProperty);
-    _STORAGE_PROPERTY_NAME(DeviceIoCapabilityProperty);
-    _STORAGE_PROPERTY_NAME(AdapterProtocolSpecificProperty);
-    _STORAGE_PROPERTY_NAME(DeviceProtocolSpecificProperty);
-    _STORAGE_PROPERTY_NAME(AdapterTemperatureProperty);
-    _STORAGE_PROPERTY_NAME(DeviceTemperatureProperty);
-    _STORAGE_PROPERTY_NAME(AdapterPhysicalTopologyProperty);
-    _STORAGE_PROPERTY_NAME(DevicePhysicalTopologyProperty);
-    _STORAGE_PROPERTY_NAME(DeviceAttributesProperty);
-    default:
-        break;
-    }
-
-    return "UNKNOWN";
-
-#undef _STORAGE_PROPERTY_NAME
-}
-
-static const CHAR *
-QueryTypeName(
-    IN  STORAGE_QUERY_TYPE  Type
-    )
-{
-#define _STORAGE_QUERY_NAME(_Type)   \
-    case Property ## _Type ## Query: \
-        return #_Type;
-
-    switch (Type) {
-    _STORAGE_QUERY_NAME(Standard);
-    _STORAGE_QUERY_NAME(Exists);
-    _STORAGE_QUERY_NAME(Mask);
-    default:
-        break;
-    }
-
-    return "UNKNOWN";
-
-#undef _STORAGE_QUERY_NAME
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-PdoQueryProperty(
-    IN  PXENDISK_PDO        Pdo,
-    IN  PIRP                Irp
-    )
-{
-    PIO_STACK_LOCATION      StackLocation;
-    PSTORAGE_PROPERTY_QUERY Query;
-    NTSTATUS                status;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-
-    if (StackLocation->Parameters.DeviceIoControl.InputBufferLength <
-        sizeof (STORAGE_PROPERTY_QUERY))
-        return PdoCompleteIrp(Pdo, Irp, STATUS_INFO_LENGTH_MISMATCH);
-
-    Query = Irp->AssociatedIrp.SystemBuffer;
-
-    Trace("%s %s\n", PropertyIdName(Query->PropertyId), 
QueryTypeName(Query->QueryType));
-
-    switch (Query->PropertyId) {
-    case StorageDeviceTrimProperty:
-        if (!Pdo->InterceptTrim || !Pdo->DiscardSupported) {
-            status = PdoForwardIrpAndForget(Pdo, Irp);
-            break;
-        }
-
-        if (Query->QueryType == PropertyStandardQuery) {
-            PDEVICE_TRIM_DESCRIPTOR Trim;
-
-            if (StackLocation->Parameters.DeviceIoControl.OutputBufferLength <
-                sizeof (DEVICE_TRIM_DESCRIPTOR))
-                return PdoCompleteIrp(Pdo, Irp, STATUS_BUFFER_OVERFLOW);
-
-            Trim = Irp->AssociatedIrp.SystemBuffer;
-
-            RtlZeroMemory(Trim, sizeof(DEVICE_TRIM_DESCRIPTOR));
-
-            Trim->Version = sizeof(DEVICE_TRIM_DESCRIPTOR);
-            Trim->Size = sizeof(DEVICE_TRIM_DESCRIPTOR);
-            Trim->TrimEnabled = TRUE;
-
-            Irp->IoStatus.Information = sizeof(DEVICE_TRIM_DESCRIPTOR);
-        } else {
-            Irp->IoStatus.Information = 0;
-        }
-
-        status = PdoCompleteIrp(Pdo, Irp, STATUS_SUCCESS);
-        break;
-
-    case StorageAccessAlignmentProperty: {
-        if (Query->QueryType == PropertyStandardQuery) {
-            PSTORAGE_ACCESS_ALIGNMENT_DESCRIPTOR AccessAlignment;
-
-            if (StackLocation->Parameters.DeviceIoControl.OutputBufferLength <
-                sizeof (STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR))
-                return PdoCompleteIrp(Pdo, Irp, STATUS_BUFFER_OVERFLOW);
-
-            AccessAlignment = Irp->AssociatedIrp.SystemBuffer;
-
-            RtlZeroMemory(AccessAlignment, 
sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR));
-
-            AccessAlignment->Version = 
sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR);
-            AccessAlignment->Size = 
sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR);
-            AccessAlignment->BytesPerCacheLine = 0;
-            AccessAlignment->BytesOffsetForCacheAlignment = 0;
-            AccessAlignment->BytesPerLogicalSector = Pdo->SectorSize;
-            AccessAlignment->BytesPerPhysicalSector = Pdo->PhysSectorSize;
-            AccessAlignment->BytesOffsetForSectorAlignment = 0;
-
-            Irp->IoStatus.Information = 
sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR);
-        } else {
-            Irp->IoStatus.Information = 0;
-        }
-
-        status = PdoCompleteIrp(Pdo, Irp, STATUS_SUCCESS);
-        break;
-    }
-    default:
-        status = PdoForwardIrpAndForget(Pdo, Irp);
-        break;
-    }
-
-    return status;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-PdoManageDataSetAttributes(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    PDEVICE_MANAGE_DATA_SET_ATTRIBUTES  Attributes;
-    PDEVICE_DATA_SET_RANGE              Ranges;
-    ULONG                               NumRanges;
-    NTSTATUS                            status;
-
-    Attributes = Irp->AssociatedIrp.SystemBuffer;
-
-    switch (Attributes->Action) {
-    case DeviceDsmAction_Trim:
-        if (!Pdo->InterceptTrim || !Pdo->DiscardSupported) {
-            status = PdoForwardIrpAndForget(Pdo, Irp);
-            break;
-        }
-
-        Ranges = (PDEVICE_DATA_SET_RANGE)((PUCHAR)Attributes + 
Attributes->DataSetRangesOffset);
-        NumRanges = Attributes->DataSetRangesLength / 
sizeof(DEVICE_DATA_SET_RANGE);
-
-        status = PdoSendTrimSynchronous(Pdo, Ranges, NumRanges);
-
-        status = PdoCompleteIrp(Pdo, Irp, status);
-        break;
-
-    default:
-        status = PdoForwardIrpAndForget(Pdo, Irp);
-        break;
-    }
-
-    return status;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-PdoDispatchControl(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    ULONG               ControlCode;
-    ULONG               Method;
-    NTSTATUS            status;
-
-    status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    ControlCode = StackLocation->Parameters.DeviceIoControl.IoControlCode;
-    Method = METHOD_FROM_CTL_CODE(ControlCode);
-
-    switch (ControlCode) {
-    case IOCTL_STORAGE_QUERY_PROPERTY:
-        ASSERT(Method == METHOD_BUFFERED);
-        status = PdoQueryProperty(Pdo, Irp);
-        break;
-
-    case IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES:
-        ASSERT(Method == METHOD_BUFFERED);
-        status = PdoManageDataSetAttributes(Pdo, Irp);
-        break;
-
-    default:
-        status = PdoForwardIrpAndForget(Pdo, Irp);
-        break;
-    }
-
-    return status;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-PdoStartDevice(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    ULONG               SectorSize;
-    ULONG               PhysSectorSize;
-    ULONG64             SectorCount;
-    ULONG64             Size;
-    BOOLEAN             DiscardSupported;
-    POWER_STATE         PowerState;
-    NTSTATUS            status;
-
-    status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status = PdoForwardIrpSynchronously(Pdo, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status = PdoSendReadCapacity16Synchronous(Pdo,
-                                              &SectorSize,
-                                              &PhysSectorSize,
-                                              &SectorCount);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    status = PdoSendInquiryB0Synchronous(Pdo,
-                                         &DiscardSupported);
-    if (!NT_SUCCESS(status))
-        goto fail4;
-
-    Pdo->SectorSize = SectorSize;
-    Pdo->PhysSectorSize = PhysSectorSize;
-    Pdo->DiscardSupported = DiscardSupported;
-
-    Size = SectorSize * SectorCount;
-    Size >>= 20; // Scale to megabytes
-
-    Verbose("%s: %luMB (%uB sectors)%s%s\n",
-            __PdoGetName(Pdo), Size, SectorSize,
-            Pdo->DiscardSupported ? " DISCARD" : "",
-            Pdo->InterceptTrim ? "" : " (VETOED)");
-
-    __PdoSetSystemPowerState(Pdo, PowerSystemWorking);
-    __PdoSetDevicePowerState(Pdo, PowerDeviceD0);
-
-    PowerState.DeviceState = PowerDeviceD0;
-    PoSetPowerState(Pdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
-
-    __PdoSetDevicePnpState(Pdo, Started);
-
-    IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-
-    Irp->IoStatus.Status = STATUS_SUCCESS;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return STATUS_SUCCESS;
-
-fail4:
-    Error("fail4\n");
-
-fail3:
-    Error("fail3\n");
-
-fail2:
-    Error("fail2\n");
-
-    IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__PdoQueryStopDevice(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_PDO        Pdo = Context;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-
-    return STATUS_SUCCESS;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-PdoQueryStopDevice(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    NTSTATUS            status;
-
-    status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    __PdoSetDevicePnpState(Pdo, StopPending);
-    Irp->IoStatus.Status = STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __PdoQueryStopDevice,
-                           Pdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__PdoCancelStopDevice(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_PDO        Pdo = Context;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-
-    return STATUS_SUCCESS;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-PdoCancelStopDevice(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    NTSTATUS            status;
-
-    status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    Irp->IoStatus.Status = STATUS_SUCCESS;
-
-    __PdoRestoreDevicePnpState(Pdo, StopPending);
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __PdoCancelStopDevice,
-                           Pdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__PdoStopDevice(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_PDO        Pdo = Context;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-
-    Pdo->PhysSectorSize = 0;
-    Pdo->SectorSize = 0;
-
-    return STATUS_SUCCESS;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-PdoStopDevice(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    POWER_STATE         PowerState;
-    NTSTATUS            status;
-
-    status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    if (__PdoGetDevicePowerState(Pdo) != PowerDeviceD0)
-        goto done;
-
-    __PdoSetDevicePowerState(Pdo, PowerDeviceD3);
-    __PdoSetSystemPowerState(Pdo, PowerSystemShutdown);
-
-    PowerState.DeviceState = PowerDeviceD3;
-    PoSetPowerState(Pdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
-
-done:
-    __PdoSetDevicePnpState(Pdo, Stopped);
-    Irp->IoStatus.Status = STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __PdoStopDevice,
-                           Pdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__PdoQueryRemoveDevice(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_PDO        Pdo = Context;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-
-    return STATUS_SUCCESS;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-PdoQueryRemoveDevice(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    NTSTATUS            status;
-
-    status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    __PdoSetDevicePnpState(Pdo, RemovePending);
-    Irp->IoStatus.Status = STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __PdoQueryRemoveDevice,
-                           Pdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__PdoCancelRemoveDevice(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_PDO        Pdo = Context;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-
-    return STATUS_SUCCESS;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-PdoCancelRemoveDevice(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    NTSTATUS            status;
-
-    status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    __PdoRestoreDevicePnpState(Pdo, RemovePending);
-    Irp->IoStatus.Status = STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __PdoCancelRemoveDevice,
-                           Pdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__PdoSurpriseRemoval(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_PDO        Pdo = Context;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-
-    return STATUS_SUCCESS;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-PdoSurpriseRemoval(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    NTSTATUS            status;
-
-    status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    __PdoSetDevicePnpState(Pdo, SurpriseRemovePending);
-    Irp->IoStatus.Status = STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __PdoSurpriseRemoval,
-                           Pdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-PdoRemoveDevice(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    PXENDISK_FDO        Fdo = __PdoGetFdo(Pdo);
-    POWER_STATE         PowerState;
-    NTSTATUS            status;
-
-    status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    if (__PdoGetDevicePowerState(Pdo) != PowerDeviceD0)
-        goto done;
-
-    __PdoSetDevicePowerState(Pdo, PowerDeviceD3);
-    __PdoSetSystemPowerState(Pdo, PowerSystemShutdown);
-
-    PowerState.DeviceState = PowerDeviceD3;
-    PoSetPowerState(Pdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
-
-done:
-    FdoAcquireMutex(Fdo);
-    __PdoSetDevicePnpState(Pdo, Deleted);
-    FdoReleaseMutex(Fdo);
-
-    IoReleaseRemoveLockAndWait(&Pdo->Dx->RemoveLock, Irp);
-
-    status = PdoForwardIrpSynchronously(Pdo, Irp);
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    Pdo->PhysSectorSize = 0;
-    Pdo->SectorSize = 0;
-
-    FdoAcquireMutex(Fdo);
-    PdoDestroy(Pdo);
-    FdoReleaseMutex(Fdo);
-
-    IoInvalidateDeviceRelations(FdoGetPhysicalDeviceObject(Fdo),
-                                BusRelations);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-PdoEject(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    PXENDISK_FDO        Fdo = __PdoGetFdo(Pdo);
-    NTSTATUS            status;
-
-    __PdoSetDevicePnpState(Pdo, Deleted);
-
-    status = PdoForwardIrpSynchronously(Pdo, Irp);
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    FdoAcquireMutex(Fdo);
-    PdoDestroy(Pdo);
-    FdoReleaseMutex(Fdo);
-
-    return status;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__PdoDispatchPnp(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_PDO        Pdo = Context;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    return STATUS_SUCCESS;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-PdoDispatchPnp(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    UCHAR               MinorFunction;
-    NTSTATUS            status;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    MinorFunction = StackLocation->MinorFunction;
-
-    switch (StackLocation->MinorFunction) {
-    case IRP_MN_START_DEVICE:
-        status = PdoStartDevice(Pdo, Irp);
-        break;
-
-    case IRP_MN_QUERY_STOP_DEVICE:
-        status = PdoQueryStopDevice(Pdo, Irp);
-        break;
-
-    case IRP_MN_CANCEL_STOP_DEVICE:
-        status = PdoCancelStopDevice(Pdo, Irp);
-        break;
-
-    case IRP_MN_STOP_DEVICE:
-        status = PdoStopDevice(Pdo, Irp);
-        break;
-
-    case IRP_MN_QUERY_REMOVE_DEVICE:
-        status = PdoQueryRemoveDevice(Pdo, Irp);
-        break;
-
-    case IRP_MN_SURPRISE_REMOVAL:
-        status = PdoSurpriseRemoval(Pdo, Irp);
-        break;
-
-    case IRP_MN_REMOVE_DEVICE:
-        status = PdoRemoveDevice(Pdo, Irp);
-        break;
-
-    case IRP_MN_CANCEL_REMOVE_DEVICE:
-        status = PdoCancelRemoveDevice(Pdo, Irp);
-        break;
-
-    case IRP_MN_EJECT:
-        status = PdoEject(Pdo, Irp);
-        break;
-
-    default:
-        status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-        if (!NT_SUCCESS(status))
-            goto fail1;
-
-        IoCopyCurrentIrpStackLocationToNext(Irp);
-        IoSetCompletionRoutine(Irp,
-                               __PdoDispatchPnp,
-                               Pdo,
-                               TRUE,
-                               TRUE,
-                               TRUE);
-
-        status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
-        break;
-    }
-
-    return status;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-PdoSetDevicePowerUpComplete(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_PDO        Pdo = (PXENDISK_PDO) Context;
-    PIO_STACK_LOCATION  StackLocation;
-    POWER_STATE         PowerState;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    PowerState = StackLocation->Parameters.Power.State;
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    __PdoSetDevicePowerState(Pdo, PowerState.DeviceState);
-    PoSetPowerState(Pdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
-
-    return STATUS_CONTINUE_COMPLETION;
-}
-
-static FORCEINLINE NTSTATUS
-__PdoSetDevicePowerUp(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           PdoSetDevicePowerUpComplete,
-                           Pdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    return IoCallDriver(Pdo->LowerDeviceObject, Irp);
-}
-
-static FORCEINLINE NTSTATUS
-__PdoSetDevicePowerDown(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    POWER_STATE         PowerState;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    PowerState = StackLocation->Parameters.Power.State;
-
-    __PdoSetDevicePowerState(Pdo, PowerState.DeviceState);
-    PoSetPowerState(Pdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
-
-    IoSkipCurrentIrpStackLocation(Irp);
-    return IoCallDriver(Pdo->LowerDeviceObject, Irp);
-}
-
-static FORCEINLINE NTSTATUS
-__PdoSetDevicePower(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    DEVICE_POWER_STATE  DeviceState;
-    POWER_ACTION        PowerAction;
-    NTSTATUS            status;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    DeviceState = StackLocation->Parameters.Power.State.DeviceState;
-    PowerAction = StackLocation->Parameters.Power.ShutdownType;
-
-    Trace("====> (%s:%s)\n",
-          PowerDeviceStateName(DeviceState),
-          PowerActionName(PowerAction));
-
-    if (DeviceState == __PdoGetDevicePowerState(Pdo)) {
-        IoSkipCurrentIrpStackLocation(Irp);
-        status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
-        goto done;
-    }
-
-    status = DeviceState < __PdoGetDevicePowerState(Pdo) ?
-             __PdoSetDevicePowerUp(Pdo, Irp) :
-             __PdoSetDevicePowerDown(Pdo, Irp);
-
-done:
-    Trace("<==== (%s:%s)(%08x)\n",
-          PowerDeviceStateName(DeviceState),
-          PowerActionName(PowerAction),
-          status);
-
-    return status;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-PdoSetSystemPowerUpComplete(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_PDO        Pdo = (PXENDISK_PDO) Context;
-    PIO_STACK_LOCATION  StackLocation;
-    SYSTEM_POWER_STATE  SystemState;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    SystemState = StackLocation->Parameters.Power.State.SystemState;
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    __PdoSetSystemPowerState(Pdo, SystemState);
-
-    return STATUS_CONTINUE_COMPLETION;
-}
-
-static FORCEINLINE NTSTATUS
-__PdoSetSystemPowerUp(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           PdoSetSystemPowerUpComplete,
-                           Pdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    return IoCallDriver(Pdo->LowerDeviceObject, Irp);
-}
-
-static FORCEINLINE NTSTATUS
-__PdoSetSystemPowerDown(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    SYSTEM_POWER_STATE  SystemState;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    SystemState = StackLocation->Parameters.Power.State.SystemState;
-
-    __PdoSetSystemPowerState(Pdo, SystemState);
-
-    IoSkipCurrentIrpStackLocation(Irp);
-    return IoCallDriver(Pdo->LowerDeviceObject, Irp);
-}
-
-static FORCEINLINE NTSTATUS
-__PdoSetSystemPower(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    SYSTEM_POWER_STATE  SystemState;
-    POWER_ACTION        PowerAction;
-    NTSTATUS            status;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    SystemState = StackLocation->Parameters.Power.State.SystemState;
-    PowerAction = StackLocation->Parameters.Power.ShutdownType;
-
-    Trace("====> (%s:%s)\n",
-          PowerSystemStateName(SystemState),
-          PowerActionName(PowerAction));
-
-    if (SystemState == __PdoGetSystemPowerState(Pdo)) {
-        IoSkipCurrentIrpStackLocation(Irp);
-        status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
-        goto done;
-    }
-
-    status = SystemState < __PdoGetSystemPowerState(Pdo) ?
-             __PdoSetSystemPowerUp(Pdo, Irp) :
-             __PdoSetSystemPowerDown(Pdo, Irp);
-
-done:
-    Trace("<==== (%s:%s)(%08x)\n",
-          PowerSystemStateName(SystemState),
-          PowerActionName(PowerAction),
-          status);
-
-    return status;
-}
-
-static NTSTATUS
-PdoDevicePower(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    NTSTATUS            status;
-    PIO_STACK_LOCATION  StackLocation;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-
-    switch (StackLocation->MinorFunction) {
-    case IRP_MN_SET_POWER:
-        status = __PdoSetDevicePower(Pdo, Irp);
-        break;
-
-    default:
-        IoSkipCurrentIrpStackLocation(Irp);
-        status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
-        break;
-    }
-
-    return status;
-}
-
-static NTSTATUS
-PdoSystemPower(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    NTSTATUS            status;
-    PIO_STACK_LOCATION  StackLocation;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-
-    switch (StackLocation->MinorFunction) {
-    case IRP_MN_SET_POWER:
-        status = __PdoSetSystemPower(Pdo, Irp);
-        break;
-
-    default:
-        IoSkipCurrentIrpStackLocation(Irp);
-        status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
-        break;
-    }
-
-    return status;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-PdoDispatchPower(
-    IN  PXENDISK_PDO   Pdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    POWER_STATE_TYPE    PowerType;
-    NTSTATUS            status;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    PowerType = StackLocation->Parameters.Power.Type;
-
-    switch (PowerType) {
-    case DevicePowerState:
-        status = PdoDevicePower(Pdo, Irp);
-        break;
-
-    case SystemPowerState:
-        status = PdoSystemPower(Pdo, Irp);
-        break;
-
-    default:
-        IoSkipCurrentIrpStackLocation(Irp);
-        status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
-        break;
-    }
-
-    return status;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__PdoDispatchDefault(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_PDO        Pdo = Context;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-
-    return STATUS_SUCCESS;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-PdoDispatchDefault(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    NTSTATUS            status;
-
-    status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __PdoDispatchDefault,
-                           Pdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-NTSTATUS
-PdoDispatch(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    NTSTATUS            status;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-
-    switch (StackLocation->MajorFunction) {
-    case IRP_MJ_DEVICE_CONTROL:
-        status = PdoDispatchControl(Pdo, Irp);
-        break;
-
-    case IRP_MJ_PNP:
-        status = PdoDispatchPnp(Pdo, Irp);
-        break;
-
-    case IRP_MJ_POWER:
-        status = PdoDispatchPower(Pdo, Irp);
-        break;
-
-    default:
-        status = PdoDispatchDefault(Pdo, Irp);
-        break;
-    }
-
-    return status;
-}
-
-NTSTATUS
-PdoCreate(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PDEVICE_OBJECT  PhysicalDeviceObject,
-    IN  PCHAR           DeviceID,
-    IN  PCHAR           InstanceID
-    )
-{
-    PDEVICE_OBJECT      LowerDeviceObject;
-    ULONG               DeviceType;
-    PDEVICE_OBJECT      FilterDeviceObject;
-    PXENDISK_DX         Dx;
-    PXENDISK_PDO        Pdo;
-    HANDLE              ParametersKey;
-    ULONG               InterceptTrim;
-    NTSTATUS            status;
-
-    LowerDeviceObject = IoGetAttachedDeviceReference(PhysicalDeviceObject);
-    DeviceType = LowerDeviceObject->DeviceType;
-    ObDereferenceObject(LowerDeviceObject);
-
-#pragma prefast(suppress:28197) // Possibly leaking memory 
'PhysicalDeviceObject'
-    status = IoCreateDevice(DriverGetDriverObject(),
-                            sizeof(XENDISK_DX),
-                            NULL,
-                            DeviceType,
-                            FILE_DEVICE_SECURE_OPEN,
-                            FALSE,
-                            &FilterDeviceObject);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    Dx = (PXENDISK_DX)FilterDeviceObject->DeviceExtension;
-    RtlZeroMemory(Dx, sizeof (XENDISK_DX));
-
-    Dx->Type = PHYSICAL_DEVICE_OBJECT;
-    Dx->DeviceObject = FilterDeviceObject;
-    Dx->DevicePnpState = Present;
-    Dx->SystemPowerState = PowerSystemShutdown;
-    Dx->DevicePowerState = PowerDeviceD3;
-
-    IoInitializeRemoveLock(&Dx->RemoveLock, PDO_TAG, 0, 0);
-
-    Pdo = __PdoAllocate(sizeof (XENDISK_PDO));
-
-    status = STATUS_NO_MEMORY;
-    if (Pdo == NULL)
-        goto fail2;
-
-    LowerDeviceObject = IoAttachDeviceToDeviceStack(FilterDeviceObject,
-                                                    PhysicalDeviceObject);
-
-    status = STATUS_UNSUCCESSFUL;
-    if (LowerDeviceObject == NULL)
-        goto fail3;
-
-    Pdo->Dx = Dx;
-    Pdo->PhysicalDeviceObject = PhysicalDeviceObject;
-    Pdo->LowerDeviceObject = LowerDeviceObject;
-
-    __PdoSetName(Pdo, DeviceID, InstanceID);
-
-    ParametersKey = DriverGetParametersKey();
-
-    Pdo->InterceptTrim = TRUE;
-
-    status = RegistryQueryDwordValue(ParametersKey,
-                                     "InterceptTrim",
-                                     &InterceptTrim);
-    if (NT_SUCCESS(status))
-        Pdo->InterceptTrim = (InterceptTrim != 0) ? TRUE : FALSE;
-
-    Verbose("%p (%s)\n", FilterDeviceObject, __PdoGetName(Pdo));
-
-    Dx->Pdo = Pdo;
-
-#pragma prefast(suppress:28182) // Dereferencing NULL pointer
-    FilterDeviceObject->DeviceType = LowerDeviceObject->DeviceType;
-    FilterDeviceObject->Characteristics = LowerDeviceObject->Characteristics;
-
-    FilterDeviceObject->Flags |= LowerDeviceObject->Flags;
-    FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
-
-    __PdoLink(Pdo, Fdo);
-
-    return STATUS_SUCCESS;
-
-fail3:
-    Error("fail3\n");
-
-    ASSERT(IsZeroMemory(Pdo, sizeof (XENDISK_PDO)));
-    __PdoFree(Pdo);
-
-fail2:
-    Error("fail2\n");
-
-    IoDeleteDevice(FilterDeviceObject);
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
-}
-
-VOID
-PdoDestroy(
-    IN  PXENDISK_PDO    Pdo
-    )
-{
-    PDEVICE_OBJECT      LowerDeviceObject = Pdo->LowerDeviceObject;
-    PXENDISK_DX         Dx = Pdo->Dx;
-    PDEVICE_OBJECT      FilterDeviceObject = Dx->DeviceObject;
-
-    ASSERT3U(__PdoGetDevicePnpState(Pdo), ==, Deleted);
-
-    __PdoUnlink(Pdo);
-
-    Verbose("%s\n", __PdoGetName(Pdo));
-
-    Dx->Pdo = NULL;
-
-    Pdo->InterceptTrim = FALSE;
-    Pdo->DiscardSupported = FALSE;
-
-    RtlZeroMemory(Pdo->Name, sizeof (Pdo->Name));
-
-    Pdo->PhysicalDeviceObject = NULL;
-    Pdo->LowerDeviceObject = NULL;
-    Pdo->Dx = NULL;
-
-    IoDetachDevice(LowerDeviceObject);
-
-    ASSERT(IsZeroMemory(Pdo, sizeof (XENDISK_PDO)));
-    __PdoFree(Pdo);
-
-    IoDeleteDevice(FilterDeviceObject);
-}
diff --git a/src/xendisk/pdo.h b/src/xendisk/pdo.h
deleted file mode 100644
index 24e580a..0000000
--- a/src/xendisk/pdo.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* Copyright (c) Xen Project.
- * Copyright (c) Cloud Software Group, 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 _XENDISK_PDO_H
-#define _XENDISK_PDO_H
-
-#include <ntddk.h>
-#include "types.h"
-#include "fdo.h"
-
-typedef struct _XENDISK_PDO XENDISK_PDO, *PXENDISK_PDO;
-
-extern VOID
-PdoSetDevicePnpState(
-    IN  PXENDISK_PDO        Pdo,
-    IN  DEVICE_PNP_STATE    State
-    );
-
-extern DEVICE_PNP_STATE
-PdoGetDevicePnpState(
-    IN  PXENDISK_PDO    Pdo
-    );
-
-extern PDEVICE_OBJECT
-PdoGetPhysicalDeviceObject(
-    IN  PXENDISK_PDO    Pdo
-    );
-
-extern NTSTATUS
-PdoCreate(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PDEVICE_OBJECT  PhysicalDeviceObject,
-    IN  PCHAR           DeviceID,
-    IN  PCHAR           InstanceID
-    );
-
-extern VOID
-PdoDestroy(
-    IN  PXENDISK_PDO    Pdo
-    );
-
-extern NTSTATUS
-PdoDispatch(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    );
-
-#endif // _XENDISK_PDO_H
diff --git a/src/xendisk/registry.c b/src/xendisk/registry.c
deleted file mode 100644
index 03e93ac..0000000
--- a/src/xendisk/registry.c
+++ /dev/null
@@ -1,1564 +0,0 @@
-/* Copyright (c) Xen Project.
- * Copyright (c) Cloud Software Group, 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 "registry.h"
-#include "assert.h"
-#include "util.h"
-
-#define REGISTRY_TAG 'GERX'
-
-static PDRIVER_OBJECT   RegistryDriverObject;
-static UNICODE_STRING   RegistryPath;
-
-typedef NTSTATUS(*IOOPENDRIVERREGISTRYKEY)(PDRIVER_OBJECT, DRIVER_REGKEY_TYPE, 
ACCESS_MASK, ULONG, PHANDLE);
-
-static IOOPENDRIVERREGISTRYKEY __IoOpenDriverRegistryKey;
-
-static FORCEINLINE PVOID
-__RegistryAllocate(
-    IN  ULONG   Length
-    )
-{
-    return __AllocatePoolWithTag(NonPagedPool, Length, REGISTRY_TAG);
-}
-
-static FORCEINLINE VOID
-__RegistryFree(
-    IN  PVOID   Buffer
-    )
-{
-    __FreePoolWithTag(Buffer, REGISTRY_TAG);
-}
-
-NTSTATUS
-#pragma prefast(suppress:28101) // unannotated DriverEntry function
-RegistryInitialize(
-    IN  PDRIVER_OBJECT  DriverObject,
-    IN  PUNICODE_STRING Path
-    )
-{
-    UNICODE_STRING      Unicode;
-    PVOID               Func;
-    NTSTATUS            status;
-
-    ASSERT3P(RegistryPath.Buffer, ==, NULL);
-
-    status = RtlUpcaseUnicodeString(&RegistryPath, Path, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    ASSERT3P(RegistryDriverObject, ==, NULL);
-    RegistryDriverObject = DriverObject;
-
-    ASSERT3P(__IoOpenDriverRegistryKey, ==, NULL);
-    RtlInitUnicodeString(&Unicode, L"IoOpenDriverRegistryKey");
-
-    Func = MmGetSystemRoutineAddress(&Unicode);
-    if (Func != NULL)
-        __IoOpenDriverRegistryKey = (IOOPENDRIVERREGISTRYKEY)Func;
-
-    return STATUS_SUCCESS;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
-}
-
-VOID
-RegistryTeardown(
-    VOID
-    )
-{
-    __IoOpenDriverRegistryKey = NULL;
-
-    RegistryDriverObject = NULL;
-
-    RtlFreeUnicodeString(&RegistryPath);
-    RegistryPath.Buffer = NULL;
-    RegistryPath.MaximumLength = RegistryPath.Length = 0;
-}
-
-NTSTATUS
-RegistryOpenKey(
-    IN  HANDLE          Parent,
-    IN  PUNICODE_STRING Path,
-    IN  ACCESS_MASK     DesiredAccess,
-    OUT PHANDLE         Key
-    )
-{
-    OBJECT_ATTRIBUTES   Attributes;
-    NTSTATUS            status;
-
-    InitializeObjectAttributes(&Attributes,
-                               Path,
-                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
-                               Parent,
-                               NULL);
-
-    status = ZwOpenKey(Key,
-                       DesiredAccess,
-                       &Attributes);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    return STATUS_SUCCESS;
-
-fail1:
-    return status;
-}
-
-static NTSTATUS
-RegistryOpenRoot(
-    IN  PWCHAR          Path,
-    OUT PHANDLE         Parent,
-    OUT PWCHAR          *ChildPath
-    )
-{
-    const WCHAR         Prefix[] = L"\\Registry\\Machine\\";
-    ULONG               Length;
-    UNICODE_STRING      Unicode;
-    NTSTATUS            status;
-
-    Length = (ULONG)wcslen(Prefix);
-
-    status = STATUS_INVALID_PARAMETER;
-    if (_wcsnicmp(Path, Prefix, Length) != 0)
-        goto fail1;
-
-    RtlInitUnicodeString(&Unicode, Prefix);
-
-    status = RegistryOpenKey(NULL, &Unicode, KEY_ALL_ACCESS, Parent);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    *ChildPath = Path + Length;
-
-    return STATUS_SUCCESS;
-
-fail2:
-fail1:
-    return status;
-}
-
-NTSTATUS
-RegistryCreateKey(
-    IN  HANDLE          Parent,
-    IN  PUNICODE_STRING Path,
-    IN  ULONG           Options,
-    OUT PHANDLE         Key
-    )
-{
-    PWCHAR              Buffer;
-    HANDLE              Root;
-    PWCHAR              ChildPath;
-    PWCHAR              ChildName;
-    PWCHAR              Context;
-    HANDLE              Child;
-    NTSTATUS            status;
-
-    //
-    // UNICODE_STRINGs are not guaranteed to have NUL terminated
-    // buffers.
-    //
-
-    Buffer = __RegistryAllocate(Path->MaximumLength + sizeof (WCHAR));
-
-    status = STATUS_NO_MEMORY;
-    if (Buffer == NULL)
-        goto fail1;
-
-    RtlCopyMemory(Buffer, Path->Buffer, Path->Length);
-
-    Root = Parent;
-
-    if (Parent != NULL) {
-        ChildPath = Buffer;
-    } else {
-        status = RegistryOpenRoot(Buffer, &Parent, &ChildPath);
-        if (!NT_SUCCESS(status))
-            goto fail2;
-    }
-
-    ChildName = __wcstok_r(ChildPath, L"\\", &Context);
-
-    status = STATUS_INVALID_PARAMETER;
-    if (ChildName == NULL)
-        goto fail3;
-
-    Child = NULL;
-
-    while (ChildName != NULL) {
-        UNICODE_STRING      Unicode;
-        OBJECT_ATTRIBUTES   Attributes;
-
-        RtlInitUnicodeString(&Unicode, ChildName);
-
-        InitializeObjectAttributes(&Attributes,
-                                   &Unicode,
-                                   OBJ_CASE_INSENSITIVE |
-                                   OBJ_KERNEL_HANDLE |
-                                   OBJ_OPENIF,
-                                   Parent,
-                                   NULL);
-
-        status = ZwCreateKey(&Child,
-                             KEY_ALL_ACCESS,
-                             &Attributes,
-                             0,
-                             NULL,
-                             Options,
-                             NULL
-                             );
-        if (!NT_SUCCESS(status))
-            goto fail4;
-
-        ChildName = __wcstok_r(NULL, L"\\", &Context);
-
-        if (Parent != Root)
-            ZwClose(Parent);
-
-        Parent = Child;
-    }
-
-    ASSERT(Child != NULL);
-
-    *Key = Child;
-
-    __RegistryFree(Buffer);
-
-    return STATUS_SUCCESS;
-
-fail4:
-fail3:
-    if (Parent != Root)
-        ZwClose(Parent);
-
-fail2:
-    __RegistryFree(Buffer);
-
-fail1:
-    return status;
-}
-
-NTSTATUS
-RegistryOpenServiceKey(
-    IN  ACCESS_MASK     DesiredAccess,
-    OUT PHANDLE         Key
-    )
-{
-    return RegistryOpenKey(NULL, &RegistryPath, DesiredAccess, Key);
-}
-
-NTSTATUS
-RegistryCreateServiceKey(
-    OUT PHANDLE         Key
-    )
-{
-    return RegistryCreateKey(NULL, &RegistryPath, REG_OPTION_NON_VOLATILE, 
Key);
-}
-
-NTSTATUS
-RegistryOpenParametersKey(
-    IN  ACCESS_MASK DesiredAccess,
-    OUT PHANDLE     Key
-    )
-{
-    HANDLE              ServiceKey;
-    NTSTATUS            status;
-
-    if (__IoOpenDriverRegistryKey != NULL) {
-        status = __IoOpenDriverRegistryKey(RegistryDriverObject,
-                                           DriverRegKeyParameters,
-                                           DesiredAccess,
-                                           0,
-                                           Key);
-        if (!NT_SUCCESS(status))
-            goto fail1;
-
-        goto done;
-    }
-
-    status = RegistryOpenKey(NULL, &RegistryPath, DesiredAccess, &ServiceKey);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status = RegistryOpenSubKey(ServiceKey, "Parameters", DesiredAccess, Key);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    RegistryCloseKey(ServiceKey);
-
-done:
-    return STATUS_SUCCESS;
-
-fail3:
-    Error("fail3\n");
-
-    RegistryCloseKey(ServiceKey);
-
-fail2:
-    Error("fail2\n");
-
-fail1:
-    Error("fail1 %08x\n", status);
-
-    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
-    )
-{
-    HANDLE                  SubKey;
-    ULONG                   Length;
-    PKEY_NAME_INFORMATION   Info;
-    PWCHAR                  Cursor;
-    UNICODE_STRING          Unicode;
-    NTSTATUS                status;
-
-    status = IoOpenDeviceRegistryKey(DeviceObject,
-                                     PLUGPLAY_REGKEY_DEVICE,
-                                     KEY_READ,
-                                     &SubKey);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    Length = 0;
-    status = ZwQueryKey(SubKey,
-                        KeyNameInformation,
-                        NULL,
-                        0,
-                        &Length);
-    if (status != STATUS_BUFFER_OVERFLOW &&
-        status != STATUS_BUFFER_TOO_SMALL)
-        goto fail2;
-
-#pragma prefast(suppress:6102)
-    Info = __RegistryAllocate(Length + sizeof (WCHAR));
-
-    status = STATUS_NO_MEMORY;
-    if (Info == NULL)
-        goto fail3;
-
-    status = ZwQueryKey(SubKey,
-                        KeyNameInformation,
-                        Info,
-                        Length,
-                        &Length);
-    if (!NT_SUCCESS(status))
-        goto fail4;
-
-    Info->Name[Info->NameLength / sizeof (WCHAR)] = '\0';
-
-    Cursor = wcsrchr(Info->Name, L'\\');
-    ASSERT(Cursor != NULL);
-
-    *Cursor = L'\0';
-
-    RtlInitUnicodeString(&Unicode, Info->Name);
-
-    status = RegistryOpenKey(NULL, &Unicode, DesiredAccess, Key);
-    if (!NT_SUCCESS(status))
-        goto fail5;
-
-    __RegistryFree(Info);
-
-    RegistryCloseKey(SubKey);
-
-    return STATUS_SUCCESS;
-
-fail5:
-fail4:
-    __RegistryFree(Info);
-
-fail3:
-fail2:
-    RegistryCloseKey(SubKey);
-
-fail1:
-    return status;
-}
-
-NTSTATUS
-RegistryOpenSubKey(
-    IN  PHANDLE         Key,
-    IN  PCHAR           Name,
-    IN  ACCESS_MASK     DesiredAccess,
-    OUT PHANDLE         SubKey
-    )
-{
-    ANSI_STRING         Ansi;
-    UNICODE_STRING      Unicode;
-    NTSTATUS            status;
-
-    RtlInitAnsiString(&Ansi, Name);
-
-    status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status = RegistryOpenKey(Key, &Unicode, DesiredAccess, SubKey);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    RtlFreeUnicodeString(&Unicode);
-
-    return STATUS_SUCCESS;
-
-fail2:
-    RtlFreeUnicodeString(&Unicode);
-
-fail1:
-    return status;
-}
-
-NTSTATUS
-RegistryCreateSubKey(
-    IN  PHANDLE         Key,
-    IN  PCHAR           Name,
-    IN  ULONG           Options,
-    OUT PHANDLE         SubKey
-    )
-{
-    ANSI_STRING         Ansi;
-    UNICODE_STRING      Unicode;
-    NTSTATUS            status;
-
-    RtlInitAnsiString(&Ansi, Name);
-
-    status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status = RegistryCreateKey(Key, &Unicode, Options, SubKey);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    RtlFreeUnicodeString(&Unicode);
-
-    return STATUS_SUCCESS;
-
-fail2:
-    RtlFreeUnicodeString(&Unicode);
-
-fail1:
-    return status;
-}
-
-NTSTATUS
-RegistryDeleteSubKey(
-    IN  PHANDLE         Key,
-    IN  PCHAR           Name
-    )
-{
-    ANSI_STRING         Ansi;
-    UNICODE_STRING      Unicode;
-    HANDLE              SubKey;
-    NTSTATUS            status;
-
-    RtlInitAnsiString(&Ansi, Name);
-
-    status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status = RegistryOpenKey(Key, &Unicode, KEY_ALL_ACCESS, &SubKey);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status = ZwDeleteKey(SubKey);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    ZwClose(SubKey);
-
-    (VOID) ZwFlushKey(Key);
-
-    RtlFreeUnicodeString(&Unicode);
-
-    return STATUS_SUCCESS;
-
-fail3:
-    ZwClose(SubKey);
-
-fail2:
-    RtlFreeUnicodeString(&Unicode);
-
-fail1:
-    return status;
-}
-
-NTSTATUS
-RegistryEnumerateSubKeys(
-    IN  HANDLE              Key,
-    IN  NTSTATUS            (*Callback)(PVOID, HANDLE, PANSI_STRING),
-    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_OVERFLOW &&
-        status != STATUS_BUFFER_TOO_SMALL)
-        goto fail1;
-
-#pragma prefast(suppress:6102)
-    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++) {
-        ULONG           Ignore;
-        UNICODE_STRING  Unicode;
-        ANSI_STRING     Ansi;
-
-        status = ZwEnumerateKey(Key,
-                                Index,
-                                KeyBasicInformation,
-                                Basic,
-                                Size,
-                                &Ignore);
-        if (!NT_SUCCESS(status))
-            goto fail5;
-
-        Unicode.MaximumLength = (USHORT)Basic->NameLength;
-        Unicode.Buffer = Basic->Name;
-        Unicode.Length = (USHORT)Basic->NameLength;
-
-        Ansi.MaximumLength = (USHORT)((Basic->NameLength / sizeof (WCHAR)) + 
sizeof (CHAR));
-        Ansi.Buffer = __RegistryAllocate(Ansi.MaximumLength);
-
-        status = STATUS_NO_MEMORY;
-        if (Ansi.Buffer == NULL)
-            goto fail6;
-
-        status = RtlUnicodeStringToAnsiString(&Ansi, &Unicode, FALSE);
-        ASSERT(NT_SUCCESS(status));
-
-        Ansi.Length = (USHORT)(strlen(Ansi.Buffer) * sizeof (CHAR));
-
-        status = Callback(Context, Key, &Ansi);
-
-        __RegistryFree(Ansi.Buffer);
-        Ansi.Buffer = NULL;
-
-        if (!NT_SUCCESS(status))
-            goto fail7;
-    }
-
-    __RegistryFree(Basic);
-
-    __RegistryFree(Full);
-
-    return STATUS_SUCCESS;
-
-fail7:
-fail6:
-fail5:
-    __RegistryFree(Basic);
-
-fail4:
-fail3:
-    __RegistryFree(Full);
-
-fail2:
-fail1:
-    return status;
-}
-
-NTSTATUS
-RegistryEnumerateValues(
-    IN  HANDLE                      Key,
-    IN  NTSTATUS                    (*Callback)(PVOID, HANDLE, PANSI_STRING, 
ULONG),
-    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_OVERFLOW &&
-        status != STATUS_BUFFER_TOO_SMALL)
-        goto fail1;
-
-#pragma prefast(suppress:6102)
-    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++) {
-        ULONG           Ignore;
-        UNICODE_STRING  Unicode;
-        ANSI_STRING     Ansi;
-
-        status = ZwEnumerateValueKey(Key,
-                                     Index,
-                                     KeyValueBasicInformation,
-                                     Basic,
-                                     Size,
-                                     &Ignore);
-        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, Basic->Type);
-
-        __RegistryFree(Ansi.Buffer);
-
-        if (!NT_SUCCESS(status))
-            goto fail6;
-    }
-
-    __RegistryFree(Basic);
-
-    __RegistryFree(Full);
-
-    return STATUS_SUCCESS;
-
-fail6:
-fail5:
-    __RegistryFree(Basic);
-
-fail4:
-fail3:
-    __RegistryFree(Full);
-
-fail2:
-fail1:
-    return status;
-}
-
-NTSTATUS
-RegistryDeleteValue(
-    IN  PHANDLE         Key,
-    IN  PCHAR           Name
-    )
-{
-    ANSI_STRING         Ansi;
-    UNICODE_STRING      Unicode;
-    NTSTATUS            status;
-
-    RtlInitAnsiString(&Ansi, Name);
-
-    status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status = ZwDeleteValueKey(Key, &Unicode);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    RtlFreeUnicodeString(&Unicode);
-
-    (VOID) ZwFlushKey(Key);
-
-    return STATUS_SUCCESS;
-
-fail2:
-    RtlFreeUnicodeString(&Unicode);
-
-fail1:
-    return status;
-}
-
-NTSTATUS
-RegistryQueryDwordValue(
-    IN  HANDLE                      Key,
-    IN  PCHAR                       Name,
-    OUT PULONG                      Value
-    )
-{
-    ANSI_STRING                     Ansi;
-    UNICODE_STRING                  Unicode;
-    PKEY_VALUE_PARTIAL_INFORMATION  Partial;
-    ULONG                           Size;
-    NTSTATUS                        status;
-
-    RtlInitAnsiString(&Ansi, Name);
-
-    status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status = ZwQueryValueKey(Key,
-                             &Unicode,
-                             KeyValuePartialInformation,
-                             NULL,
-                             0,
-                             &Size);
-    if (status != STATUS_BUFFER_OVERFLOW &&
-        status != STATUS_BUFFER_TOO_SMALL)
-        goto fail2;
-
-#pragma prefast(suppress:6102)
-    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);
-
-    (VOID) ZwFlushKey(Key);
-
-    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 PULONG                      Type OPTIONAL,
-    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_OVERFLOW &&
-        status != STATUS_BUFFER_TOO_SMALL)
-        goto fail2;
-
-#pragma prefast(suppress:6102)
-    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;
-
-    if (Type != NULL)
-        *Type = Value->Type;
-
-    __RegistryFree(Value);
-
-    RtlFreeUnicodeString(&Unicode);
-
-    return STATUS_SUCCESS;
-
-fail5:
-fail4:
-    __RegistryFree(Value);
-
-fail3:
-fail2:
-    RtlFreeUnicodeString(&Unicode);
-
-fail1:
-    return status;
-}
-
-NTSTATUS
-RegistryQueryBinaryValue(
-    IN  HANDLE                      Key,
-    IN  PCHAR                       Name,
-    OUT PVOID                       *Buffer,
-    OUT PULONG                      Length
-    )
-{
-    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_OVERFLOW &&
-        status != STATUS_BUFFER_TOO_SMALL)
-        goto fail2;
-
-#pragma prefast(suppress:6102)
-    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;
-
-    switch (Partial->Type) {
-    case REG_BINARY:
-        *Buffer = __RegistryAllocate(Partial->DataLength);
-
-        status = STATUS_NO_MEMORY;
-        if (*Buffer == NULL)
-            break;
-
-        *Length = Partial->DataLength;
-        RtlCopyMemory(*Buffer, Partial->Data, Partial->DataLength);
-        break;
-
-    default:
-        status = STATUS_INVALID_PARAMETER;
-        *Buffer = NULL;
-        break;
-    }
-
-    if (*Buffer == NULL)
-        goto fail5;
-
-    __RegistryFree(Partial);
-
-    RtlFreeUnicodeString(&Unicode);
-
-    return STATUS_SUCCESS;
-
-fail5:
-fail4:
-    __RegistryFree(Partial);
-
-fail3:
-fail2:
-    RtlFreeUnicodeString(&Unicode);
-
-fail1:
-    return status;
-}
-
-NTSTATUS
-RegistryUpdateBinaryValue(
-    IN  HANDLE                      Key,
-    IN  PCHAR                       Name,
-    IN  PVOID                       Buffer,
-    IN  ULONG                       Length
-    )
-{
-    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) +
-                                 Length);
-
-    status = STATUS_NO_MEMORY;
-    if (Partial == NULL)
-        goto fail2;
-
-    Partial->TitleIndex = 0;
-    Partial->Type = REG_BINARY;
-    Partial->DataLength = Length;
-    RtlCopyMemory(Partial->Data, Buffer, Partial->DataLength);
-
-    status = ZwSetValueKey(Key,
-                           &Unicode,
-                           Partial->TitleIndex,
-                           Partial->Type,
-                           Partial->Data,
-                           Partial->DataLength);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    __RegistryFree(Partial);
-
-    (VOID) ZwFlushKey(Key);
-
-    RtlFreeUnicodeString(&Unicode);
-
-    return STATUS_SUCCESS;
-
-fail3:
-    __RegistryFree(Partial);
-
-fail2:
-    RtlFreeUnicodeString(&Unicode);
-
-fail1:
-
-    return status;
-}
-
-NTSTATUS
-RegistryQueryKeyName(
-    IN  HANDLE              Key,
-    OUT PANSI_STRING        *Array
-    )
-{
-    PKEY_NAME_INFORMATION   Value;
-    ULONG                   Size;
-    NTSTATUS                status;
-
-    status = ZwQueryKey(Key,
-                        KeyNameInformation,
-                        NULL,
-                        0,
-                        &Size);
-    if (status != STATUS_BUFFER_OVERFLOW &&
-        status != STATUS_BUFFER_TOO_SMALL)
-        goto fail1;
-
-    // Name information is not intrinsically NULL terminated
-#pragma prefast(suppress:6102)
-    Value = __RegistryAllocate(Size + sizeof (WCHAR));
-
-    status = STATUS_NO_MEMORY;
-    if (Value == NULL)
-        goto fail2;
-
-    status = ZwQueryKey(Key,
-                        KeyNameInformation,
-                        Value,
-                        Size,
-                        &Size);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    Value->Name[Value->NameLength / sizeof (WCHAR)] = L'\0';
-    *Array = RegistrySzToAnsi((PWCHAR)Value->Name);
-
-    status = STATUS_NO_MEMORY;
-    if (*Array == NULL)
-        goto fail4;
-
-    __RegistryFree(Value);
-
-    return STATUS_SUCCESS;
-
-fail4:
-fail3:
-    __RegistryFree(Value);
-
-fail2:
-fail1:
-    return status;
-}
-
-NTSTATUS
-RegistryQuerySystemStartOption(
-    IN  PCHAR                       Prefix,
-    OUT PANSI_STRING                *Value
-    )
-{
-    UNICODE_STRING                  Unicode;
-    HANDLE                          Key;
-    PANSI_STRING                    Ansi;
-    ULONG                           Length;
-    PCHAR                           Option;
-    PCHAR                           Context;
-    NTSTATUS                        status;
-
-    RtlInitUnicodeString(&Unicode, 
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control");
-
-    status = RegistryOpenKey(NULL, &Unicode, KEY_READ, &Key);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status = RegistryQuerySzValue(Key, "SystemStartOptions", NULL, &Ansi);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    // SystemStartOptions is a space separated list of options.
-    // Scan it looking for the one we want.
-    Length = (ULONG)strlen(Prefix);
-
-    Option = __strtok_r(Ansi[0].Buffer, " ", &Context);
-    while (Option != NULL) {
-        if (strncmp(Prefix, Option, Length) == 0)
-            goto found;
-
-        Option = __strtok_r(NULL, " ", &Context);
-    }
-
-    status = STATUS_OBJECT_NAME_NOT_FOUND;
-    goto fail3;
-
-found:
-    *Value = __RegistryAllocate(sizeof (ANSI_STRING) * 2);
-
-    status = STATUS_NO_MEMORY;
-    if (*Value == NULL)
-        goto fail4;
-
-    Length = (ULONG)strlen(Option);
-    (*Value)[0].MaximumLength = (USHORT)(Length + 1) * sizeof (CHAR);
-    (*Value)[0].Buffer = __RegistryAllocate((*Value)[0].MaximumLength);
-
-    status = STATUS_NO_MEMORY;
-    if ((*Value)[0].Buffer == NULL)
-        goto fail5;
-
-    RtlCopyMemory((*Value)[0].Buffer, Option, Length * sizeof (CHAR));
-
-    (*Value)[0].Length = (USHORT)Length * sizeof (CHAR);
-
-    RegistryFreeSzValue(Ansi);
-
-    ZwClose(Key);
-
-    return STATUS_SUCCESS;
-
-fail5:
-    __RegistryFree(*Value);
-
-fail4:
-fail3:
-    RegistryFreeSzValue(Ansi);
-
-fail2:
-    ZwClose(Key);
-
-fail1:
-    return status;
-}
-
-static PKEY_VALUE_PARTIAL_INFORMATION
-RegistryAnsiToSz(
-    PANSI_STRING                    Ansi
-    )
-{
-    ULONG                           Length;
-    PKEY_VALUE_PARTIAL_INFORMATION  Partial;
-    UNICODE_STRING                  Unicode;
-    NTSTATUS                        status;
-
-    Length = Ansi->Length + 1;
-    Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, 
Data) +
-                                 Length * sizeof (WCHAR));
-
-    status = STATUS_NO_MEMORY;
-    if (Partial == NULL)
-        goto fail1;
-
-    Partial->TitleIndex = 0;
-    Partial->Type = REG_SZ;
-    Partial->DataLength = Length * sizeof (WCHAR);
-
-    Unicode.MaximumLength = (UCHAR)Partial->DataLength;
-    Unicode.Buffer = (PWCHAR)Partial->Data;
-    Unicode.Length = 0;
-
-    status = RtlAnsiStringToUnicodeString(&Unicode, Ansi, FALSE);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    return Partial;
-
-fail2:
-    __RegistryFree(Partial);
-
-fail1:
-    return NULL;
-}
-
-static PKEY_VALUE_PARTIAL_INFORMATION
-RegistryAnsiToMultiSz(
-    PANSI_STRING                    Ansi
-    )
-{
-    ULONG                           Length;
-    ULONG                           Index;
-    PKEY_VALUE_PARTIAL_INFORMATION  Partial;
-    UNICODE_STRING                  Unicode;
-    NTSTATUS                        status;
-
-    Length = 1;
-    for (Index = 0; Ansi[Index].Buffer != NULL; Index++)
-        Length += Ansi[Index].Length + 1;
-
-    Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, 
Data) +
-                               Length * sizeof (WCHAR));
-
-    status = STATUS_NO_MEMORY;
-    if (Partial == NULL)
-        goto fail1;
-
-    Partial->TitleIndex = 0;
-    Partial->Type = REG_MULTI_SZ;
-    Partial->DataLength = Length * sizeof (WCHAR);
-
-    Unicode.MaximumLength = (USHORT)Partial->DataLength;
-    Unicode.Buffer = (PWCHAR)Partial->Data;
-    Unicode.Length = 0;
-
-    for (Index = 0; Ansi[Index].Buffer != NULL; Index++) {
-        status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi[Index], FALSE);
-        if (!NT_SUCCESS(status))
-            goto fail2;
-
-        Length = Unicode.Length / sizeof (WCHAR);
-
-        ASSERT3U(Unicode.MaximumLength, >=, (Length + 1) * sizeof (WCHAR));
-        Unicode.MaximumLength -= (USHORT)((Length + 1) * sizeof (WCHAR));
-        Unicode.Buffer += Length + 1;
-        Unicode.Length = 0;
-    }
-    *Unicode.Buffer = L'\0';
-
-    return Partial;
-
-fail2:
-    __RegistryFree(Partial);
-
-fail1:
-    return NULL;
-}
-
-NTSTATUS
-RegistryUpdateSzValue(
-    IN  HANDLE                      Key,
-    IN  PCHAR                       Name,
-    IN  ULONG                       Type,
-    IN  PANSI_STRING                Array
-    )
-{
-    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;
-
-    switch (Type) {
-    case REG_SZ:
-        status = STATUS_NO_MEMORY;
-        Partial = RegistryAnsiToSz(Array);
-        break;
-
-    case REG_MULTI_SZ:
-        status = STATUS_NO_MEMORY;
-        Partial = RegistryAnsiToMultiSz(Array);
-        break;
-
-    default:
-        status = STATUS_INVALID_PARAMETER;
-        Partial = NULL;
-        break;
-    }
-
-    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);
-
-    (VOID) ZwFlushKey(Key);
-
-    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
-RegistryFreeBinaryValue(
-    IN  PVOID   Buffer
-    )
-{
-    __RegistryFree(Buffer);
-}
-
-VOID
-RegistryCloseKey(
-    IN  HANDLE  Key
-    )
-{
-    ZwClose(Key);
-}
diff --git a/src/xendisk/registry.h b/src/xendisk/registry.h
deleted file mode 100644
index b33eb81..0000000
--- a/src/xendisk/registry.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/* Copyright (c) Xen Project.
- * Copyright (c) Cloud Software Group, 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 _XENDISK_REGISTRY_H
-#define _XENDISK_REGISTRY_H
-
-#include <ntddk.h>
-
-extern NTSTATUS
-RegistryInitialize(
-    IN  PDRIVER_OBJECT  DriverObject,
-    IN  PUNICODE_STRING Path
-    );
-
-extern VOID
-RegistryTeardown(
-    VOID
-    );
-
-extern NTSTATUS
-RegistryOpenKey(
-    IN  HANDLE          Parent,
-    IN  PUNICODE_STRING Path,
-    IN  ACCESS_MASK     DesiredAccess,
-    OUT PHANDLE         Key
-    );
-
-extern NTSTATUS
-RegistryCreateKey(
-    IN  HANDLE          Parent,
-    IN  PUNICODE_STRING Path,
-    IN  ULONG           Options,
-    OUT PHANDLE         Key
-    );
-
-extern NTSTATUS
-RegistryOpenServiceKey(
-    IN  ACCESS_MASK DesiredAccess,
-    OUT PHANDLE     Key
-    );
-
-extern NTSTATUS
-RegistryCreateServiceKey(
-    OUT PHANDLE     Key
-    );
-
-extern NTSTATUS
-RegistryOpenParametersKey(
-    IN  ACCESS_MASK DesiredAccess,
-    OUT PHANDLE     Key
-    );
-
-extern NTSTATUS
-RegistryOpenSoftwareKey(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  ACCESS_MASK     DesiredAccess,
-    OUT PHANDLE         Key
-    );
-
-extern NTSTATUS
-RegistryOpenHardwareKey(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  ACCESS_MASK     DesiredAccess,
-    OUT PHANDLE         Key
-    );
-
-extern NTSTATUS
-RegistryOpenSubKey(
-    IN  HANDLE      Key,
-    IN  PCHAR       Name,
-    IN  ACCESS_MASK DesiredAccess,
-    OUT PHANDLE     SubKey
-    );
-
-extern NTSTATUS
-RegistryCreateSubKey(
-    IN  HANDLE      Key,
-    IN  PCHAR       Name,
-    IN  ULONG       Options,
-    OUT PHANDLE     SubKey
-    );
-
-extern NTSTATUS
-RegistryDeleteSubKey(
-    IN  HANDLE      Key,
-    IN  PCHAR       Name
-    );
-
-extern NTSTATUS
-RegistryEnumerateSubKeys(
-    IN  HANDLE      Key,
-    IN  NTSTATUS    (*Callback)(PVOID, HANDLE, PANSI_STRING),
-    IN  PVOID       Context
-    );
-
-extern NTSTATUS
-RegistryEnumerateValues(
-    IN  HANDLE      Key,
-    IN  NTSTATUS    (*Callback)(PVOID, HANDLE, PANSI_STRING, ULONG),
-    IN  PVOID       Context
-    );
-
-extern NTSTATUS
-RegistryDeleteValue(
-    IN  HANDLE      Key,
-    IN  PCHAR       Name
-    );
-
-extern NTSTATUS
-RegistryQueryDwordValue(
-    IN  HANDLE          Key,
-    IN  PCHAR           Name,
-    OUT PULONG          Value
-    );
-
-extern NTSTATUS
-RegistryUpdateDwordValue(
-    IN  HANDLE          Key,
-    IN  PCHAR           Name,
-    IN  ULONG           Value
-    );
-
-extern NTSTATUS
-RegistryQuerySzValue(
-    IN  HANDLE          Key,
-    IN  PCHAR           Name,
-    OUT PULONG          Type OPTIONAL,
-    OUT PANSI_STRING    *Array
-    );
-
-extern NTSTATUS
-RegistryQueryBinaryValue(
-    IN  HANDLE          Key,
-    IN  PCHAR           Name,
-    OUT PVOID           *Buffer,
-    OUT PULONG          Length
-    );
-
-extern NTSTATUS
-RegistryUpdateBinaryValue(
-    IN  HANDLE          Key,
-    IN  PCHAR           Name,
-    IN  PVOID           Buffer,
-    IN  ULONG           Length
-    );
-
-extern NTSTATUS
-RegistryQueryKeyName(
-    IN  HANDLE              Key,
-    OUT PANSI_STRING        *Array
-    );
-
-extern NTSTATUS
-RegistryQuerySystemStartOption(
-    IN  PCHAR           Name,
-    OUT PANSI_STRING    *Option
-    );
-
-extern VOID
-RegistryFreeSzValue(
-    IN  PANSI_STRING    Array
-    );
-
-extern VOID
-RegistryFreeBinaryValue(
-    IN  PVOID           Buffer
-    );
-
-extern NTSTATUS
-RegistryUpdateSzValue(
-    IN  HANDLE          Key,
-    IN  PCHAR           Name,
-    IN  ULONG           Type,
-    IN  PANSI_STRING    Array
-    );
-
-extern VOID
-RegistryCloseKey(
-    IN  HANDLE  Key
-    );
-
-#endif  // _XENDISK_REGISTRY_H
diff --git a/src/xendisk/thread.c b/src/xendisk/thread.c
deleted file mode 100644
index 044c104..0000000
--- a/src/xendisk/thread.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/* Copyright (c) Xen Project.
- * Copyright (c) Cloud Software Group, 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 "thread.h"
-#include "debug.h"
-#include "assert.h"
-#include "util.h"
-
-#define THREAD_TAG 'ERHT'
-
-struct _XENDISK_THREAD {
-    XENDISK_THREAD_FUNCTION  Function;
-    PVOID                   Context;
-    KEVENT                  Event;
-    BOOLEAN                 Alerted;
-    LONG                    References;
-    PKTHREAD                Thread;
-};
-
-static FORCEINLINE PVOID
-__ThreadAllocate(
-    IN  ULONG   Length
-    )
-{
-    return __AllocatePoolWithTag(NonPagedPool, Length, THREAD_TAG);
-}
-
-static FORCEINLINE VOID
-__ThreadFree(
-    IN  PVOID   Buffer
-    )
-{
-    __FreePoolWithTag(Buffer, THREAD_TAG);
-}
-
-static FORCEINLINE VOID
-__ThreadWake(
-    IN  PXENDISK_THREAD Thread
-    )
-{
-    KeSetEvent(&Thread->Event, IO_NO_INCREMENT, FALSE);
-}
-
-VOID
-ThreadWake(
-    IN  PXENDISK_THREAD Thread
-    )
-{
-    __ThreadWake(Thread);
-}
-
-static FORCEINLINE VOID
-__ThreadAlert(
-    IN  PXENDISK_THREAD Thread
-    )
-{
-    Thread->Alerted = TRUE;
-    __ThreadWake(Thread);
-}
-
-VOID
-ThreadAlert(
-    IN  PXENDISK_THREAD Thread
-    )
-{
-    __ThreadAlert(Thread);
-}
-
-KSTART_ROUTINE  ThreadFunction;
-
-VOID
-ThreadFunction(
-    IN  PVOID       Argument
-    )
-{
-    PXENDISK_THREAD Self = Argument;
-    NTSTATUS        status;
-
-    status = Self->Function(Self, Self->Context);
-
-    if (InterlockedDecrement(&Self->References) == 0)
-        __ThreadFree(Self);
-
-    PsTerminateSystemThread(status);
-    // NOT REACHED
-}
-
-__drv_requiresIRQL(PASSIVE_LEVEL)
-NTSTATUS
-ThreadCreate(
-    IN  XENDISK_THREAD_FUNCTION Function,
-    IN  PVOID                   Context,
-    OUT PXENDISK_THREAD         *Thread
-    )
-{
-    HANDLE                      Handle;
-    NTSTATUS                    status;
-
-    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
-
-    (*Thread) = __ThreadAllocate(sizeof (XENDISK_THREAD));
-
-    status = STATUS_NO_MEMORY;
-    if (*Thread == NULL)
-        goto fail1;
-
-    (*Thread)->Function = Function;
-    (*Thread)->Context = Context;
-    (*Thread)->Alerted = FALSE;
-    (*Thread)->References = 2; // One for us, one for the thread function
-
-    KeInitializeEvent(&(*Thread)->Event, NotificationEvent, FALSE);
-
-    status = PsCreateSystemThread(&Handle,
-                                  STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
-                                  NULL,
-                                  NULL,
-                                  NULL,
-                                  ThreadFunction,
-                                  *Thread);
-    if (!NT_SUCCESS(status)) {
-        --(*Thread)->References;    // Fake thread function termination
-        goto fail2;
-    }
-
-    status = ObReferenceObjectByHandle(Handle,
-                                       SYNCHRONIZE,
-                                       *PsThreadType,
-                                       KernelMode,
-                                       &(*Thread)->Thread,
-                                       NULL);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    ZwClose(Handle);
-
-    return STATUS_SUCCESS;
-
-fail3:
-    Error("fail3\n");
-
-    __ThreadAlert(*Thread);
-    ZwClose(Handle);
-
-fail2:
-    Error("fail2\n");
-
-    if (InterlockedDecrement(&(*Thread)->References) == 0)
-        __ThreadFree(*Thread);
-
-    *Thread = NULL;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
-}
-
-PKEVENT
-ThreadGetEvent(
-    IN  PXENDISK_THREAD Thread
-    )
-{
-    return &Thread->Event;
-}
-
-BOOLEAN
-ThreadIsAlerted(
-    IN  PXENDISK_THREAD Thread
-    )
-{
-    return Thread->Alerted;
-}
-
-VOID
-ThreadJoin(
-    IN  PXENDISK_THREAD Thread
-    )
-{
-    LONG                References;
-
-    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
-    ASSERT3P(KeGetCurrentThread(), !=, Thread->Thread);
-
-    (VOID) KeWaitForSingleObject(Thread->Thread,
-                                 Executive,
-                                 KernelMode,
-                                 FALSE,
-                                 NULL);
-
-    References = InterlockedDecrement(&Thread->References);
-    ASSERT3U(References, ==, 0);
-
-    __ThreadFree(Thread);
-}
diff --git a/src/xendisk/thread.h b/src/xendisk/thread.h
deleted file mode 100644
index d778943..0000000
--- a/src/xendisk/thread.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Copyright (c) Xen Project.
- * Copyright (c) Cloud Software Group, 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 _XENDISK_THREAD_H
-#define _XENDISK_THREAD_H
-
-#include <ntddk.h>
-
-typedef struct _XENDISK_THREAD XENDISK_THREAD, *PXENDISK_THREAD;
-
-typedef NTSTATUS (*XENDISK_THREAD_FUNCTION)(PXENDISK_THREAD, PVOID);
-
-__drv_requiresIRQL(PASSIVE_LEVEL)
-extern NTSTATUS
-ThreadCreate(
-    IN  XENDISK_THREAD_FUNCTION Function,
-    IN  PVOID                   Context,
-    OUT PXENDISK_THREAD         *Thread
-    );
-
-extern PKEVENT
-ThreadGetEvent(
-    IN  PXENDISK_THREAD Self
-    );
-
-extern BOOLEAN
-ThreadIsAlerted(
-    IN  PXENDISK_THREAD Self
-    );
-
-extern VOID
-ThreadWake(
-    IN  PXENDISK_THREAD Thread
-    );
-
-extern VOID
-ThreadAlert(
-    IN  PXENDISK_THREAD Thread
-    );
-
-extern VOID
-ThreadJoin(
-    IN  PXENDISK_THREAD Thread
-    );
-
-#endif  // _XENDISK_THREAD_H
diff --git a/src/xendisk/types.h b/src/xendisk/types.h
deleted file mode 100644
index 500c28c..0000000
--- a/src/xendisk/types.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Copyright (c) Xen Project.
- * Copyright (c) Cloud Software Group, 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 _XENDISK_TYPES_H
-#define _XENDISK_TYPES_H
-
-typedef enum _DEVICE_OBJECT_TYPE {
-    PHYSICAL_DEVICE_OBJECT = 'ODP',
-    FUNCTION_DEVICE_OBJECT = 'ODF'
-} DEVICE_OBJECT_TYPE, *PDEVICE_OBJECT_TYPE;
-
-typedef enum _DEVICE_PNP_STATE {
-    Invalid = 0,
-    Present,        // PDO only
-    Enumerated,     // PDO only
-    Added,          // FDO only
-    Started,
-    StopPending,
-    Stopped,
-    RemovePending,
-    SurpriseRemovePending,
-    Deleted
-} DEVICE_PNP_STATE, *PDEVICE_PNP_STATE;
-
-#endif  // _XENDISK_TYPES_H
diff --git a/src/xendisk/xendisk.rc b/src/xendisk/xendisk.rc
deleted file mode 100644
index a863007..0000000
--- a/src/xendisk/xendisk.rc
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Copyright (c) Xen Project.
- * Copyright (c) Cloud Software Group, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms,
- * with or without modification, are permitted provided
- * that the following conditions are met:
- *
- * *   Redistributions of source code must retain the above
- *     copyright notice, this list of conditions and the
- *     following disclaimer.
- * *   Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the
- *     following disclaimer in the documentation and/or other
- *     materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <windows.h>
-#include <ntverp.h>
-
-
-#undef VER_COMPANYNAME_STR
-#undef VER_PRODUCTNAME_STR
-#undef VER_PRODUCTVERSION
-#undef VER_PRODUCTVERSION_STR
-
-#include <version.h>
-
-#define        VER_COMPANYNAME_STR         VENDOR_NAME_STR
-#define VER_LEGALCOPYRIGHT_STR      COPYRIGHT_STR
-
-#define VER_PRODUCTNAME_STR         "XENDISK"
-#define VER_PRODUCTVERSION          
MAJOR_VERSION,MINOR_VERSION,MICRO_VERSION,BUILD_NUMBER
-#define VER_PRODUCTVERSION_STR      MAJOR_VERSION_STR "." MINOR_VERSION_STR 
"." MICRO_VERSION_STR "." BUILD_NUMBER_STR
-
-#define VER_INTERNALNAME_STR        "XENDISK.SYS"
-#define VER_FILEDESCRIPTION_STR     "XENDISK"
-
-#define VER_FILETYPE                VFT_DRV
-#define VER_FILESUBTYPE             VFT2_DRV_SYSTEM
-
-#include <common.ver>
diff --git a/src/xenvbd.inf b/src/xenvbd.inf
index 19e92c9..f5e1614 100644
--- a/src/xenvbd.inf
+++ b/src/xenvbd.inf
@@ -2,45 +2,45 @@
 ; Copyright (c) Cloud Software Group, Inc.
 ; All rights reserved.
 ;
-; Redistribution and use in source and binary forms,
-; with or without modification, are permitted provided
+; 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
+; *   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
+; *   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
+; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+; CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+; INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 ; SUCH DAMAGE.
-
-[Version]
-Signature="$Windows NT$"
+
+[Version]
+Signature="$Windows NT$"
 Class=SCSIAdapter
-ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318}
-Provider=%Vendor%
+ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318}
+Provider=%Vendor%
 CatalogFile=xenvbd.cat
 
DriverVer=@INF_DATE@,@MAJOR_VERSION@.@MINOR_VERSION@.@MICRO_VERSION@.@BUILD_NUMBER@
 DriverPackageDisplayName=%DiskDesc%
 PnpLockdown=1

-[DestinationDirs]
-DefaultDestDir=12
+[DestinationDirs]
+DefaultDestDir=12

 [SourceDisksNames]
 0=%DiskDesc%
@@ -48,9 +48,8 @@ DefaultDestDir=12
 [SourceDisksFiles]
 xenvbd.sys=0,,
 xencrsh.sys=0,,
-xendisk.sys=0,,

-[Manufacturer]
+[Manufacturer]
 %Vendor%=Inst,NT@INF_ARCH@

 [Inst.NT@INF_ARCH@]
@@ -59,7 +58,7 @@ 
XENBUS\VEN_@VENDOR_PREFIX@@VENDOR_DEVICE_ID@&DEV_VBD&REV_0900000B,\
 XENBUS\VEN_@VENDOR_PREFIX@0001&DEV_VBD&REV_0900000B,\
 XENBUS\VEN_@VENDOR_PREFIX@0002&DEV_VBD&REV_0900000B

-[XenVbd_Inst]
+[XenVbd_Inst]
 CopyFiles=XenVbd_Copyfiles
 ; TODO: Remove during next PDO version bump
 FeatureScore=0xFE
@@ -67,43 +66,23 @@ FeatureScore=0xFE
 [XenVbd_Copyfiles]
 xenvbd.sys
 xencrsh.sys
-xendisk.sys
-
-[XenVbd_Inst.HW]
-AddReg=XenVbd_AddReg
-
-[XenVbd_AddReg]
-HKR,,"UpperFilters",0x00010000,"xendisk"

-[XenVbd_Inst.Services]
+[XenVbd_Inst.Services]
 AddService=xenvbd,2,XenVbd_Service,
-AddService=xendisk,,XenDisk_Service,

-[XenDisk_Service]
-DisplayName=%XenDiskName%
+[XenVbd_Service]
+DisplayName=%XenVbdName%
 ServiceType=%SERVICE_KERNEL_DRIVER%
 StartType=%SERVICE_BOOT_START%
 ErrorControl=%SERVICE_ERROR_NORMAL%
-ServiceBinary=%12%\xendisk.sys
-LoadOrderGroup="Scsi Miniport"
-AddReg=XenDisk_Parameters
-
-[XenDisk_Parameters]
-HKR,"Parameters",,0x00000010
-
-[XenVbd_Service]
-DisplayName=%XenVbdName%
-ServiceType=%SERVICE_KERNEL_DRIVER%
-StartType=%SERVICE_BOOT_START%
-ErrorControl=%SERVICE_ERROR_NORMAL%
-ServiceBinary=%12%\xenvbd.sys
+ServiceBinary=%12%\xenvbd.sys
 LoadOrderGroup="Scsi Miniport"
 AddReg=XenVbd_Parameters, XenVbd_Unplug, XenVbd_Extras

-[XenVbd_Parameters]
+[XenVbd_Parameters]
 HKR,"Parameters",,0x00000010
-HKR,"Parameters","BusType",0x00010001,0x00000001
-HKR,"Parameters\PnpInterface","5",0x00010001,0x00000001
+HKR,"Parameters","BusType",0x00010001,0x00000001
+HKR,"Parameters\PnpInterface","5",0x00010001,0x00000001
 HKR,"Parameters","max-ring-page-order",0x00010001,0x00000001
 HKR,"Parameters","multi-queue-max-queues",0x00010001,0x00000002

@@ -120,23 +99,22 @@ HKLM,%DiskKey%,"TimeOutValue",0x00010001,120
 [Strings]

 Vendor = "@VENDOR_NAME@"
-DiskDesc = "@PRODUCT_NAME@ PV Storage Host Adapter Package"
+DiskDesc = "@PRODUCT_NAME@ PV Storage Host Adapter Package"
 XenVbdName= "@PRODUCT_NAME@ PV Storage Host Adapter"
-XenDiskName= "@PRODUCT_NAME@ PV Storage Filter"
 UnplugKey="SYSTEM\CurrentControlSet\Services\XEN\Unplug"
 ForceUnplugKey="SYSTEM\CurrentControlSet\Services\XEN\ForceUnplug"
 PnpKey="SYSTEM\CurrentControlSet\Control\Pnp"
 PartMgrKey="SYSTEM\CurrentControlSet\Services\PartMgr\Parameters"
 DiskKey="SYSTEM\CurrentControlSet\Services\Disk"

-SERVICE_BOOT_START = 0x0
-SERVICE_SYSTEM_START = 0x1
-SERVICE_AUTO_START = 0x2
-SERVICE_DEMAND_START = 0x3
-SERVICE_DISABLED = 0x4
-
-SERVICE_KERNEL_DRIVER = 0x1
-SERVICE_ERROR_IGNORE = 0x0
-SERVICE_ERROR_NORMAL = 0x1
-SERVICE_ERROR_SEVERE = 0x2
-SERVICE_ERROR_CRITICAL = 0x3
+SERVICE_BOOT_START = 0x0
+SERVICE_SYSTEM_START = 0x1
+SERVICE_AUTO_START = 0x2
+SERVICE_DEMAND_START = 0x3
+SERVICE_DISABLED = 0x4
+
+SERVICE_KERNEL_DRIVER = 0x1
+SERVICE_ERROR_IGNORE = 0x0
+SERVICE_ERROR_NORMAL = 0x1
+SERVICE_ERROR_SEVERE = 0x2
+SERVICE_ERROR_CRITICAL = 0x3
diff --git a/src/xenvbd/target.c b/src/xenvbd/target.c
index 2cae479..6929276 100644
--- a/src/xenvbd/target.c
+++ b/src/xenvbd/target.c
@@ -403,7 +403,7 @@ TargetModeSense(

     // Header
     Data->MediumType                = 0;
-    Data->DeviceSpecificParameter   = FrontendGetReadOnly(Target->Frontend) ?
+    Data->DeviceSpecificParameter   = FrontendGetReadOnly(Target->Frontend) ?
                                                     MODE_DSP_WRITE_PROTECT : 0;
     Size = sizeof(MODE_PARAMETER_HEADER);

@@ -448,7 +448,7 @@ TargetModeSense10(

     // Header
     Data->MediumType                = 0;
-    Data->DeviceSpecificParameter   = FrontendGetReadOnly(Target->Frontend) ?
+    Data->DeviceSpecificParameter   = FrontendGetReadOnly(Target->Frontend) ?
                                                     MODE_DSP_WRITE_PROTECT : 0;
     Size = sizeof(MODE_PARAMETER_HEADER10);

@@ -462,7 +462,7 @@ TargetModeSense10(
     ASSERT3U(ModeDataLength, <=, 65535 - (sizeof(MODE_PARAMETER_HEADER10) - 
2));
     ASSERT3U(BlockDescrLength, <=, 65535);

-    *(PUSHORT)Data->ModeDataLength = _byteswap_ushort((USHORT)ModeDataLength +
+    *(PUSHORT)Data->ModeDataLength = _byteswap_ushort((USHORT)ModeDataLength +
                                                       
sizeof(MODE_PARAMETER_HEADER10) - 2);
     *(PUSHORT)Data->BlockDescriptorLength = 
_byteswap_ushort((USHORT)BlockDescrLength);

diff --git a/vs2019/package/package.vcxproj b/vs2019/package/package.vcxproj
index 764cfef..1a553d7 100644
--- a/vs2019/package/package.vcxproj
+++ b/vs2019/package/package.vcxproj
@@ -50,9 +50,6 @@
     <ProjectReference Include="..\xenvbd\xenvbd.vcxproj">
       <Project>{ef236371-3145-41b1-99c9-82b33e353f17}</Project>
     </ProjectReference>
-    <ProjectReference Include="..\xendisk\xendisk.vcxproj">
-      <Project>{d7411b2c-2c43-434d-9f56-e10a3d2f5bad}</Project>
-    </ProjectReference>
     <FilesToPackage Include="..\xenvbd.inf" />
   </ItemGroup>
   <ItemGroup Condition="Exists('$(DPINST_REDIST)')">
diff --git a/vs2019/xendisk/xendisk.vcxproj b/vs2019/xendisk/xendisk.vcxproj
deleted file mode 100644
index 25b195f..0000000
--- a/vs2019/xendisk/xendisk.vcxproj
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="15.0" 
xmlns="http://schemas.microsoft.com/developer/msbuild/2003";>
-  <Import Project="..\configs.props" />
-  <PropertyGroup Label="PropertySheets">
-    <DriverType>WDM</DriverType>
-    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
-    <ConfigurationType>Driver</ConfigurationType>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}</ProjectGuid>
-  </PropertyGroup>
-  <Import Project="..\targets.props" />
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <PropertyGroup>
-    <EnableInf2cat>false</EnableInf2cat>
-    <IntDir>..\$(ProjectName)\$(ConfigurationName)\$(Platform)\</IntDir>
-    <OutDir>..\$(ConfigurationName)\$(Platform)\</OutDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup>
-    <ClCompile>
-      <AdditionalOptions>/ZH:SHA_256 %(AdditionalOptions)</AdditionalOptions>
-      
<AdditionalIncludeDirectories>..\..\include;..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      
<PreprocessorDefinitions>PROJECT=$(ProjectName);POOL_NX_OPTIN=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <WarningLevel>EnableAllWarnings</WarningLevel>
-      
<DisableSpecificWarnings>4061;4464;4548;4770;4711;4820;4668;4255;5045;6001;6054;26451;28196;30030;30029;%(DisableSpecificWarnings)</DisableSpecificWarnings>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-    </ClCompile>
-    <ResourceCompile>
-      
<AdditionalIncludeDirectories>..\..\include;..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-    </ResourceCompile>
-    <Link>
-      
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalOptions>/INTEGRITYCHECK 
%(AdditionalOptions)</AdditionalOptions>
-      
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
-      <CETCompat>true</CETCompat>
-      <GenerateMapFile>true</GenerateMapFile>
-      <MapExports>true</MapExports>
-    </Link>
-    <DriverSign>
-      <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
-    </DriverSign>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
-    <ClCompile>
-      
<PreprocessorDefinitions>__i386__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-    </ClCompile>
-    <Link>
-      <ImageHasSafeExceptionHandlers>true</ImageHasSafeExceptionHandlers>
-    </Link>  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Platform)'=='x64'">
-    <ClCompile>
-      
<PreprocessorDefinitions>__x86_64__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-    </ClCompile>
-    <Link>
-      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)'=='Windows 10 Release'">
-    <ClCompile>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <WholeProgramOptimization>true</WholeProgramOptimization>
-      <AdditionalOptions>/Qspectre %(AdditionalOptions)</AdditionalOptions>
-    </ClCompile>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <FilesToPackage Include="$(TargetPath)" />
-    <FilesToPackage Include="$(OutDir)$(TargetName).pdb" />
-    <FilesToPackage Include="$(OutDir)$(TargetName).map" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="../../src/xendisk/driver.c" />
-    <ClCompile Include="../../src/xendisk/fdo.c" />
-    <ClCompile Include="../../src/xendisk/pdo.c" />
-    <ClCompile Include="../../src/xendisk/registry.c" />
-    <ClCompile Include="../../src/xendisk/thread.c" />
-  </ItemGroup>
-  <ItemGroup>
-    <ResourceCompile Include="..\..\src\xendisk\xendisk.rc" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-</Project>
diff --git a/vs2019/xendisk/xendisk.vcxproj.user 
b/vs2019/xendisk/xendisk.vcxproj.user
deleted file mode 100644
index e1315db..0000000
--- a/vs2019/xendisk/xendisk.vcxproj.user
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="15.0" 
xmlns="http://schemas.microsoft.com/developer/msbuild/2003";>
-  <PropertyGroup>
-    <SignMode>TestSign</SignMode>
-    <TestCertificate>..\..\src\xenvbd.pfx</TestCertificate>
-    
<TimeStampServer>http://timestamp.verisign.com/scripts/timstamp.dll</TimeStampServer>
-  </PropertyGroup>
-</Project>
diff --git a/vs2019/xenvbd.sln b/vs2019/xenvbd.sln
index 2b6a09e..1777096 100644
--- a/vs2019/xenvbd.sln
+++ b/vs2019/xenvbd.sln
@@ -15,17 +15,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = 
"xencrsh", "xencrsh\xencrsh.
                {65FA97EA-A569-4FC1-BFE7-D68E109143F7} = 
{65FA97EA-A569-4FC1-BFE7-D68E109143F7}
        EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xendisk", 
"xendisk\xendisk.vcxproj", "{D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}"
-       ProjectSection(ProjectDependencies) = postProject
-               {65FA97EA-A569-4FC1-BFE7-D68E109143F7} = 
{65FA97EA-A569-4FC1-BFE7-D68E109143F7}
-       EndProjectSection
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "package", 
"package\package.vcxproj", "{AB8DAED3-9D70-4907-99A3-C643F1FC1972}"
        ProjectSection(ProjectDependencies) = postProject
                {65FA97EA-A569-4FC1-BFE7-D68E109143F7} = 
{65FA97EA-A569-4FC1-BFE7-D68E109143F7}
                {58F5BC43-B92E-4A2B-975D-0066EAB29092} = 
{58F5BC43-B92E-4A2B-975D-0066EAB29092}
                {EF236371-3145-41B1-99C9-82B33E353F17} = 
{EF236371-3145-41B1-99C9-82B33E353F17}
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD} = 
{D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}
        EndProjectSection
 EndProject
 Global
@@ -44,14 +38,6 @@ Global
                {65FA97EA-A569-4FC1-BFE7-D68E109143F7}.Windows 10 
Release|Win32.Build.0 = Windows 10 Release|Win32
                {65FA97EA-A569-4FC1-BFE7-D68E109143F7}.Windows 10 
Release|x64.ActiveCfg = Windows 10 Release|x64
                {65FA97EA-A569-4FC1-BFE7-D68E109143F7}.Windows 10 
Release|x64.Build.0 = Windows 10 Release|x64
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}.Windows 10 
Debug|Win32.ActiveCfg = Windows 10 Debug|Win32
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}.Windows 10 
Debug|Win32.Build.0 = Windows 10 Debug|Win32
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}.Windows 10 
Debug|x64.ActiveCfg = Windows 10 Debug|x64
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}.Windows 10 
Debug|x64.Build.0 = Windows 10 Debug|x64
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}.Windows 10 
Release|Win32.ActiveCfg = Windows 10 Release|Win32
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}.Windows 10 
Release|Win32.Build.0 = Windows 10 Release|Win32
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}.Windows 10 
Release|x64.ActiveCfg = Windows 10 Release|x64
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}.Windows 10 
Release|x64.Build.0 = Windows 10 Release|x64
                {EF236371-3145-41B1-99C9-82B33E353F17}.Windows 10 
Debug|Win32.ActiveCfg = Windows 10 Debug|Win32
                {EF236371-3145-41B1-99C9-82B33E353F17}.Windows 10 
Debug|Win32.Build.0 = Windows 10 Debug|Win32
                {EF236371-3145-41B1-99C9-82B33E353F17}.Windows 10 
Debug|x64.ActiveCfg = Windows 10 Debug|x64
diff --git a/vs2022/package/package.vcxproj b/vs2022/package/package.vcxproj
index 2a7d9f2..9c7c813 100644
--- a/vs2022/package/package.vcxproj
+++ b/vs2022/package/package.vcxproj
@@ -49,9 +49,6 @@
     <ProjectReference Include="..\xenvbd\xenvbd.vcxproj">
       <Project>{ef236371-3145-41b1-99c9-82b33e353f17}</Project>
     </ProjectReference>
-    <ProjectReference Include="..\xendisk\xendisk.vcxproj">
-      <Project>{d7411b2c-2c43-434d-9f56-e10a3d2f5bad}</Project>
-    </ProjectReference>
     <FilesToPackage Include="..\xenvbd.inf" />
   </ItemGroup>
   <ItemGroup Condition="Exists('$(DPINST_REDIST)')">
diff --git a/vs2022/xendisk/xendisk.vcxproj b/vs2022/xendisk/xendisk.vcxproj
deleted file mode 100644
index d7df663..0000000
--- a/vs2022/xendisk/xendisk.vcxproj
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="15.0" 
xmlns="http://schemas.microsoft.com/developer/msbuild/2003";>
-  <Import Project="..\configs.props" />
-  <PropertyGroup Label="PropertySheets">
-    <DriverType>WDM</DriverType>
-    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
-    <ConfigurationType>Driver</ConfigurationType>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}</ProjectGuid>
-  </PropertyGroup>
-  <Import Project="..\targets.props" />
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <PropertyGroup>
-    <EnableInf2cat>false</EnableInf2cat>
-    <IntDir>..\$(ProjectName)\$(ConfigurationName)\$(Platform)\</IntDir>
-    <OutDir>..\$(ConfigurationName)\$(Platform)\</OutDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup>
-    <ClCompile>
-      <AdditionalOptions>/ZH:SHA_256 %(AdditionalOptions)</AdditionalOptions>
-      
<AdditionalIncludeDirectories>..\..\include;..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      
<PreprocessorDefinitions>PROJECT=$(ProjectName);POOL_NX_OPTIN=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <WarningLevel>EnableAllWarnings</WarningLevel>
-      
<DisableSpecificWarnings>4061;4464;4548;4770;4711;4820;4668;4255;5045;6001;6054;26451;28196;30030;30029;%(DisableSpecificWarnings)</DisableSpecificWarnings>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-    </ClCompile>
-    <ResourceCompile>
-      
<AdditionalIncludeDirectories>..\..\include;..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-    </ResourceCompile>
-    <Link>
-      
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalOptions>/INTEGRITYCHECK 
%(AdditionalOptions)</AdditionalOptions>
-      
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
-      <CETCompat>true</CETCompat>
-      <GenerateMapFile>true</GenerateMapFile>
-      <MapExports>true</MapExports>
-    </Link>
-    <DriverSign>
-      <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
-    </DriverSign>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Platform)'=='x64'">
-    <ClCompile>
-      
<PreprocessorDefinitions>__x86_64__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-    </ClCompile>
-    <Link>
-      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)'=='Windows 10 Release'">
-    <ClCompile>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <WholeProgramOptimization>true</WholeProgramOptimization>
-      <AdditionalOptions>/Qspectre %(AdditionalOptions)</AdditionalOptions>
-    </ClCompile>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <FilesToPackage Include="$(TargetPath)" />
-    <FilesToPackage Include="$(OutDir)$(TargetName).pdb" />
-    <FilesToPackage Include="$(OutDir)$(TargetName).map" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="../../src/xendisk/driver.c" />
-    <ClCompile Include="../../src/xendisk/fdo.c" />
-    <ClCompile Include="../../src/xendisk/pdo.c" />
-    <ClCompile Include="../../src/xendisk/registry.c" />
-    <ClCompile Include="../../src/xendisk/thread.c" />
-  </ItemGroup>
-  <ItemGroup>
-    <ResourceCompile Include="..\..\src\xendisk\xendisk.rc" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-</Project>
diff --git a/vs2022/xendisk/xendisk.vcxproj.user 
b/vs2022/xendisk/xendisk.vcxproj.user
deleted file mode 100644
index e1315db..0000000
--- a/vs2022/xendisk/xendisk.vcxproj.user
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="15.0" 
xmlns="http://schemas.microsoft.com/developer/msbuild/2003";>
-  <PropertyGroup>
-    <SignMode>TestSign</SignMode>
-    <TestCertificate>..\..\src\xenvbd.pfx</TestCertificate>
-    
<TimeStampServer>http://timestamp.verisign.com/scripts/timstamp.dll</TimeStampServer>
-  </PropertyGroup>
-</Project>
diff --git a/vs2022/xenvbd.sln b/vs2022/xenvbd.sln
index 407f395..a302a38 100644
--- a/vs2022/xenvbd.sln
+++ b/vs2022/xenvbd.sln
@@ -15,17 +15,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = 
"xencrsh", "xencrsh\xencrsh.
                {65FA97EA-A569-4FC1-BFE7-D68E109143F7} = 
{65FA97EA-A569-4FC1-BFE7-D68E109143F7}
        EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xendisk", 
"xendisk\xendisk.vcxproj", "{D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}"
-       ProjectSection(ProjectDependencies) = postProject
-               {65FA97EA-A569-4FC1-BFE7-D68E109143F7} = 
{65FA97EA-A569-4FC1-BFE7-D68E109143F7}
-       EndProjectSection
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "package", 
"package\package.vcxproj", "{AB8DAED3-9D70-4907-99A3-C643F1FC1972}"
        ProjectSection(ProjectDependencies) = postProject
                {65FA97EA-A569-4FC1-BFE7-D68E109143F7} = 
{65FA97EA-A569-4FC1-BFE7-D68E109143F7}
                {58F5BC43-B92E-4A2B-975D-0066EAB29092} = 
{58F5BC43-B92E-4A2B-975D-0066EAB29092}
                {EF236371-3145-41B1-99C9-82B33E353F17} = 
{EF236371-3145-41B1-99C9-82B33E353F17}
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD} = 
{D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}
        EndProjectSection
 EndProject
 Global
@@ -38,10 +32,6 @@ Global
                {65FA97EA-A569-4FC1-BFE7-D68E109143F7}.Windows 10 
Debug|x64.Build.0 = Windows 10 Debug|x64
                {65FA97EA-A569-4FC1-BFE7-D68E109143F7}.Windows 10 
Release|x64.ActiveCfg = Windows 10 Release|x64
                {65FA97EA-A569-4FC1-BFE7-D68E109143F7}.Windows 10 
Release|x64.Build.0 = Windows 10 Release|x64
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}.Windows 10 
Debug|x64.ActiveCfg = Windows 10 Debug|x64
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}.Windows 10 
Debug|x64.Build.0 = Windows 10 Debug|x64
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}.Windows 10 
Release|x64.ActiveCfg = Windows 10 Release|x64
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}.Windows 10 
Release|x64.Build.0 = Windows 10 Release|x64
                {EF236371-3145-41B1-99C9-82B33E353F17}.Windows 10 
Debug|x64.ActiveCfg = Windows 10 Debug|x64
                {EF236371-3145-41B1-99C9-82B33E353F17}.Windows 10 
Debug|x64.Build.0 = Windows 10 Debug|x64
                {EF236371-3145-41B1-99C9-82B33E353F17}.Windows 10 
Release|x64.ActiveCfg = Windows 10 Release|x64
--
2.51.2.windows.1



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.