From win-pv-devel-bounces@lists.xenproject.org Tue Mar 03 09:36:41 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Tue, 03 Mar 2026 09:36:41 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1244586.1544023 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxMBF-0002EA-FM; Tue, 03 Mar 2026 09:36:41 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1244586.1544023; Tue, 03 Mar 2026 09:36:41 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxMBF-0002E3-Bo; Tue, 03 Mar 2026 09:36:41 +0000
Received: by outflank-mailman (input) for mailman id 1244586;
 Tue, 03 Mar 2026 09:36:39 +0000
Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254]
 helo=se1-gles-sth1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=jlLD=BD=citrix.com=owen.smith@srs-se1.protection.inumbo.net>)
 id 1vxMBD-0002BK-Rz
 for win-pv-devel@lists.xenproject.org; Tue, 03 Mar 2026 09:36:39 +0000
Received: from na1pdmzitismtp01.tibco.com (na1pdmzitismtp01.tibco.com
 [160.101.131.8]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS
 id 774d6f3b-16e4-11f1-b164-2bf370ae4941;
 Tue, 03 Mar 2026 10:36:35 +0100 (CET)
Received: from mewpvdipd2033.citrite.net (unknown [10.113.48.64])
 by na1pdmzitismtp01.tibco.com (Postfix) with ESMTP id 12553417BB8E;
 Tue,  3 Mar 2026 04:36:10 -0500 (EST)
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: 774d6f3b-16e4-11f1-b164-2bf370ae4941
From: Owen Smith <owen.smith@citrix.com>
To: win-pv-devel@lists.xenproject.org
Cc: Owen Smith <owen.smith@citrix.com>
Subject: [PATCH 3/4 v2] Consolidate macro'ed access to properties
Date: Tue,  3 Mar 2026 09:36:27 +0000
Message-ID: <20260303093628.1743-3-owen.smith@citrix.com>
X-Mailer: git-send-email 2.51.2.windows.1
In-Reply-To: <20260303093628.1743-1-owen.smith@citrix.com>
References: <20260303093628.1743-1-owen.smith@citrix.com>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit

Replace specific accessors for members of the XENVBD_CAPS,
XENVBD_FEATURES and XENVBD_DISKINFO structures, with an
accessor for the structure, and direct accesses for the structure
members.
Remove all manually implemented FrontendGet* accessors, using a
new macro for returning a pointer to a member.

Signed-off-by: Owen Smith <owen.smith@citrix.com>
---
 src/xenvbd/frontend.c | 85 +++++++++++--------------------------------
 src/xenvbd/frontend.h |  9 +----
 src/xenvbd/target.c   | 29 +++++++++------
 3 files changed, 40 insertions(+), 83 deletions(-)

diff --git a/src/xenvbd/frontend.c b/src/xenvbd/frontend.c
index 912fc7e..ef60f9c 100644
--- a/src/xenvbd/frontend.c
+++ b/src/xenvbd/frontend.c
@@ -130,6 +130,23 @@ FrontendGet ## _name ## (                       \
     return __FrontendGet ## _name ## (Frontend);\
 }
 
+
+#define FRONTEND_GET_PROPERTY_PTR(_name, _type) \
+static FORCEINLINE _type                        \
+__FrontendGet ## _name ## (                     \
+    IN  PXENVBD_FRONTEND    Frontend            \
+    )                                           \
+{                                               \
+    return &Frontend-> ## _name ## ;            \
+}                                               \
+_type                                           \
+FrontendGet ## _name ## (                       \
+    IN  PXENVBD_FRONTEND    Frontend            \
+    )                                           \
+{                                               \
+    return __FrontendGet ## _name ## (Frontend);\
+}
+
 FRONTEND_GET_PROPERTY(Target, PXENVBD_TARGET)
 FRONTEND_GET_PROPERTY(Ring, PXENVBD_RING)
 FRONTEND_GET_PROPERTY(Granter, PXENVBD_GRANTER)
@@ -138,74 +155,14 @@ FRONTEND_GET_PROPERTY(DeviceId, ULONG)
 FRONTEND_GET_PROPERTY(BackendDomain, ULONG)
 FRONTEND_GET_PROPERTY(BackendPath, PCHAR)
 FRONTEND_GET_PROPERTY(FrontendPath, PCHAR)
-//FRONTEND_GET_PROPERTY(Caps, PXENVBD_CAPS)
-PXENVBD_CAPS
-FrontendGetCaps(
-    IN  PXENVBD_FRONTEND    Frontend
-    )
-{
-    return &Frontend->Caps;
-}
-//FRONTEND_GET_PROPERTY(Features, PXENVBD_FEATURES)
-PXENVBD_FEATURES
-FrontendGetFeatures(
-    IN  PXENVBD_FRONTEND    Frontend
-    )
-{
-    return &Frontend->Features;
-}
-//FRONTEND_GET_PROPERTY(DiskInfo, PXENVBD_DISKINFO)
-PXENVBD_DISKINFO
-FrontendGetDiskInfo(
-    IN  PXENVBD_FRONTEND    Frontend
-    )
-{
-    return &Frontend->DiskInfo;
-}
-//FRONTEND_GET_PROPERTY(Connected, BOOLEAN)
-BOOLEAN
-FrontendGetConnected(
-    IN  PXENVBD_FRONTEND    Frontend
-    )
-{
-    return Frontend->Caps.Connected;
-}
-//FRONTEND_GET_PROPERTY(ReadOnly, BOOLEAN)
-BOOLEAN
-FrontendGetReadOnly(
-    IN  PXENVBD_FRONTEND    Frontend
-    )
-{
-    return !!(Frontend->DiskInfo.DiskInfo & VDISK_READONLY);
-}
-//FRONTEND_GET_PROPERTY(Discard, BOOLEAN)
-BOOLEAN
-FrontendGetDiscard(
-    IN  PXENVBD_FRONTEND    Frontend
-    )
-{
-    return Frontend->Features.Discard;
-}
-//FRONTEND_GET_PROPERTY(FlushCache, BOOLEAN)
-BOOLEAN
-FrontendGetFlushCache(
-    IN  PXENVBD_FRONTEND    Frontend
-    )
-{
-    return Frontend->Features.FlushCache;
-}
-//FRONTEND_GET_PROPERTY(Barrier, BOOLEAN)
-BOOLEAN
-FrontendGetBarrier(
-    IN  PXENVBD_FRONTEND    Frontend
-    )
-{
-    return Frontend->Features.Barrier;
-}
 FRONTEND_GET_PROPERTY(MaxQueues, ULONG)
 FRONTEND_GET_PROPERTY(NumQueues, ULONG)
+FRONTEND_GET_PROPERTY_PTR(Caps, PXENVBD_CAPS)
+FRONTEND_GET_PROPERTY_PTR(Features, PXENVBD_FEATURES)
+FRONTEND_GET_PROPERTY_PTR(DiskInfo, PXENVBD_DISKINFO)
 
 #undef FRONTEND_GET_PROPERTY
+#undef FRONTEND_GET_PROPERTY_PTR
 
 //=============================================================================
 #define FRONTEND_POOL_TAG            'tnFX'
diff --git a/src/xenvbd/frontend.h b/src/xenvbd/frontend.h
index 34f91b4..dc7b55f 100644
--- a/src/xenvbd/frontend.h
+++ b/src/xenvbd/frontend.h
@@ -159,16 +159,11 @@ FRONTEND_GET_PROPERTY(DeviceId, ULONG)
 FRONTEND_GET_PROPERTY(BackendDomain, ULONG)
 FRONTEND_GET_PROPERTY(BackendPath, PCHAR)
 FRONTEND_GET_PROPERTY(FrontendPath, PCHAR)
+FRONTEND_GET_PROPERTY(MaxQueues, ULONG)
+FRONTEND_GET_PROPERTY(NumQueues, ULONG)
 FRONTEND_GET_PROPERTY(Caps, PXENVBD_CAPS)
 FRONTEND_GET_PROPERTY(Features, PXENVBD_FEATURES)
 FRONTEND_GET_PROPERTY(DiskInfo, PXENVBD_DISKINFO)
-FRONTEND_GET_PROPERTY(Connected, BOOLEAN)
-FRONTEND_GET_PROPERTY(ReadOnly, BOOLEAN)
-FRONTEND_GET_PROPERTY(Discard, BOOLEAN)
-FRONTEND_GET_PROPERTY(FlushCache, BOOLEAN)
-FRONTEND_GET_PROPERTY(Barrier, BOOLEAN)
-FRONTEND_GET_PROPERTY(MaxQueues, ULONG)
-FRONTEND_GET_PROPERTY(NumQueues, ULONG)
 
 #undef FRONTEND_GET_PROPERTY
 
diff --git a/src/xenvbd/target.c b/src/xenvbd/target.c
index a07fc45..7dc18f3 100644
--- a/src/xenvbd/target.c
+++ b/src/xenvbd/target.c
@@ -223,11 +223,11 @@ TargetReadWrite(
     ULONG                   NumSectors;
 
     Srb->SrbStatus = SRB_STATUS_ERROR;
-    if (!FrontendGetConnected(Frontend))
+    if (!FrontendGetCaps(Frontend)->Connected)
         goto fail1;
 
     // disallow writes to read-only disks
-    if (FrontendGetReadOnly(Frontend) &&
+    if (FrontendGetDiskInfo(Frontend)->DiskInfo & VDISK_READONLY &&
         Cdb_OperationEx(Srb) == SCSIOP_WRITE)
         goto fail2;
 
@@ -266,15 +266,15 @@ TargetSyncCache(
     PXENVBD_RING            Ring = FrontendGetRing(Frontend);
 
     Srb->SrbStatus = SRB_STATUS_ERROR;
-    if (!FrontendGetConnected(Frontend))
+    if (!FrontendGetCaps(Frontend)->Connected)
         goto fail1;
 
-    if (FrontendGetReadOnly(Frontend))
+    if (FrontendGetDiskInfo(Frontend)->DiskInfo & VDISK_READONLY)
         goto fail2;
 
     // If neither FLUSH or BARRIER is supported, just succceed the SRB
-    if (!(FrontendGetFlushCache(Frontend) ||
-          FrontendGetBarrier(Frontend)))
+    if (!(FrontendGetFeatures(Frontend)->FlushCache ||
+          FrontendGetFeatures(Frontend)->Barrier))
         goto succeed;
 
     Srb->SrbStatus = SRB_STATUS_PENDING;
@@ -302,13 +302,13 @@ TargetUnmap(
     PXENVBD_RING            Ring = FrontendGetRing(Frontend);
 
     Srb->SrbStatus = SRB_STATUS_ERROR;
-    if (!FrontendGetConnected(Frontend))
+    if (!FrontendGetCaps(Frontend)->Connected)
         goto fail1;
 
-    if (FrontendGetReadOnly(Frontend))
+    if (FrontendGetDiskInfo(Frontend)->DiskInfo & VDISK_READONLY)
         goto fail2;
 
-    if (!FrontendGetDiscard(Frontend))
+    if (!FrontendGetFeatures(Frontend)->Discard)
         goto succeed;
 
     Srb->SrbStatus = SRB_STATUS_PENDING;
@@ -359,7 +359,7 @@ __TargetModeSense(
         // Fill in CachingParams
         Caching->PageCode           = MODE_PAGE_CACHING;
         Caching->PageLength         = sizeof(MODE_CACHING_PAGE);
-        Caching->WriteCacheEnable   = FrontendGetFlushCache(Target->Frontend) ? 1 : 0;
+        Caching->WriteCacheEnable   = FrontendGetFeatures(Target->Frontend)->FlushCache ? 1 : 0;
 
         *ModeDataLength += sizeof(MODE_CACHING_PAGE);
         *Size           += sizeof(MODE_CACHING_PAGE);
@@ -386,12 +386,15 @@ TargetModeSense(
     IN  PSCSI_REQUEST_BLOCK Srb
     )
 {
+    PXENVBD_FRONTEND        Frontend = Target->Frontend;
+    PXENVBD_DISKINFO        DiskInfo = FrontendGetDiskInfo(Frontend);
     PMODE_PARAMETER_HEADER  Data  = Srb->DataBuffer;
     ULONG                   Length = Srb->DataTransferLength;
     ULONG                   BlockDescrLength = 0;
     ULONG                   ModeDataLength = 0;
     ULONG                   Size;
 
+
     Srb->SrbStatus = SRB_STATUS_ERROR;
 
     if (Data == NULL)
@@ -403,7 +406,7 @@ TargetModeSense(
 
     // Header
     Data->MediumType                = 0;
-    Data->DeviceSpecificParameter   = FrontendGetReadOnly(Target->Frontend) ? 
+    Data->DeviceSpecificParameter   = (DiskInfo->DiskInfo & VDISK_READONLY) ?
                                                     MODE_DSP_WRITE_PROTECT : 0;
     Size = sizeof(MODE_PARAMETER_HEADER);
 
@@ -431,6 +434,8 @@ TargetModeSense10(
     IN  PSCSI_REQUEST_BLOCK     Srb
     )
 {
+    PXENVBD_FRONTEND            Frontend = Target->Frontend;
+    PXENVBD_DISKINFO            DiskInfo = FrontendGetDiskInfo(Frontend);
     PMODE_PARAMETER_HEADER10    Data  = Srb->DataBuffer;
     ULONG                       Length = Srb->DataTransferLength;
     ULONG                       BlockDescrLength = 0;
@@ -448,7 +453,7 @@ TargetModeSense10(
 
     // Header
     Data->MediumType                = 0;
-    Data->DeviceSpecificParameter   = FrontendGetReadOnly(Target->Frontend) ? 
+    Data->DeviceSpecificParameter   = (DiskInfo->DiskInfo & VDISK_READONLY) ?
                                                     MODE_DSP_WRITE_PROTECT : 0;
     Size = sizeof(MODE_PARAMETER_HEADER10);
 
-- 
2.51.2.windows.1



From win-pv-devel-bounces@lists.xenproject.org Tue Mar 03 09:36:41 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Tue, 03 Mar 2026 09:36:41 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1244584.1544016 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxMBE-0002Bk-Cl; Tue, 03 Mar 2026 09:36:40 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1244584.1544016; Tue, 03 Mar 2026 09:36:40 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxMBE-0002Bc-9O; Tue, 03 Mar 2026 09:36:40 +0000
Received: by outflank-mailman (input) for mailman id 1244584;
 Tue, 03 Mar 2026 09:36:38 +0000
Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254]
 helo=se1-gles-sth1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=jlLD=BD=citrix.com=owen.smith@srs-se1.protection.inumbo.net>)
 id 1vxMBC-0002BK-6y
 for win-pv-devel@lists.xenproject.org; Tue, 03 Mar 2026 09:36:38 +0000
Received: from na1pdmzitismtp01.tibco.com (na1pdmzitismtp01.tibco.com
 [160.101.131.8]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS
 id 76fc19da-16e4-11f1-b164-2bf370ae4941;
 Tue, 03 Mar 2026 10:36:35 +0100 (CET)
Received: from mewpvdipd2033.citrite.net (unknown [10.113.48.64])
 by na1pdmzitismtp01.tibco.com (Postfix) with ESMTP id 7E785417BB8D;
 Tue,  3 Mar 2026 04:36:10 -0500 (EST)
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: 76fc19da-16e4-11f1-b164-2bf370ae4941
From: Owen Smith <owen.smith@citrix.com>
To: win-pv-devel@lists.xenproject.org
Cc: Owen Smith <owen.smith@cloud.com>
Subject: [PATCH 2/4 v2] Refactor Features and DiskInfo
Date: Tue,  3 Mar 2026 09:36:26 +0000
Message-ID: <20260303093628.1743-2-owen.smith@citrix.com>
X-Mailer: git-send-email 2.51.2.windows.1
In-Reply-To: <20260303093628.1743-1-owen.smith@citrix.com>
References: <20260303093628.1743-1-owen.smith@citrix.com>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit

From: Owen Smith <owen.smith@cloud.com>

Make the XENVBD_FEATURES structure contain ring protocol related
feature flags and values, including which ring operations the backend
exposes to the frontend. The backend may fail any operation with
BLKIF_OP_ENOTSUPP, which instructs the frontend to stop issuing these
operations, and in response the frontend will disable the associated
feature flags.

Make the XENVBD_DISKINFO structure contain the backend storage
parameters, such as disk size, physical layout and disk specific flags.

Zeroing the XENVBD_FEATURES structure and re-reading it on connection
will allow feature flags to be modified when the backend changes.

Signed-off-by: Owen Smith <owen.smith@cloud.com>
---
 src/xenvbd/frontend.c | 203 ++++++++++++++++++------------------------
 src/xenvbd/frontend.h |  12 +--
 src/xenvbd/ring.c     |   2 +-
 src/xenvbd/target.c   |   8 +-
 4 files changed, 99 insertions(+), 126 deletions(-)

diff --git a/src/xenvbd/frontend.c b/src/xenvbd/frontend.c
index 9f157fe..912fc7e 100644
--- a/src/xenvbd/frontend.c
+++ b/src/xenvbd/frontend.c
@@ -184,7 +184,7 @@ FrontendGetDiscard(
     IN  PXENVBD_FRONTEND    Frontend
     )
 {
-    return Frontend->DiskInfo.Discard;
+    return Frontend->Features.Discard;
 }
 //FRONTEND_GET_PROPERTY(FlushCache, BOOLEAN)
 BOOLEAN
@@ -192,7 +192,7 @@ FrontendGetFlushCache(
     IN  PXENVBD_FRONTEND    Frontend
     )
 {
-    return Frontend->DiskInfo.FlushCache;
+    return Frontend->Features.FlushCache;
 }
 //FRONTEND_GET_PROPERTY(Barrier, BOOLEAN)
 BOOLEAN
@@ -200,7 +200,7 @@ FrontendGetBarrier(
     IN  PXENVBD_FRONTEND    Frontend
     )
 {
-    return Frontend->DiskInfo.Barrier;
+    return Frontend->Features.Barrier;
 }
 FRONTEND_GET_PROPERTY(MaxQueues, ULONG)
 FRONTEND_GET_PROPERTY(NumQueues, ULONG)
@@ -240,15 +240,15 @@ FrontendRemoveFeature(
     switch (BlkifOperation) {
     case BLKIF_OP_FLUSH_DISKCACHE:
         Verbose("FLUSH_DISKCACHE\n");
-        Frontend->DiskInfo.FlushCache = FALSE;
+        Frontend->Features.FlushCache = FALSE;
         break;
     case BLKIF_OP_WRITE_BARRIER:    
         Verbose("WRITE_BARRIER\n");
-        Frontend->DiskInfo.Barrier = FALSE;
+        Frontend->Features.Barrier = FALSE;
         break;
     case BLKIF_OP_DISCARD:
         Verbose("DISCARD\n");
-        Frontend->DiskInfo.Discard = FALSE;
+        Frontend->Features.Discard = FALSE;
         break;
     case BLKIF_OP_INDIRECT:
         Verbose("INDIRECT\n");
@@ -824,10 +824,78 @@ __Units(
     return "GB";
 }
 
-__drv_requiresIRQL(DISPATCH_LEVEL)
-static VOID
-__ReadDiskInfo(
-    __in  PXENVBD_FRONTEND  Frontend
+static FORCEINLINE VOID
+FrontendReadFeatures(
+    IN  PXENVBD_FRONTEND    Frontend
+    )
+{
+    BOOLEAN                 DiscardFeature = FALSE;
+    BOOLEAN                 DiscardEnable = TRUE;
+
+    FrontendReadFeature(Frontend,
+                        FeatureRemovable,
+                        &Frontend->Features.Removable);
+    FrontendReadValue32(Frontend,
+                        FeatureMaxIndirectSegments,
+                        TRUE,
+                        &Frontend->Features.Indirect);
+    FrontendReadFeature(Frontend,
+                        FeaturePersistent,
+                        &Frontend->Features.Persistent);
+    FrontendReadFeature(Frontend,
+                        FeatureBarrier,
+                        &Frontend->Features.Barrier);
+    FrontendReadFeature(Frontend,
+                        FeatureFlushCache,
+                        &Frontend->Features.FlushCache);
+
+    FrontendReadFeature(Frontend,
+                        FeatureDiscard,
+                        &DiscardFeature);
+    FrontendReadFeature(Frontend,
+                        FeatureDiscardEnable,
+                        &DiscardEnable);
+    Frontend->Features.Discard = DiscardFeature && DiscardEnable;
+
+    FrontendReadFeature(Frontend,
+                        FeatureDiscardSecure,
+                        &Frontend->Features.DiscardSecure);
+    FrontendReadValue32(Frontend,
+                        FeatureDiscardAlignment,
+                        TRUE,
+                        &Frontend->Features.DiscardAlignment);
+    FrontendReadValue32(Frontend,
+                        FeatureDiscardGranularity,
+                        TRUE,
+                        &Frontend->Features.DiscardGranularity);
+
+    Verbose("Target[%d] : Features: %s%s%s%s%s%s\n",
+            Frontend->TargetId,
+            Frontend->Features.Persistent ? "PERSISTENT " : "",
+            Frontend->Features.Indirect > 0 ? "INDIRECT " : "",
+            Frontend->Features.Removable ? "REMOVABLE " : "",
+            Frontend->Features.Barrier ? "BARRIER " : "",
+            Frontend->Features.FlushCache ? "FLUSH " : "",
+            Frontend->Features.Discard ? "DISCARD " : "");
+
+    if (Frontend->Features.Indirect) {
+        Verbose("Target[%d] : INDIRECT %x\n",
+                    Frontend->TargetId,
+                    Frontend->Features.Indirect);
+    }
+
+    if (Frontend->Features.Discard) {
+        Verbose("Target[%d] : DISCARD %s%x/%x\n",
+                    Frontend->TargetId,
+                    Frontend->Features.DiscardSecure ? "SECURE " : "",
+                    Frontend->Features.DiscardAlignment,
+                    Frontend->Features.DiscardGranularity);
+    }
+}
+
+static FORCEINLINE VOID
+FrontendReadDiskInfo(
+    IN  PXENVBD_FRONTEND    Frontend
     )
 {
     BOOLEAN                 Changed;
@@ -873,92 +941,6 @@ __ReadDiskInfo(
           Frontend->DiskInfo.DiskInfo);
 }
 
-static FORCEINLINE VOID
-FrontendReadFeatures(
-    IN  PXENVBD_FRONTEND    Frontend
-    )
-{
-    BOOLEAN                 Changed;
-
-    Changed = FrontendReadFeature(Frontend,
-                                  FeatureRemovable,
-                                  &Frontend->Features.Removable);
-    Changed |= FrontendReadValue32(Frontend,
-                                   FeatureMaxIndirectSegments,
-                                   TRUE,
-                                   &Frontend->Features.Indirect);
-    Changed |= FrontendReadFeature(Frontend,
-                                   FeaturePersistent,
-                                   &Frontend->Features.Persistent);
-
-    if (!Changed)
-        return;
-
-    Verbose("Target[%d] : Features: %s%s%s\n",
-            Frontend->TargetId,
-            Frontend->Features.Persistent ? "PERSISTENT " : "",
-            Frontend->Features.Indirect ? "INDIRECT " : "",
-            Frontend->Features.Removable ? "REMOVABLE" : "");
-
-    if (Frontend->Features.Indirect) {
-        Verbose("Target[%d] : INDIRECT %x\n",
-                    Frontend->TargetId,
-                    Frontend->Features.Indirect);
-    }
-}
-
-static FORCEINLINE VOID
-FrontendReadDiskInfo(
-    IN  PXENVBD_FRONTEND    Frontend
-    )
-{
-    BOOLEAN                 DiscardFeature = FALSE;
-    BOOLEAN                 DiscardEnable = TRUE;
-
-    FrontendReadFeature(Frontend,
-                        FeatureBarrier,
-                        &Frontend->DiskInfo.Barrier);
-    FrontendReadFeature(Frontend,
-                        FeatureFlushCache,
-                        &Frontend->DiskInfo.FlushCache);
-
-    // discard related
-    FrontendReadFeature(Frontend,
-                        FeatureDiscard,
-                        &DiscardFeature);
-    FrontendReadFeature(Frontend,
-                        FeatureDiscardEnable,
-                        &DiscardEnable);
-
-    Frontend->DiskInfo.Discard = DiscardFeature && DiscardEnable;
-
-    FrontendReadFeature(Frontend,
-                        FeatureDiscardSecure,
-                        &Frontend->DiskInfo.DiscardSecure);
-    FrontendReadValue32(Frontend,
-                        FeatureDiscardAlignment,
-                        TRUE,
-                        &Frontend->DiskInfo.DiscardAlignment);
-    FrontendReadValue32(Frontend,
-                        FeatureDiscardGranularity,
-                        TRUE,
-                        &Frontend->DiskInfo.DiscardGranularity);
-
-    Verbose("Target[%d] : Features: %s%s%s\n",
-                Frontend->TargetId,
-                Frontend->DiskInfo.Barrier ? "BARRIER " : "",
-                Frontend->DiskInfo.FlushCache ?  "FLUSH " : "",
-                Frontend->DiskInfo.Discard ? "DISCARD " : "");
-
-    if (Frontend->DiskInfo.Discard) {
-        Verbose("Target[%d] : DISCARD %s%x/%x\n",
-                    Frontend->TargetId,
-                    Frontend->DiskInfo.DiscardSecure ? "SECURE " : "",
-                    Frontend->DiskInfo.DiscardAlignment,
-                    Frontend->DiskInfo.DiscardGranularity);
-    }
-}
-
 static FORCEINLINE VOID
 FrontendReadInquiryOverrides(
     IN  PXENVBD_FRONTEND    Frontend
@@ -1142,8 +1124,6 @@ FrontendPrepare(
             Frontend->BackendDomain,
             Frontend->BackendPath);
 
-    FrontendReadFeatures(Frontend);
-    
     return STATUS_SUCCESS;
 
 fail7:
@@ -1314,7 +1294,6 @@ abort:
         goto fail6;
 
     // read disk info
-    __ReadDiskInfo(Frontend);
     FrontendReadDiskInfo(Frontend);
 
     // read inquiry data
@@ -1332,6 +1311,7 @@ abort:
 
 fail7:
     Error("Fail7\n");
+    RtlZeroMemory(&Frontend->Features, sizeof(XENVBD_FEATURES));
 fail6:
     Error("Fail6\n");
 fail5:
@@ -1370,14 +1350,7 @@ FrontendDisconnect(
     Frontend->Page83.Data = NULL;
     Frontend->Page83.Size = 0;
 
-    // clear some disk info values, so they can be re-read on connect
-    // allows migration to a backend with different supported features
-    Frontend->DiskInfo.Barrier = FALSE;
-    Frontend->DiskInfo.FlushCache = FALSE;
-    Frontend->DiskInfo.Discard = FALSE;
-    Frontend->DiskInfo.DiscardSecure = FALSE;
-    Frontend->DiskInfo.DiscardAlignment = 0;
-    Frontend->DiskInfo.DiscardGranularity = 0;
+    RtlZeroMemory(&Frontend->Features, sizeof(XENVBD_FEATURES));
 }
 __drv_requiresIRQL(DISPATCH_LEVEL)
 static FORCEINLINE VOID
@@ -1649,9 +1622,9 @@ FrontendDebugCallback(
                  Frontend->Features.Persistent ? "PERSISTENT " : "",
                  Frontend->Features.Indirect > 0 ? "INDIRECT " : "",
                  Frontend->Features.Removable ? "REMOVABLE " : "",
-                 Frontend->DiskInfo.Barrier ? "BARRIER " : "",
-                 Frontend->DiskInfo.FlushCache ? "FLUSH " : "",
-                 Frontend->DiskInfo.Discard ? "DISCARD " : "");
+                 Frontend->Features.Barrier ? "BARRIER " : "",
+                 Frontend->Features.FlushCache ? "FLUSH " : "",
+                 Frontend->Features.Discard ? "DISCARD " : "");
 
     if (Frontend->Features.Indirect > 0) {
         XENBUS_DEBUG(Printf,
@@ -1659,13 +1632,13 @@ FrontendDebugCallback(
                      "INDIRECT %x\n",
                      Frontend->Features.Indirect);
     }
-    if (Frontend->DiskInfo.Discard) {
+    if (Frontend->Features.Discard) {
         XENBUS_DEBUG(Printf,
                      &Frontend->DebugInterface,
                      "DISCARD %s%x/%x\n",
-                     Frontend->DiskInfo.DiscardSecure ? "SECURE " : "",
-                     Frontend->DiskInfo.DiscardAlignment,
-                     Frontend->DiskInfo.DiscardGranularity);
+                     Frontend->Features.DiscardSecure ? "SECURE " : "",
+                     Frontend->Features.DiscardAlignment,
+                     Frontend->Features.DiscardGranularity);
     }
 
     XENBUS_DEBUG(Printf,
@@ -1834,7 +1807,7 @@ FrontendBackend(
         KeAcquireSpinLock(&Frontend->StateLock, &Irql);
         // Only attempt this if Active, Active is set/cleared on D3->D0/D0->D3
         if (Frontend->Active) {
-            __ReadDiskInfo(Frontend);
+            FrontendReadDiskInfo(Frontend);
             __CheckBackendForEject(Frontend);
         }
         KeReleaseSpinLock(&Frontend->StateLock, Irql);
diff --git a/src/xenvbd/frontend.h b/src/xenvbd/frontend.h
index a83c1f0..34f91b4 100644
--- a/src/xenvbd/frontend.h
+++ b/src/xenvbd/frontend.h
@@ -56,6 +56,12 @@ typedef struct _XENVBD_FEATURES {
     ULONG                       Indirect;
     BOOLEAN                     Persistent;
     BOOLEAN                     Removable;
+    BOOLEAN                     Barrier;
+    BOOLEAN                     FlushCache;
+    BOOLEAN                     Discard;
+    BOOLEAN                     DiscardSecure;
+    ULONG                       DiscardAlignment;
+    ULONG                       DiscardGranularity;
 } XENVBD_FEATURES, *PXENVBD_FEATURES;
 
 typedef struct _XENVBD_DISKINFO {
@@ -63,12 +69,6 @@ typedef struct _XENVBD_DISKINFO {
     ULONG                       SectorSize;
     ULONG                       PhysSectorSize;
     ULONG                       DiskInfo;
-    BOOLEAN                     Barrier;
-    BOOLEAN                     FlushCache;
-    BOOLEAN                     Discard;
-    BOOLEAN                     DiscardSecure;
-    ULONG                       DiscardAlignment;
-    ULONG                       DiscardGranularity;
 } XENVBD_DISKINFO, *PXENVBD_DISKINFO;
 
 typedef struct _XENVBD_FRONTEND XENVBD_FRONTEND, *PXENVBD_FRONTEND;
diff --git a/src/xenvbd/ring.c b/src/xenvbd/ring.c
index 86a71ac..50f8d58 100644
--- a/src/xenvbd/ring.c
+++ b/src/xenvbd/ring.c
@@ -914,7 +914,7 @@ BlkifRingPrepareSyncCache(
     InitializeListHead(&List);
     Srb->SrbStatus = SRB_STATUS_PENDING;
 
-    if (FrontendGetDiskInfo(Frontend)->FlushCache)
+    if (FrontendGetFeatures(Frontend)->FlushCache)
         Operation = BLKIF_OP_FLUSH_DISKCACHE;
     else
         Operation = BLKIF_OP_WRITE_BARRIER;
diff --git a/src/xenvbd/target.c b/src/xenvbd/target.c
index f07ee8b..a07fc45 100644
--- a/src/xenvbd/target.c
+++ b/src/xenvbd/target.c
@@ -806,7 +806,7 @@ TargetInquiryB0(
     IN  PSCSI_REQUEST_BLOCK Srb
     )
 {
-    PXENVBD_DISKINFO        DiskInfo = FrontendGetDiskInfo(Target->Frontend);
+    PXENVBD_FEATURES        Features = FrontendGetFeatures(Target->Frontend);
     PVPD_BLOCK_LIMITS_PAGE  Data = Srb->DataBuffer;
     ULONG                   Length = Srb->DataTransferLength;
 
@@ -822,10 +822,10 @@ TargetInquiryB0(
     Data->PageCode = 0xB0;
     Data->PageLength[1] = 0x3C; // as per spec
 
-    *(PULONG)Data->OptimalUnmapGranularity = _byteswap_ulong(DiskInfo->DiscardGranularity);
-    *(PULONG)Data->UnmapGranularityAlignment = _byteswap_ulong(DiskInfo->DiscardAlignment);
+    *(PULONG)Data->OptimalUnmapGranularity = _byteswap_ulong(Features->DiscardGranularity);
+    *(PULONG)Data->UnmapGranularityAlignment = _byteswap_ulong(Features->DiscardAlignment);
     // alignment is only valid if a granularity has been set
-    Data->UGAValid = (DiskInfo->DiscardGranularity != 0) ? 1 : 0;
+    Data->UGAValid = (Features->DiscardGranularity != 0) ? 1 : 0;
 
     Srb->DataTransferLength = sizeof(VPD_BLOCK_LIMITS_PAGE);
     Srb->SrbStatus = SRB_STATUS_SUCCESS;
-- 
2.51.2.windows.1



From win-pv-devel-bounces@lists.xenproject.org Tue Mar 03 09:36:41 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Tue, 03 Mar 2026 09:36:41 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1244587.1544027 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxMBF-0002EZ-IJ; Tue, 03 Mar 2026 09:36:41 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1244587.1544027; Tue, 03 Mar 2026 09:36:41 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxMBF-0002EL-Ee; Tue, 03 Mar 2026 09:36:41 +0000
Received: by outflank-mailman (input) for mailman id 1244587;
 Tue, 03 Mar 2026 09:36:40 +0000
Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254]
 helo=se1-gles-sth1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=jlLD=BD=citrix.com=owen.smith@srs-se1.protection.inumbo.net>)
 id 1vxMBE-0002BK-SH
 for win-pv-devel@lists.xenproject.org; Tue, 03 Mar 2026 09:36:40 +0000
Received: from na1pdmzitismtp01.tibco.com (na1pdmzitismtp01.tibco.com
 [160.101.131.8]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS
 id 77a73e80-16e4-11f1-b164-2bf370ae4941;
 Tue, 03 Mar 2026 10:36:35 +0100 (CET)
Received: from mewpvdipd2033.citrite.net (unknown [10.113.48.64])
 by na1pdmzitismtp01.tibco.com (Postfix) with ESMTP id 9A682417BB8F;
 Tue,  3 Mar 2026 04:36:11 -0500 (EST)
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: 77a73e80-16e4-11f1-b164-2bf370ae4941
From: Owen Smith <owen.smith@citrix.com>
To: win-pv-devel@lists.xenproject.org
Cc: Owen Smith <owen.smith@citrix.com>
Subject: [PATCH 4/4 v2] Use NT Safe String printf in log.c
Date: Tue,  3 Mar 2026 09:36:28 +0000
Message-ID: <20260303093628.1743-4-owen.smith@citrix.com>
X-Mailer: git-send-email 2.51.2.windows.1
In-Reply-To: <20260303093628.1743-1-owen.smith@citrix.com>
References: <20260303093628.1743-1-owen.smith@citrix.com>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit

CodeQL generates a warning about using sprintf(). Switch to using
RtlStringCbPrintf() when formatting debug messages.
Avoid calling vDbgPrintExWithPrefix when RtlStringCbPrintf reports
an error.

Signed-off-by: Owen Smith <owen.smith@citrix.com>
---
 src/xencrsh/log.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/xencrsh/log.c b/src/xencrsh/log.c
index a1e8a5a..5d3fcc0 100644
--- a/src/xencrsh/log.c
+++ b/src/xencrsh/log.c
@@ -34,6 +34,7 @@
 #include "driver.h"
 #include "assert.h"
 #include <stdio.h>
+#include <ntstrsafe.h>
 
 static PVOID Port12 = ((PVOID)(ULONG_PTR)0x12);
 
@@ -252,10 +253,18 @@ LogVDebug(
     IN  va_list     Args
     )
 {
-    static CHAR Buffer[256];
+    static CHAR     Buffer[256];
+    NTSTATUS        status;
+
+    status = RtlStringCbPrintfA(Buffer,
+                                sizeof(Buffer),
+                                "%s|%s|%s:",
+                                Module,
+                                __Mode(),
+                                Function);
+    if (!NT_SUCCESS(status))
+        return; // Buffer is not safe to use
 
-#pragma warning(suppress : 28719) // SDV
-    sprintf(Buffer, "%s|%s|%s:", Module, __Mode(), Function);
     Buffer[255] = 0;
 
     vDbgPrintExWithPrefix(Buffer,
-- 
2.51.2.windows.1



From win-pv-devel-bounces@lists.xenproject.org Tue Mar 03 09:36:41 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Tue, 03 Mar 2026 09:36:41 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1244585.1544021 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxMBE-0002C3-Fy; Tue, 03 Mar 2026 09:36:40 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1244585.1544021; Tue, 03 Mar 2026 09:36:40 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxMBE-0002Bn-AZ; Tue, 03 Mar 2026 09:36:40 +0000
Received: by outflank-mailman (input) for mailman id 1244585;
 Tue, 03 Mar 2026 09:36:38 +0000
Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254]
 helo=se1-gles-sth1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=jlLD=BD=citrix.com=owen.smith@srs-se1.protection.inumbo.net>)
 id 1vxMBC-0002BK-Rg
 for win-pv-devel@lists.xenproject.org; Tue, 03 Mar 2026 09:36:38 +0000
Received: from na1pdmzitismtp01.tibco.com (na1pdmzitismtp01.tibco.com
 [160.101.131.8]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS
 id 76aafb4c-16e4-11f1-b164-2bf370ae4941;
 Tue, 03 Mar 2026 10:36:35 +0100 (CET)
Received: from mewpvdipd2033.citrite.net (unknown [10.113.48.64])
 by na1pdmzitismtp01.tibco.com (Postfix) with ESMTP id D44D5417BB8C;
 Tue,  3 Mar 2026 04:36:09 -0500 (EST)
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: 76aafb4c-16e4-11f1-b164-2bf370ae4941
From: Owen Smith <owen.smith@citrix.com>
To: win-pv-devel@lists.xenproject.org
Cc: Owen Smith <owen.smith@cloud.com>,
	Owen Smith <owen.smith@citrix.com>
Subject: [PATCH 1/4 v2] XenDisk: Report Discard support by issuing an Inquiry
Date: Tue,  3 Mar 2026 09:36:25 +0000
Message-ID: <20260303093628.1743-1-owen.smith@citrix.com>
X-Mailer: git-send-email 2.51.2.windows.1
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit

From: Owen Smith <owen.smith@cloud.com>

When XenDisk starts, issue an inquiry to determine the status of discard
support in the backend. If the backend exposes discard support, allow
XenDisk to respond to the appropriate property requests, and forward the
trim requests to XenVbd.

Signed-off-by: Owen Smith <owen.smith@citrix.com>
---
 src/xendisk/pdo.c | 88 ++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 84 insertions(+), 4 deletions(-)

diff --git a/src/xendisk/pdo.c b/src/xendisk/pdo.c
index f714efb..5d40a13 100644
--- a/src/xendisk/pdo.c
+++ b/src/xendisk/pdo.c
@@ -63,6 +63,7 @@ struct _XENDISK_PDO {
     PXENDISK_FDO                Fdo;
 
     BOOLEAN                     InterceptTrim;
+    BOOLEAN                     DiscardSupported;
     ULONG                       SectorSize;
     ULONG                       PhysSectorSize;
 };
@@ -519,6 +520,72 @@ fail1:
     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,
@@ -674,7 +741,7 @@ PdoQueryProperty(
 
     switch (Query->PropertyId) {
     case StorageDeviceTrimProperty:
-        if (!Pdo->InterceptTrim) {
+        if (!Pdo->InterceptTrim || !Pdo->DiscardSupported) {
             status = PdoForwardIrpAndForget(Pdo, Irp);
             break;
         }
@@ -753,7 +820,7 @@ PdoManageDataSetAttributes(
 
     switch (Attributes->Action) {
     case DeviceDsmAction_Trim:
-        if (!Pdo->InterceptTrim) {
+        if (!Pdo->InterceptTrim || !Pdo->DiscardSupported) {
             status = PdoForwardIrpAndForget(Pdo, Irp);
             break;
         }
@@ -830,6 +897,7 @@ PdoStartDevice(
     ULONG               PhysSectorSize;
     ULONG64             SectorCount;
     ULONG64             Size;
+    BOOLEAN             DiscardSupported;
     POWER_STATE         PowerState;
     NTSTATUS            status;
 
@@ -848,14 +916,22 @@ PdoStartDevice(
     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)\n",
-            __PdoGetName(Pdo), Size, SectorSize);
+    Verbose("%s: %luMB (%uB sectors)%s%s\n",
+            __PdoGetName(Pdo), Size, SectorSize,
+            Pdo->DiscardSupported ? " DISCARD" : "",
+            Pdo->InterceptTrim ? "" : " (VETOED)");
 
     __PdoSetSystemPowerState(Pdo, PowerSystemWorking);
     __PdoSetDevicePowerState(Pdo, PowerDeviceD0);
@@ -874,6 +950,9 @@ PdoStartDevice(
 
     return STATUS_SUCCESS;
 
+fail4:
+    Error("fail4\n");
+
 fail3:
     Error("fail3\n");
 
@@ -1904,6 +1983,7 @@ PdoDestroy(
     Dx->Pdo = NULL;
 
     Pdo->InterceptTrim = FALSE;
+    Pdo->DiscardSupported = FALSE;
 
     RtlZeroMemory(Pdo->Name, sizeof (Pdo->Name));
 
-- 
2.51.2.windows.1



From win-pv-devel-bounces@lists.xenproject.org Wed Mar 04 08:26:12 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Wed, 04 Mar 2026 08:26:12 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1245147.1544490 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxhYY-0006jP-JO; Wed, 04 Mar 2026 08:26:10 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1245147.1544490; Wed, 04 Mar 2026 08:26:10 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxhYY-0006jI-GV; Wed, 04 Mar 2026 08:26:10 +0000
Received: by outflank-mailman (input) for mailman id 1245147;
 Wed, 04 Mar 2026 08:26:09 +0000
Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50]
 helo=se1-gles-flk1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=Dykl=BE=citrix.com=owen.smith@srs-se1.protection.inumbo.net>)
 id 1vxhYX-0006jA-KU
 for win-pv-devel@lists.xenproject.org; Wed, 04 Mar 2026 08:26:09 +0000
Received: from BYAPR05CU005.outbound.protection.outlook.com
 (mail-westusazlp170100001.outbound.protection.outlook.com
 [2a01:111:f403:c000::1])
 by se1-gles-flk1.inumbo.com (Halon) with ESMTPS
 id c941c375-17a3-11f1-9ccf-f158ae23cfc8;
 Wed, 04 Mar 2026 09:26:06 +0100 (CET)
Received: from SA6PR03MB7760.namprd03.prod.outlook.com (2603:10b6:806:43c::5)
 by DS4PR03MB8471.namprd03.prod.outlook.com (2603:10b6:8:323::5) with
 Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9678.17; Wed, 4 Mar
 2026 08:26:00 +0000
Received: from SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38]) by SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38%7]) with mapi id 15.20.9654.022; Wed, 4 Mar 2026
 08:26:00 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: c941c375-17a3-11f1-9ccf-f158ae23cfc8
ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;
 b=jfRFFuTQzu1Eg2aFcN/i7iVuKApwqRyP8y8dQ2FNFwfMmIpEhzvbiZT3/dfaeZyF+SJzKKJ+uym0Yvt0YlunL8L4wV3QnIwoWFMk0HbesILZDBQbWKLjXjdy9fm3Uhqg2tBWgvEhRGi2V1Xz0hGEvz5YgkfAWV5LdU0d8dMGpx1x4FCpI0oHWPM4i2+ASFB9GjLDyHtQWBL29D3DuaVWUPUgBTDDNh7mEzzRVlttHfZnDxlU3NM8br6OmK33zTjJmbiBpMOxyn2uznFYApN9IGdNikvTkcFpuBjZeL2RH3ZWu3mOODSbQU4bKJ1Fp3ri3Xn5VgIuZVg2tMcjtTcsYA==
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=B+5FEqDe9kti/Ajh6Mc57l34i0yOu00poK63ENXWog4=;
 b=Kny7z/4hymmt1JjJK48Tw07RF6dzdTDtuO4mu4uRXr5n91Oy+SF4Ea9IWDGEwuas+9S/AVa0/omiwjk+TtNq6yK77BZsok6jiMR+IEcZf4jGWAFH/qPzPxlNtbGZk1o+oiCTfL3Cp9bF8twH+964oynuEjo/ZHbCzUXi7CIvE92sQZDnSS2L5KjmRsBfHbjZu3k+/rWxN7W3r43z9ARxf3ytdzQlYJevPhbKiVHvXoODAiIT9r9Y9v1QM5RwpiciwE/9in2hB4HK4FdNVpu85QRzEfwdFaEWqC/s+apOcu1BoVjrRgXwtSzNfgX4DgFs6SdNX9MmZQOsjHYlU3QEKg==
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
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com;
 s=selector1;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=B+5FEqDe9kti/Ajh6Mc57l34i0yOu00poK63ENXWog4=;
 b=u/4lWL0sMDE+4QVlkJI92IjXq9D7mZyGzLPmS+jRhVJAzNfdclQEQTGzelIVagUO5JxSWGS5VRlaocA38mIOiVUewJQqfwPuZbAEMI+HKbumYDMDRTBwF3Ydf+O7zSS2k09FMJK3UGef8aL5yiABejmPz44YEbObbS4MVbkqtNs=
From: Owen Smith <owen.smith@citrix.com>
To: Tu Dinh <ngoc-tu.dinh@vates.tech>, "win-pv-devel@lists.xenproject.org"
	<win-pv-devel@lists.xenproject.org>
Subject: Re: [RFC PATCH 1/6] Stop inlining the VPD page list in
 TargetInquiry00
Thread-Topic: [RFC PATCH 1/6] Stop inlining the VPD page list in
 TargetInquiry00
Thread-Index: AQHcpw8HSZq1FE4pf0SC1wouK0mVgbWeEt9x
Date: Wed, 4 Mar 2026 08:26:00 +0000
Message-ID:
 <SA6PR03MB776098CDE817F4F8EBEFCAE2FE7CA@SA6PR03MB7760.namprd03.prod.outlook.com>
References: <20260226105922.1916-1-ngoc-tu.dinh@vates.tech>
 <20260226105922.1916-2-ngoc-tu.dinh@vates.tech>
In-Reply-To: <20260226105922.1916-2-ngoc-tu.dinh@vates.tech>
Accept-Language: en-GB, en-US
Content-Language: en-GB
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
msip_labels:
authentication-results: dkim=none (message not signed)
 header.d=none;dmarc=none action=none header.from=citrix.com;
x-ms-publictraffictype: Email
x-ms-traffictypediagnostic: SA6PR03MB7760:EE_|DS4PR03MB8471:EE_
x-ms-office365-filtering-correlation-id: 3eb69e97-d630-4b31-f2b0-08de79c7aae6
x-ms-exchange-senderadcheck: 1
x-ms-exchange-antispam-relay: 0
x-microsoft-antispam:
 BCL:0;ARA:13230040|366016|376014|1800799024|3613699012|38070700021;
x-microsoft-antispam-message-info:
 OOeLFk+e5d3xnsFPbKeb1lcbDv48cUtnAXJF0pzmoinQHYgjD1fBysk11DeR5uyLmF8x2cnB/Rzwi4cFJLF/DVwVc90evaU73psB6Hx+1uDJzai1klf0iJ+1QS+B+tVS5akgdj1mPzpoUxrHhPdbxVwD36bNLrbAUng9IXSy2rIPkemgmkHUvgYKJcQ/HtHxYjE1+yS4yyGlGN2m0jO8PKYFzFVVj7KkQIW5+2Asr7UY7xaMD4VfU7HRiCmeUKI3JVm++rlUvaAKWqg6xKwH0Wc9nd+r3QfOkh5cDR/W/PZnYF53Fm32mAaJocfHjrtjbPIyUz4y3o/3stA7N+JiArpHaecYYdjikSUN0WxhW+7o78sCOQUMoQlhcvi6BnIxSLYogirBra807+Z0EFyLZX3ToJwYMgvKGUABiSUri7DjbgfpkTy3BBi7twFEvs8f+sTWFHwGKj/D1uFiUh3kUCQrk+xx8HXHjB0fTS9MyRxv0sd8PCPJTB9giVcyoJoawN0B9R5/7HNKsT7aYIF1lnnKXH6/UEWF6qrsqxvvAFggqek6Gr+zv6xxQy4UrG+pCd9nmIeHtN8XOxudijaMTiUeZKlOGU+Pu+iheyxpuuqsDfxEe34+RuKm7LZcPvS8yx1weseRSViOWt8ITdezkdDqAitetLmBjyy0c5Q5Tc+JtYlzoNd7xQAS+CC8DkzhtiIImBJlPG/bYnlW8dhxXM8N5Rz+r9ura9n50OAph2XSiYs4GKX/D+o8HaIOqeeOTt1DNaDg5Up8o+1s3ECRcQ==
x-forefront-antispam-report:
 CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SA6PR03MB7760.namprd03.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(366016)(376014)(1800799024)(3613699012)(38070700021);DIR:OUT;SFP:1101;
x-ms-exchange-antispam-messagedata-chunkcount: 1
x-ms-exchange-antispam-messagedata-0:
 =?us-ascii?Q?tthKr7UNUZVCAPvRLYExN/q3S48l/mTtvtGVWucbMyV8h2sSJIu3wX+vXvaZ?=
 =?us-ascii?Q?rJVQl8kNzi0gtYgexJVPkeF9F7XW+yIqvrrXoivZ8jkgVncqfRP2ZAlFGlpV?=
 =?us-ascii?Q?eBYzKJ9dClI5E0x/aT+B0WUpcM2E9bXGEiBC6lIN7V092DK87zQ+gHtxZWJJ?=
 =?us-ascii?Q?SuQekQBBvLTlv/myQYKFxpyBtcc5cAMkYQVtoAmYSjAPPPD96oEnY7FeF1My?=
 =?us-ascii?Q?4HLdCyFqsaFuiRxzHEqyvju3uHSPXcis71k/Cd37xvufk9wfyhlsctMBAKM3?=
 =?us-ascii?Q?8NZ13hYiiGCqqhszW7wRNgONC0xxPFKiWvn7aedRtE4q+UbnV9ooiQi8U66u?=
 =?us-ascii?Q?XFwbjqXueIlZUByvRzVervpyyKj/62aQ1bOUlZmDmhzG0qZ0KvgOZS65d8kr?=
 =?us-ascii?Q?7P+XcwQ7qWUBNT3O2PqpBYTWF/UeBBW7750xOz/wdNS+hz1oH//Z8Ikg1R8z?=
 =?us-ascii?Q?1Qr0m3UK1BxHQPdC/61alUxlSexZ4ham+WlrGpgGyVYY39/LlU5LAgCGUkZ7?=
 =?us-ascii?Q?Cd6FNoz+/1btqqaLBgOsl7aOQRSWFrqw9U2iFscgD5usQ3w6FcJ3xl5q0BPH?=
 =?us-ascii?Q?jujLg4oZUg6Xh5ZMHd7Z5aDpV5Kpzn2eDuRULmngTYBGCtC7qbK1ugT4pGgp?=
 =?us-ascii?Q?ba+Dmsl6J4SMXF/oJ4FpZ/cgPURQRt4hwSELzonUji9HbSAEfWOVhZNnnb/H?=
 =?us-ascii?Q?bgkm95f/bJhvsq+fOTHwSE+qeZyT6QffdYhvlJyQxM+PVLhlZv03nIppMNjt?=
 =?us-ascii?Q?Z3eGAfkZnDUU6PUnPS4Uv/auWFENYxvanQjdVwxJl4WcKku593RroEe72dWX?=
 =?us-ascii?Q?KUKl8bfZBQl4nXs62b6ymhpu9r1IMCLt38/GDiTYRQAr4hZ1U3DbuVDsYcZ0?=
 =?us-ascii?Q?JYijW74GdI0+vh1jaVmaC0yFJxpUE86beQ5iJlbM3Eiuu3bJqhYAY8mhMKU3?=
 =?us-ascii?Q?8DBDIk3yZhFCKZY7Ir2XdCmtPLINesYhZuklzxkBpW1QL9gUrPxK9EP0ObF9?=
 =?us-ascii?Q?iMS88ferq56N6ecBbmXQauvO2ltjOPNWjz3J4oIb5ixz1RzLphW4cB4IPdsR?=
 =?us-ascii?Q?z5gCgXt2qNHFM36VSUZE5vIHHOaFJxujxugKpn73HO2Oj+Sd+ETVFqawTN1M?=
 =?us-ascii?Q?qgFef16E8+GhLOT7hizD8/AzLeVHX15KFFLP4BWSrqRQYkRbQYin7Ykdyole?=
 =?us-ascii?Q?hYAS+T9Kp+vUtjTxBZzuJ2eqkvAdUNIitslAhkI8+YGuHKfgsbAETz7E0jej?=
 =?us-ascii?Q?5MecwfTDJEre38F23gKX0vWhjHOxoOxvzQcwPT6k/qPV9tDq+aG027Sf3r4x?=
 =?us-ascii?Q?xBtc1LsqQfXTkdlp7RDy9JqEB0Zf45reasR4yUaB7nfnu05RbnSJwsiab61c?=
 =?us-ascii?Q?0d9HvK24CWMy2Kkh/h19+mVyNJdq0PmuEzhooYwU3nCKyqne7Rw60lxk4gVR?=
 =?us-ascii?Q?ey6UfC7aNeH2YhrVqFLSj4fYi99D/y0+AGhkEEgrxnysfDWSM1DxvNbAsnc2?=
 =?us-ascii?Q?qRr5apDWfk86EuT0lP9G9ZJzD9GcObzLgUja+6Uaj7+pYnc3l5XBCTYD6ZFa?=
 =?us-ascii?Q?//CJOIh3QDHVQ7iLvc9o7oGPDtaxgQf9jXA1LWZWIldCWtJSpLDXiZpgvFAF?=
 =?us-ascii?Q?xGJrRcNHvzqRh9VNv3V3ihZx2YXAhcSWswdEAgI4SIv5J7xp2+MFUgXJY93O?=
 =?us-ascii?Q?+feev2FTkx7Y56TRqhcr29yBmgtCk1Dpms+2XunU9QFkFLhi?=
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
X-OriginatorOrg: citrix.com
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-AuthSource: SA6PR03MB7760.namprd03.prod.outlook.com
X-MS-Exchange-CrossTenant-Network-Message-Id: 3eb69e97-d630-4b31-f2b0-08de79c7aae6
X-MS-Exchange-CrossTenant-originalarrivaltime: 04 Mar 2026 08:26:00.5782
 (UTC)
X-MS-Exchange-CrossTenant-fromentityheader: Hosted
X-MS-Exchange-CrossTenant-id: 335836de-42ef-43a2-b145-348c2ee9ca5b
X-MS-Exchange-CrossTenant-mailboxtype: HOSTED
X-MS-Exchange-CrossTenant-userprincipalname: 3cEANv7DO6JhluK0xaMGZ61xX0BYDsRTb2pwbhlk0s0CzJV8OsZq4RTaJLbuvftxMWrxM/vxvO0+EZdJUk7sDw==
X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS4PR03MB8471

Reviewed-by: Owen Smith <owen.smith@citrix.com>

________________________________________
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
Sent: 26 February 2026 10:59 AM
To: win-pv-devel@lists.xenproject.org
Cc: Tu Dinh; Owen Smith
Subject: [RFC PATCH 1/6] Stop inlining the VPD page list in TargetInquiry00

Define a SupportedPages array containing all supported VPD pages so that
we could check its size later.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
---
 src/xenvbd/target.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/src/xenvbd/target.c b/src/xenvbd/target.c
index a07fc45..5a6c7be 100644
--- a/src/xenvbd/target.c
+++ b/src/xenvbd/target.c
@@ -674,6 +674,14 @@ TargetInquiryStd(
     Srb->SrbStatus =3D SRB_STATUS_SUCCESS;
 }

+static const UCHAR SupportedPages[] =3D {
+    VPD_SUPPORTED_PAGES,
+    VPD_SERIAL_NUMBER,
+    VPD_DEVICE_IDENTIFIERS,
+    VPD_BLOCK_LIMITS,
+    VPD_BLOCK_DEVICE_CHARACTERISTICS,
+};
+
 static FORCEINLINE VOID
 TargetInquiry00(
     IN  PXENVBD_TARGET          Target,
@@ -691,17 +699,16 @@ TargetInquiry00(
         return;
     RtlZeroMemory(Data, Length);

-    if (Length < 9)
+    if (Length < sizeof(VPD_SUPPORTED_PAGES_PAGE) + sizeof(SupportedPages)=
)
         return;

-    Data->PageLength =3D 5;
-    Data->SupportedPageList[0] =3D 0x00;
-    Data->SupportedPageList[1] =3D 0x80;
-    Data->SupportedPageList[2] =3D 0x83;
-    Data->SupportedPageList[3] =3D 0xB0;
-    Data->SupportedPageList[4] =3D 0xB1;
+    Data->PageLength =3D sizeof(SupportedPages);
+    RtlCopyMemory(Data->SupportedPageList,
+                  SupportedPages,
+                  sizeof(SupportedPages));

-    Srb->DataTransferLength =3D 9;
+    Srb->DataTransferLength =3D sizeof(VPD_SUPPORTED_PAGES_PAGE) +
+        Data->PageLength;
     Srb->SrbStatus =3D SRB_STATUS_SUCCESS;
 }

--
2.51.2.windows.1



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Wed Mar 04 08:26:19 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Wed, 04 Mar 2026 08:26:19 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1245148.1544494 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxhYh-0006lV-Kz; Wed, 04 Mar 2026 08:26:19 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1245148.1544494; Wed, 04 Mar 2026 08:26:19 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxhYh-0006lO-IL; Wed, 04 Mar 2026 08:26:19 +0000
Received: by outflank-mailman (input) for mailman id 1245148;
 Wed, 04 Mar 2026 08:26:18 +0000
Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50]
 helo=se1-gles-flk1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=Dykl=BE=citrix.com=owen.smith@srs-se1.protection.inumbo.net>)
 id 1vxhYg-0006jA-Is
 for win-pv-devel@lists.xenproject.org; Wed, 04 Mar 2026 08:26:18 +0000
Received: from SN4PR2101CU001.outbound.protection.outlook.com
 (mail-southcentralusazlp170120001.outbound.protection.outlook.com
 [2a01:111:f403:c10d::1])
 by se1-gles-flk1.inumbo.com (Halon) with ESMTPS
 id d046496e-17a3-11f1-9ccf-f158ae23cfc8;
 Wed, 04 Mar 2026 09:26:16 +0100 (CET)
Received: from SA6PR03MB7760.namprd03.prod.outlook.com (2603:10b6:806:43c::5)
 by DS4PR03MB8471.namprd03.prod.outlook.com (2603:10b6:8:323::5) with
 Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9678.17; Wed, 4 Mar
 2026 08:26:13 +0000
Received: from SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38]) by SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38%7]) with mapi id 15.20.9654.022; Wed, 4 Mar 2026
 08:26:13 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: d046496e-17a3-11f1-9ccf-f158ae23cfc8
ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;
 b=jWPkS0y7R36ud2FQqaFws4Ej174EwLsqldNhnVCZzyRje94fuAgoR/xpLLLvzSQjN82WgmmqAundoXD8uE6YuatxituvWYgQrXPEwnCCepjbMvqEwxDYXWH51ilZUjZLadxtWx1Fp1mDSkcIqVOCK/GNgGU9QJKcHQhciBJDL7BJl5xklgyJDbiDYiiHGXQLz7YrIEqvOTvo7plikcTwVQOtbHgT1DLD3olhcETk1hr9sgoawm1Ta1WVhbpLpVx+qO5Vqq2T3sVyBtKmusSVPnPIyUtF9NkZQL21rA59iKPevf7ShlNkX77+8I5/yJ9p5TaJZKSdqWj36y0QkPM8uw==
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=9fXUepzGl26k+T4KhtD3D404lSmilAUOnj6mbE9KLC4=;
 b=VsNEGvsqmiNcws1w83EpwrUmfDdGnRTbppsukDjZrYXGMXkOarwxQgbYHZCHVCtcMUT0LNKaa8OkIiXzQq+1jxd9K9idmSfuOvZYvm6ZesphvkMLzHQsWoJvQlUYtBN+hPnVuhLl4HAQw3wAT/I2Yu7CPAXw+MUCxD06aG9J6GHi1pUwt9OojLLi/IhWBYjAE+E2AsOOijj3LCdU/IiRCx5kr/8KuEeW0jjz5GcyJZAS600Hz4cv2wsrmEu/L63XfC/Ns+MI2xUCzjZJyYHlc9Vye7Fn5uI6tQvSt1cDv9I7WryQGe4mt9/HWSL6hfYKF9rzhgnFQKEoW6iU4BkHBg==
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
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com;
 s=selector1;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=9fXUepzGl26k+T4KhtD3D404lSmilAUOnj6mbE9KLC4=;
 b=h5YFj201Zh7m9cbzx04LH82l07nU8SZxFj61JgwzzPLg4LUqmJr3utaa8aD7eIrbnmhT6kbJeI6pK11USCTmc8traIuO+gcDQ6yye4muxCvRxh9geMjjwftzCKWd0obo9VF2B81IIL0Az/FRrYUwKwfiCKAuYJi5IJUyaLkPO3o=
From: Owen Smith <owen.smith@citrix.com>
To: Tu Dinh <ngoc-tu.dinh@vates.tech>, "win-pv-devel@lists.xenproject.org"
	<win-pv-devel@lists.xenproject.org>
Subject: Re: [RFC PATCH 2/6] Stop inlining VPD page codes
Thread-Topic: [RFC PATCH 2/6] Stop inlining VPD page codes
Thread-Index: AQHcpw8IwdrsMczlbU+gVlkTrzKi0LWeEv4w
Date: Wed, 4 Mar 2026 08:26:13 +0000
Message-ID:
 <SA6PR03MB7760F45A6B81340314E266BBFE7CA@SA6PR03MB7760.namprd03.prod.outlook.com>
References: <20260226105922.1916-1-ngoc-tu.dinh@vates.tech>
 <20260226105922.1916-3-ngoc-tu.dinh@vates.tech>
In-Reply-To: <20260226105922.1916-3-ngoc-tu.dinh@vates.tech>
Accept-Language: en-GB, en-US
Content-Language: en-GB
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
msip_labels:
authentication-results: dkim=none (message not signed)
 header.d=none;dmarc=none action=none header.from=citrix.com;
x-ms-publictraffictype: Email
x-ms-traffictypediagnostic: SA6PR03MB7760:EE_|DS4PR03MB8471:EE_
x-ms-office365-filtering-correlation-id: 3be91602-87e6-4656-85f8-08de79c7b2bb
x-ms-exchange-senderadcheck: 1
x-ms-exchange-antispam-relay: 0
x-microsoft-antispam: BCL:0;ARA:13230040|366016|376014|1800799024|38070700021;
x-microsoft-antispam-message-info:
 eUGsqhQOcmEwY4GQ6OdY2vBa1hdmv1CBBZ5tNMCxBb3ICbHfrklWT19CQEBiUxbI1Rbh6PTRhn41vtLdkneu+7AheWfxL5QkNLQ/o3M/Ee3FZXzf7TSZRQ7aF3HJZKW0I17ir2PS0HOLwYJtSJYwmyygtJ7Xyhus2VhiXglDPxj5bXEzxpdA7SKVhoAhzFamGFstBk5+7QZy8eqv5DUxm3glM67Y+6D0t3xL2HHhwOpStW/j1BFVwKGvCMmpTBPv/RWBiTzlix5R+py118BXYsm5vOFxy6Pdp3IMrtprJnrP9ejMNR7okCqwX4EyOYHRztwfA0sTVzVqyMfS4RkXYlV59XM0GiuF2PcLKg/fwhp5AiHQn1gSF9kaed5nJY4GgaxZj13GeJ3BJSdD5ropydEvhBfiBG2LgcWoA+/0TUSJ8JybDIsI5Hl/jnqU6fOpdQEbcehUyaSSQcEiYPse+p3TMXNU6dv3Wxrb/UvRSbYYf72LKPf6ZMueP69EfB2DlrHSL6uAw0NSeDEDCTswQh4RYLM2h6ZP4eMZ6wtipP/O2FPzRgh8j7cgMK3Ap7mjeMMRk1jDrR7YhR79KhAc54mCmWT8xDvyH+AQi+Qed9p1/oP7ygNRkywppO6HBHjF0Ybam5BxzbdlW+8FjD9ZFqBli6OUmgBaeLYGXTuPzvVJXpCLjEtSYLdgYzI14cqMvmoz4TeDa4ZJ687Ip/Qt1xfdElrk8rARi3LVhxosqqY=
x-forefront-antispam-report:
 CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SA6PR03MB7760.namprd03.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(366016)(376014)(1800799024)(38070700021);DIR:OUT;SFP:1101;
x-ms-exchange-antispam-messagedata-chunkcount: 1
x-ms-exchange-antispam-messagedata-0:
 =?us-ascii?Q?T9AJhB/0/lhClJXn+Fneut7dWCuAo7tnb8ETKYr/gXRj7IRFDqEPpNsOwYlH?=
 =?us-ascii?Q?FxRc9fO0ceNaJP1Qeu4o64LCs9tWgCeQQPTRtCnbdVQOP5XztPuNLgldwuVT?=
 =?us-ascii?Q?27DOYyDfk4Gn4LlvETsv4zzY/dGuLgmtKglFM+wK0a2VgAtY8GAOsT1hKKeC?=
 =?us-ascii?Q?2jcvSfITe5EXhvCzndn1/bG1wIFLsXjeAznAbGYjvyKt6klIHN8nM+u2NXPk?=
 =?us-ascii?Q?8iRrkOKogdstydcL7VcKntzGqylGvOnakUv9bfPWueuP2nJ48Bg51wp5rPdH?=
 =?us-ascii?Q?6zOZ83WMZltxMQcsmaTZLGDCwbzLRlZPJafCPxRXnsHpHkIEdeVZesY2pxf5?=
 =?us-ascii?Q?aZ59qmIB52NYDmuU44Kdr1tH+cTpis81QPAA2NAFDAB1JEJUQE3t5MXKH7DW?=
 =?us-ascii?Q?LMRpboCZiZ9ipug8VRRPTFMtvxSK5jhdJDQcuJkspVeOxoNEdl4gAxC1VcgY?=
 =?us-ascii?Q?RkLXyWlejB/Wgo3lorD3KXHK2r9jCXaWTlJdbD095976SD+Ttjo2RUV57L3k?=
 =?us-ascii?Q?hDmc1Ppb2Z5wNSh10WXrgT4cO/6Dnj/tgJLGCVSLIuuJhWHMoPbJhQqeZs2P?=
 =?us-ascii?Q?90URukfPABD3bEFOuqvWweLWxep4e8aEJ9FTWEuZ4fjWuWpEjnippVMhpnMj?=
 =?us-ascii?Q?j6OU4mrCTszIqDecpxCD/O/3yTMOug7R5o0wd+wmjvxYzkh6bH858LHItMuR?=
 =?us-ascii?Q?BthYfE2xfWunrG/8z+ZobMgfWSsQJ/Lc5HH9jVLAP2u3avz4mWRXDZ7fgCxM?=
 =?us-ascii?Q?5JkcPFWm9F1e5xCwsTxQHQtQnx9s/u9xzcZdql6djj85RluB8TqJnOsy8hhX?=
 =?us-ascii?Q?YK0T77OJGSCUp3JwRSpAty6X+/bQu26X6a5wSQuc9VRtkaUlsjDvic6KDctW?=
 =?us-ascii?Q?nSKcrywPa2d8z7iNsUKXlm2bMGfQiqpiqzrFJYb+fJ03ohOdD9Gt9mJF5nsY?=
 =?us-ascii?Q?qetCnc46OvvWDlrmrdcCvG5NZENihkQ3mrtZX7ditIXUYGaBzpoaRlBL9C/M?=
 =?us-ascii?Q?IDwkhX/YJsXZxyiTQanC8JzKham5z9paAHSiGP9OuX77z4sB8E/7umYPxXMU?=
 =?us-ascii?Q?VmBSsm2NtRoyZqxY4qbYTYpFSeUqmVL+Nxyqedo9vYwutUbDiAaQ5ZycWHVf?=
 =?us-ascii?Q?SKjkbWzT9geEyn5nsAQhRVhLC6Rsr2uCNocaezkzkvIaWvlYh6hA5nd9B3LC?=
 =?us-ascii?Q?qC2dbO1FndW5j79GwME1RwUEcAZKmptMLhx03tDqDgMvcfBK7MCV5wsxU5MX?=
 =?us-ascii?Q?tm7FFZfGJk/Zj8m82N8rUyVMVT8EE6i5C2R7/hHMYHWKrT2MlqvjVR3fK+B2?=
 =?us-ascii?Q?3W8/wIAB27c9f81hFmNo8e3t0gK8q7XFfdzUdB69H6vn4zeCW7Wxd+isWMyY?=
 =?us-ascii?Q?JMVEM7YKwXu7G0mXjMoxuntb/zX7nQSKAncTD9xsHwhYEeGw7JNoH+aGHpUq?=
 =?us-ascii?Q?1n7ebEWoPceboW+Zy6BWYFTjg1MKZzbO2Hyp2S6T00nCYIr73ihv35S7AMCg?=
 =?us-ascii?Q?dqDR3kNX7LllGn6IK2SOq2Loahz6lrSvvG5HzU/HXV8DAX+ZB/6ao8hMBip4?=
 =?us-ascii?Q?F9h7j32pgkwWjl51J7zTtAo5Fg1f+jnVLKYf1u3NkLDzzgqwNzVlrYx0ZvXU?=
 =?us-ascii?Q?HyOuFBA8THOEXTul8q5165umpWg4+FB687SNgkKeUW7AB9FgTqMZeT6a6Xz3?=
 =?us-ascii?Q?z/QyOlRdybs0qSMYa3WfbUazu681ImZvKlnl87/t2fzolbME?=
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
X-OriginatorOrg: citrix.com
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-AuthSource: SA6PR03MB7760.namprd03.prod.outlook.com
X-MS-Exchange-CrossTenant-Network-Message-Id: 3be91602-87e6-4656-85f8-08de79c7b2bb
X-MS-Exchange-CrossTenant-originalarrivaltime: 04 Mar 2026 08:26:13.7099
 (UTC)
X-MS-Exchange-CrossTenant-fromentityheader: Hosted
X-MS-Exchange-CrossTenant-id: 335836de-42ef-43a2-b145-348c2ee9ca5b
X-MS-Exchange-CrossTenant-mailboxtype: HOSTED
X-MS-Exchange-CrossTenant-userprincipalname: NyIbHcpHGSEsrm+/Az0I6Ie8wsqr9H1MDZzjGv9FeL1wFzrkiO02Bu/QPsY+aWrQmCVe3MxuMg6GIPU9Ged6LQ==
X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS4PR03MB8471


Reviewed-by: Owen Smith <owen.smith@citrix.com>

________________________________________
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
Sent: 26 February 2026 10:59 AM
To: win-pv-devel@lists.xenproject.org
Cc: Tu Dinh; Owen Smith
Subject: [RFC PATCH 2/6] Stop inlining VPD page codes

Use the constants from Storport.h instead.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
---
 src/xenvbd/target.c | 40 ++++++++++++++++++++++++++++------------
 1 file changed, 28 insertions(+), 12 deletions(-)

diff --git a/src/xenvbd/target.c b/src/xenvbd/target.c
index 5a6c7be..1c6944f 100644
--- a/src/xenvbd/target.c
+++ b/src/xenvbd/target.c
@@ -741,7 +741,7 @@ TargetInquiry80(
         if (Length < sizeof(VPD_SERIAL_NUMBER_PAGE) + 4)
             return;

-        Data->PageCode      =3D 0x80;
+        Data->PageCode      =3D VPD_SERIAL_NUMBER;
         Data->PageLength    =3D 4;
         (VOID) RtlStringCbPrintfA(Serial,
                                   sizeof(Serial),
@@ -787,7 +787,7 @@ TargetInquiry83(
                      sizeof(VPD_IDENTIFICATION_DESCRIPTOR) + 16)
             return;

-        Data->PageCode =3D 0x83;
+        Data->PageCode =3D VPD_DEVICE_IDENTIFIERS;
         Data->PageLength =3D sizeof(VPD_IDENTIFICATION_DESCRIPTOR) + 16;

         Id->CodeSet         =3D VpdCodeSetAscii;
@@ -826,7 +826,7 @@ TargetInquiryB0(
     if (Length < sizeof(VPD_BLOCK_LIMITS_PAGE))
         return;

-    Data->PageCode =3D 0xB0;
+    Data->PageCode =3D VPD_BLOCK_LIMITS;
     Data->PageLength[1] =3D 0x3C; // as per spec

     *(PULONG)Data->OptimalUnmapGranularity =3D _byteswap_ulong(Features->D=
iscardGranularity);
@@ -859,7 +859,7 @@ TargetInquiryB1(
     if (Length < sizeof(VPD_BLOCK_DEVICE_CHARACTERISTICS_PAGE))
         return;

-    Data->PageCode =3D 0xB1;
+    Data->PageCode =3D VPD_BLOCK_DEVICE_CHARACTERISTICS;
     Data->PageLength =3D 0x3C; // as per spec

     Data->MediumRotationRateMsb =3D 0;
@@ -877,17 +877,33 @@ TargetInquiry(
 {
     if (Cdb_EVPD(Srb)) {
         switch (Cdb_PageCode(Srb)) {
-        case 0x00:  TargetInquiry00(Target, Srb);       break;
-        case 0x80:  TargetInquiry80(Target, Srb);       break;
-        case 0x83:  TargetInquiry83(Target, Srb);       break;
-        case 0xB0:  TargetInquiryB0(Target, Srb);       break;
-        case 0xB1:  TargetInquiryB1(Target, Srb);       break;
-        default:    Srb->SrbStatus =3D SRB_STATUS_ERROR;  break;
+        case VPD_SUPPORTED_PAGES:
+            TargetInquiry00(Target, Srb);
+            break;
+        case VPD_SERIAL_NUMBER:
+            TargetInquiry80(Target, Srb);
+            break;
+        case VPD_DEVICE_IDENTIFIERS:
+            TargetInquiry83(Target, Srb);
+            break;
+        case VPD_BLOCK_LIMITS:
+            TargetInquiryB0(Target, Srb);
+            break;
+        case VPD_BLOCK_DEVICE_CHARACTERISTICS:
+            TargetInquiryB1(Target, Srb);
+            break;
+        default:
+            Srb->SrbStatus =3D SRB_STATUS_ERROR;
+            break;
         }
     } else {
         switch (Cdb_PageCode(Srb)) {
-        case 0x00:  TargetInquiryStd(Target, Srb);      break;
-        default:    Srb->SrbStatus =3D SRB_STATUS_ERROR;  break;
+        case VPD_SUPPORTED_PAGES:
+            TargetInquiryStd(Target, Srb);
+            break;
+        default:
+            Srb->SrbStatus =3D SRB_STATUS_ERROR;
+            break;
         }
     }
 }
--
2.51.2.windows.1



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Wed Mar 04 08:26:35 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Wed, 04 Mar 2026 08:26:35 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1245149.1544497 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxhYx-0006pR-Mq; Wed, 04 Mar 2026 08:26:35 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1245149.1544497; Wed, 04 Mar 2026 08:26:35 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxhYx-0006pK-KG; Wed, 04 Mar 2026 08:26:35 +0000
Received: by outflank-mailman (input) for mailman id 1245149;
 Wed, 04 Mar 2026 08:26:34 +0000
Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50]
 helo=se1-gles-flk1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=Dykl=BE=citrix.com=owen.smith@srs-se1.protection.inumbo.net>)
 id 1vxhYw-0006jA-UK
 for win-pv-devel@lists.xenproject.org; Wed, 04 Mar 2026 08:26:34 +0000
Received: from BYAPR05CU005.outbound.protection.outlook.com
 (mail-westusazlp170100001.outbound.protection.outlook.com
 [2a01:111:f403:c000::1])
 by se1-gles-flk1.inumbo.com (Halon) with ESMTPS
 id d97eeb00-17a3-11f1-9ccf-f158ae23cfc8;
 Wed, 04 Mar 2026 09:26:33 +0100 (CET)
Received: from SA6PR03MB7760.namprd03.prod.outlook.com (2603:10b6:806:43c::5)
 by DS4PR03MB8471.namprd03.prod.outlook.com (2603:10b6:8:323::5) with
 Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9678.17; Wed, 4 Mar
 2026 08:26:31 +0000
Received: from SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38]) by SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38%7]) with mapi id 15.20.9654.022; Wed, 4 Mar 2026
 08:26:31 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: d97eeb00-17a3-11f1-9ccf-f158ae23cfc8
ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;
 b=YVK/WoVkXs9FrMn3o6hMgV97lhlethRwblVguPmInFXsauol5CSEWiouL2DZs25Kols9Mjx0f75kD6Gpla0AtOoThCYQ/xNKDukq6dt950BEgKu5FlTLVr8gTwmRZVLsUCdrtRUMAs82Qcsx1xozDdCNsAvQ7JXLumLtuk0T2Fy+nl4XztnXcm6TYgtxgQc/EMWfgf9pNqw/zWPYPTHi5ShO64dMwU8TyqJpV5Sqzth7hX+pLbbHdMi/KQByuXu9DXHOpGTdkUvg96hcSeED2MBGyr01NsBC5KKnqqJUFiqhWoQeQkOldeT76E/CqW9mfgVS+LDRkn4T6rTPgyrbBg==
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=JO28SsyFstTIPoPYngvcvrcUQTJ34dvNC+2lmd5od6k=;
 b=QRgaAgKFpLzIaQCYqxN/sqoNyRDTTas0JwQmZMf9956uSOBNv7GWmPDMMBWeTFpIHKu0v9R7P0daaIlwbt5oQRsvBG3pWxqezTh/poU6rppQp0ZLAwARP9jXsmEvn2fIxtLfEyduugd/axctOH1sLfSAAb7YQtTfstw2dyk9FJQH7ONLQeqGeSofPZyJJ6lD3OTeg4TdjNescgFZHqyHCFXQXDMNXrJ6UrklaceVdCwo2wEFg1v7VwB0mjIJ2wZ+BHJnedrquPH9IBFJNj1YGrWcgCMSzjIaTCLZJ8m+tkie2c+Xzr2WXFqM4ufnxkTNp2OY2pIUGmm3DZA3scz/Qg==
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
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com;
 s=selector1;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=JO28SsyFstTIPoPYngvcvrcUQTJ34dvNC+2lmd5od6k=;
 b=y0XDrqbaMXNFdUJGNDgBY2dKVTw7g6Ug+AJ5NMReCQYYt2/gnGgyFGgDyklURRRozac9vf+HP4F9IHuk6RRBzAp5lPsyLJ8uWW4TLFjyyJsgoHA1gg/HkvrCdz/eCbpgqiZ7ieOqP5ynQwtTeitMktWrWgpPQe1F5tW8yeFGJus=
From: Owen Smith <owen.smith@citrix.com>
To: Tu Dinh <ngoc-tu.dinh@vates.tech>, "win-pv-devel@lists.xenproject.org"
	<win-pv-devel@lists.xenproject.org>
Subject: Re: [RFC PATCH 3/6] Report max unmap LBA and block descriptor counts
Thread-Topic: [RFC PATCH 3/6] Report max unmap LBA and block descriptor counts
Thread-Index: AQHcpw8JqAEFg/mTlEqTktOHqlr91bWeExJn
Date: Wed, 4 Mar 2026 08:26:31 +0000
Message-ID:
 <SA6PR03MB776011D6C4C10B0C83FF253AFE7CA@SA6PR03MB7760.namprd03.prod.outlook.com>
References: <20260226105922.1916-1-ngoc-tu.dinh@vates.tech>
 <20260226105922.1916-4-ngoc-tu.dinh@vates.tech>
In-Reply-To: <20260226105922.1916-4-ngoc-tu.dinh@vates.tech>
Accept-Language: en-GB, en-US
Content-Language: en-GB
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
msip_labels:
authentication-results: dkim=none (message not signed)
 header.d=none;dmarc=none action=none header.from=citrix.com;
x-ms-publictraffictype: Email
x-ms-traffictypediagnostic: SA6PR03MB7760:EE_|DS4PR03MB8471:EE_
x-ms-office365-filtering-correlation-id: ed06adcc-d9c7-4343-c15e-08de79c7bd12
x-ms-exchange-senderadcheck: 1
x-ms-exchange-antispam-relay: 0
x-microsoft-antispam: BCL:0;ARA:13230040|366016|376014|1800799024|38070700021;
x-microsoft-antispam-message-info:
 g0+JCdBTWCn9lz8M+lSo02Pbk1Ss2+95sg/FVE64xuk7uUPaeDX2PGpfElNYsXhiQptsffqR49x2gWvkUcsCd4FmyAXapmvHE8esbO0yqGjMZxKnc8h/dCT32KutA97WnWDVzO+FdI94GAy4IEEaD1C4zg1BQ1zTi28pa28DE8mfaM1gAPkjRVzvOIlir5eLkTQMSVvvzSpkUYUzfX5CwjxgGH6wZDzabOYcnHga/7fCxicwPrY7S25QuFa3Up/VOPn+8FLcVwp5A2QYvM6XlphSBeGHgpaO+ckwWdVihyS6z8BjFpErKDVARWxwRusLmgyqTzpzGhkWDt44Lkb1KxJDCoIzrwMXsBGLi4TAmWn+crkdsEGzZagS7732gTd2yQI8NMJ4E87cUPWobUAMjSaJRY1KBjdkc7+TK5RsXSkfKVs26WLc9AeoZiGB4l1bUBwfiWxvrtsLSglmlr7sVyVueH6pZgAfoWOPr0EO0nLSfnjw6sa8vsPVrWpAF7M+qfEvMpQq3YQmR9alHmCkob3snsR1nf/03wcvhsi3N5LARNtzXbW4MEVucUx8n700wbJmILs270ahhd/kLQN+OWLu7PAiQkORtDyxCWn3+SiXJgRl2SLYxEDEHqnpxsDD3FMlO3f4qsZGqIxaLvZ/4yj0ggyxglYSp9ykS2AbuJCgqQdKhMJilnFfNno4PK7RyBUIFphV0M5/6strdOrfXpMhTnczrOx4RG5sx9EK3qs=
x-forefront-antispam-report:
 CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SA6PR03MB7760.namprd03.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(366016)(376014)(1800799024)(38070700021);DIR:OUT;SFP:1101;
x-ms-exchange-antispam-messagedata-chunkcount: 1
x-ms-exchange-antispam-messagedata-0:
 =?us-ascii?Q?yyoalPCEEUn0NSQmzmPjBmvQN/JHF3jbH+O6jSX73E3OOwuFCbGa/DHLVw09?=
 =?us-ascii?Q?YwmTqR1pQNr/FPydxaXz/0oVcewB2mO+TY1ljB580Wd21UsJs0pFf0Xp31GS?=
 =?us-ascii?Q?MKqICGQB/LQiLLcS+paguB5sFKzGOwoz8oRm6qhjKFVydCnvO81M9sM1wrLJ?=
 =?us-ascii?Q?m7xsHG1uQN5MumgupNJTilaskoK3bk9IwUt1AvcC9SBlWwW2ob2b0BPZRgip?=
 =?us-ascii?Q?SIMPjIO/f5JylKN+Il7zTBaOEawXAz9ilRYnGXHmwJQuWSTrURlz02ZguDYh?=
 =?us-ascii?Q?jY/p63zeX3AgwKpf9ZS8/+PO6doSPcFguEXyBzY1JTX8weASc0/XiULEQh6o?=
 =?us-ascii?Q?6kpMQg3mT0c4Ky9BFQPE4o8onuAloMCxHQjoWvnBQVFkyT3zbWQKswAuVNca?=
 =?us-ascii?Q?HkJGZ4svSDLDn8XtIuWDqBulyzncCkibLeuDBAkDqXpt9GfZ4RPoRBjUq7rl?=
 =?us-ascii?Q?z7topdns+ogh7hWzqsCMiiSdhbAePSzjq8i4GaxlSQwf5fNMd6kVdQ01b1Cb?=
 =?us-ascii?Q?sr8sk0VDJP0VrfmF6Ry9NCstNjvMZmHrnmBgqItYEtokn7lulHMi2CudglGL?=
 =?us-ascii?Q?nipxqO2FmPJ+mQ2IilQm5g+piAV3mxHMBj2JIjEhsby6yBA5Z+ejyvhvcMAC?=
 =?us-ascii?Q?lfqQX4rv0u0MBOedAkFupTjgqTfda+KDOGXOQQdUtgLayQkv3yX+Q1VJM2TT?=
 =?us-ascii?Q?T5n8vFMtOJEy84rVHtZwOR5sD8PBmDhhlkSJz+RBtBkHQRMKe1+IQHk6pvY3?=
 =?us-ascii?Q?IfWetAr7L/hPC6bUHrkDDyqCHVspCRbqI4Fl60xtx4yga8TAl7lEWHmngVhC?=
 =?us-ascii?Q?J7nsxVbHhXxra5R025SuPbclPJUPAZuO4zVD1A+yzVFTfUV8RJ2sfVE7AUHi?=
 =?us-ascii?Q?IwbrPUkQpl9Ix3DXxt0VKfOo2tJXdKSgWdSAkJA/6lT7EslO7LDDLAWJG774?=
 =?us-ascii?Q?Q4WKM74QDvgRqmpiBfKDgcHzI3M2csL4H4uocPVZAEiZCUqZ8Z5WZDRSk1sC?=
 =?us-ascii?Q?CB3I3jqATbhWkjwW387bJr5WaPgZFdrmc/B4D63Vfe8flB17y1YVUHCRi/R1?=
 =?us-ascii?Q?ZW4xcY2jBTd9eW1JE3KKrUdHW1UAHXK9bSAcOo1B5+BJoyDWgZu6L0Ilj/SL?=
 =?us-ascii?Q?tVdYxexiDF8G8wiSR0S2ncbvkfcgGXdo93DGGUOtHwZGqM+bkU3k4cf/zDGD?=
 =?us-ascii?Q?9O/ylU+X432eyd/6d+wfggLyFjMED5ZHzQYaAyvtSm8HVlGiq1zHzK/UQ8+G?=
 =?us-ascii?Q?XG20QVkh7am3aohFaYU9SN6b91HkcUNuwKk7Y6U9NhJKPHgsGTdD3j6EeJlO?=
 =?us-ascii?Q?Z6AoBQpIucU0dJe6eO7y92lxnbW4kBnJw2LZTNiyhB5OV+rWCiiZVgbSOzwc?=
 =?us-ascii?Q?Xbi+IlCUqalA8o49xtIUZvEJVATlYEU9mTUkTgg3hXokN/Yl/JZiInEo9PI0?=
 =?us-ascii?Q?J5VzkIEcakB/9PG9rqTHgyVjTdJoLhUVvFoXgmWvK0KqEzj+8SNWzoDZOwaR?=
 =?us-ascii?Q?TG1blZMQQojLC9iknhAJm6v/WuhpFA0ZjSs0hwq9b/gdpOzAERGwArPj7uuN?=
 =?us-ascii?Q?ni4Az94yVEms+7/XFDnYM470X6jcOmcsrwjPYT4K9biA8lFKYbiykcNayV/Y?=
 =?us-ascii?Q?yad7EkPkFlWmLimf+SvLsPqvLmrRgsk9jbtSb8NuuzPeoJRcTuyFZAE3jpKu?=
 =?us-ascii?Q?GUGEWIovk8dQM8a5Ma2xyslyrHRXP9heh5Iu7vzwu/Df15Wo?=
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
X-OriginatorOrg: citrix.com
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-AuthSource: SA6PR03MB7760.namprd03.prod.outlook.com
X-MS-Exchange-CrossTenant-Network-Message-Id: ed06adcc-d9c7-4343-c15e-08de79c7bd12
X-MS-Exchange-CrossTenant-originalarrivaltime: 04 Mar 2026 08:26:31.0653
 (UTC)
X-MS-Exchange-CrossTenant-fromentityheader: Hosted
X-MS-Exchange-CrossTenant-id: 335836de-42ef-43a2-b145-348c2ee9ca5b
X-MS-Exchange-CrossTenant-mailboxtype: HOSTED
X-MS-Exchange-CrossTenant-userprincipalname: LBxfl+Uk5Cbu2v/F/LrM6rR0d8FQX4Ze4BVSgklGhQZCBWdYmtH4KCdJYi82motJYw8xXvWfuo8fxHOBWJ2XHg==
X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS4PR03MB8471

Reviewed-by: Owen Smith <owen.smith@citrix.com>

________________________________________
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
Sent: 26 February 2026 10:59 AM
To: win-pv-devel@lists.xenproject.org
Cc: Tu Dinh; Owen Smith
Subject: [RFC PATCH 3/6] Report max unmap LBA and block descriptor counts

These values are needed in the Block Limits VPD page in order to show
that unmap is supported.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
---
 src/xenvbd/target.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/src/xenvbd/target.c b/src/xenvbd/target.c
index 1c6944f..5109281 100644
--- a/src/xenvbd/target.c
+++ b/src/xenvbd/target.c
@@ -829,6 +829,16 @@ TargetInquiryB0(
     Data->PageCode =3D VPD_BLOCK_LIMITS;
     Data->PageLength[1] =3D 0x3C; // as per spec

+    *(PULONG)Data->MaximumUnmapLBACount =3D _byteswap_ulong(ULONG_MAX);
+    /*
+     * Each discarded extent requires its own BLKIF_OP_DISCARD request. We=
 don't
+     * want to consume the entire ring at once, but the optimal value migh=
t not
+     * be 1 either.
+     * Since the ring can hold anywhere from 32 requests (with 1 ring page=
) to
+     * 512 requests (using XENVBD_MAX_RING_PAGE_ORDER), use 8 as a conserv=
ative
+     * default.
+     */
+    *(PULONG)Data->MaximumUnmapBlockDescriptorCount =3D _byteswap_ulong(8)=
;
     *(PULONG)Data->OptimalUnmapGranularity =3D _byteswap_ulong(Features->D=
iscardGranularity);
     *(PULONG)Data->UnmapGranularityAlignment =3D _byteswap_ulong(Features-=
>DiscardAlignment);
     // alignment is only valid if a granularity has been set
--
2.51.2.windows.1



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Wed Mar 04 08:27:11 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Wed, 04 Mar 2026 08:27:11 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1245150.1544502 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxhZX-0006uQ-QD; Wed, 04 Mar 2026 08:27:11 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1245150.1544502; Wed, 04 Mar 2026 08:27:11 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxhZX-0006uJ-NW; Wed, 04 Mar 2026 08:27:11 +0000
Received: by outflank-mailman (input) for mailman id 1245150;
 Wed, 04 Mar 2026 08:27:10 +0000
Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254]
 helo=se1-gles-sth1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=Dykl=BE=citrix.com=owen.smith@srs-se1.protection.inumbo.net>)
 id 1vxhZW-0006u9-SU
 for win-pv-devel@lists.xenproject.org; Wed, 04 Mar 2026 08:27:10 +0000
Received: from SJ2PR03CU001.outbound.protection.outlook.com
 (mail-westusazlp170120002.outbound.protection.outlook.com
 [2a01:111:f403:c001::2])
 by se1-gles-sth1.inumbo.com (Halon) with ESMTPS
 id eecdd5cc-17a3-11f1-b164-2bf370ae4941;
 Wed, 04 Mar 2026 09:27:09 +0100 (CET)
Received: from SA6PR03MB7760.namprd03.prod.outlook.com (2603:10b6:806:43c::5)
 by DS4PR03MB8471.namprd03.prod.outlook.com (2603:10b6:8:323::5) with
 Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9678.17; Wed, 4 Mar
 2026 08:27:05 +0000
Received: from SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38]) by SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38%7]) with mapi id 15.20.9654.022; Wed, 4 Mar 2026
 08:27:05 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: eecdd5cc-17a3-11f1-b164-2bf370ae4941
ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;
 b=QkFlHSsm6rL0ctYul3055hwJxhmi6aaLdLCsTIrsAPajeuMg9FvJ1g2QOM15uN0qS8IvujDv5hG+1V3Lb9ZKRyYNBNq3wo4XAn0edkDESVrV6MLX20uqiLnWuScsBptj9u9agbKPLY/3Ndd+66BbzvLTLtt4ZwKDTxX3lPmLJl2URhsa05f/ZaANefA48wuH5EzbSo3BS2EUuXVRGP7DRzwYUuBTvXmdMRmeLEenlnZ0E01WEDOGgSzLc7739EUIJ6c+6NoBq4WadhWsdjx4Sfli/DmaxXODRaybDvMQXLXbgKreImjZhsrZhVrzu9a35ld+5q4/QSR4iTyziEiqVw==
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=YjyNN3coXQFWp32Xlkw9kw1Yj9mB9oWnK7gIaf46/Og=;
 b=ye5F2Mq4L6htp8C85sfD2risPF81oL8y44bAL0eF6liJPUumyLNhZRMhL6W6NumfEDTIOOH/xY4MyamXtpoKvpijE7Koc/wnlRHakMoMC03Fesl49DKo8Fd93Vfc91LayplIkLoEZel3SXt8OhskZ8rhy7czyMHpRwYMaYnqXdhAd5vkI4ZGk2q3P8OHU9LWolY0yY3PHOVfmNrr6BIJgtvHZpGjYi2LlmZiELgp93nr2Njq/I/7AlkEwgqUtT2EjqI6Cue4JVl6KTJHbf5f37MWCZ/w5ksdqg9IZcUcgabotVoYtFctYFnMv6j5cK5ROOCTzi3gbanKuw9gu2mX1g==
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
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com;
 s=selector1;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=YjyNN3coXQFWp32Xlkw9kw1Yj9mB9oWnK7gIaf46/Og=;
 b=W9xPQNfcprAOVnHFda5uYjZugXkTnFzZZkJNNHK8KffNAZBp3QJqbqKqskqSpPXcJdfpP9NAjpcGNv86+Df0VjLUNPBDLzG+X0QfyVT5fZA4xbAUcmzL6Sj3ic0d0ewO96NEr8ZEOSBShkRUApPlgHiqdSpxac5RtvmVRsIbeZQ=
From: Owen Smith <owen.smith@citrix.com>
To: Tu Dinh <ngoc-tu.dinh@vates.tech>, "win-pv-devel@lists.xenproject.org"
	<win-pv-devel@lists.xenproject.org>
Subject: Re: [RFC PATCH 4/6] Report VPD 0xB2 Logical Block Provisioning
Thread-Topic: [RFC PATCH 4/6] Report VPD 0xB2 Logical Block Provisioning
Thread-Index: AQHcpw8IwcpJhHFteUOIIiZRVuMZ0LWeEzxu
Date: Wed, 4 Mar 2026 08:27:05 +0000
Message-ID:
 <SA6PR03MB776075280917A855C23717BAFE7CA@SA6PR03MB7760.namprd03.prod.outlook.com>
References: <20260226105922.1916-1-ngoc-tu.dinh@vates.tech>
 <20260226105922.1916-5-ngoc-tu.dinh@vates.tech>
In-Reply-To: <20260226105922.1916-5-ngoc-tu.dinh@vates.tech>
Accept-Language: en-GB, en-US
Content-Language: en-GB
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
msip_labels:
authentication-results: dkim=none (message not signed)
 header.d=none;dmarc=none action=none header.from=citrix.com;
x-ms-publictraffictype: Email
x-ms-traffictypediagnostic: SA6PR03MB7760:EE_|DS4PR03MB8471:EE_
x-ms-office365-filtering-correlation-id: 3d170837-cb66-4bbe-8729-08de79c7d16d
x-ms-exchange-senderadcheck: 1
x-ms-exchange-antispam-relay: 0
x-microsoft-antispam: BCL:0;ARA:13230040|366016|376014|1800799024|38070700021;
x-microsoft-antispam-message-info:
 sEVqOl2Gh/nusXa1M3nICQYDdiMtU2aRwqNvlejA1XXzim9TQ2Emqhq+0SA9zv85w0lSS7OiouSDURfO/G9VfeyUOKYHYmBsc3zb5QNFint8OMpQZYPKPWbM/jaN6bLXLh0pksb4jaY0yNRpbthzuRT8ZB9t2V6PUhm1V2hNhRQMpgK4UqV09Udiq46gOFC8ylc3d77bJvrK2cDy0DFdkJ6TKBNW5AFyemY503+rDfCP5Fz/JkFhHKkA/Xw1OtkvcKw8uhkcyrE2SqFF5DZf4QimEo75Yp1wV0u0LHT2CWwYQDSeF1Y/1GlfrcO+aceFF/H2sIk9Nbf1cWcbTg0jgmPdfEIaMd3USLbHYsarkh9GKgOUBPam0aX7eqlU9s30wcX7Xq7F/98EW00jg4ZwmF+hElvlW3FB/YXMD+WvOTUPj11pBEVBwu1nrDVKo/UNVGi2jiDN7+uGXn5YtXYongjsTeKLg4gspfTkZedW3pmM9NjNYF2tVEFigFmN8X5CKhAuCd8JLl2i6rFRoFfE6uqGoMqlulzFYq8O8d9GuLCZQ0C5k7aVQi+T1/2eiAcLXHmG2D1UtOSuu16JlfuBjLboXHqVuUYGka5MX9m4lijhX9rqAGfraEXkVx3/lMH06emJin1pSh2iG/km3hOmmg+rZXV0NqnLy2u9jjOtZvmusw5ISoT4+z4UsuI6McPsBRDyaS+Vo37I/xTP7wOoTShRlF+6CyxfktdrEe1nTs4=
x-forefront-antispam-report:
 CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SA6PR03MB7760.namprd03.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(366016)(376014)(1800799024)(38070700021);DIR:OUT;SFP:1101;
x-ms-exchange-antispam-messagedata-chunkcount: 1
x-ms-exchange-antispam-messagedata-0:
 =?us-ascii?Q?izFjmp7eQhgsqhmZeistPNyZ00WyjQjA4+3jSzIdu7sr/VozYmTS5NLK7kjN?=
 =?us-ascii?Q?vkJ+g6OgNhCzMAmEpzY+25oKqiQEIUxkvkbRFhCZWAVQ21twWVkyeA5pXa0X?=
 =?us-ascii?Q?5FsUv/aPmPfCHaGWgPlpXujLP4KzOLrI35yEY7E4eTFZ7E+WcpQIwfcHb2Af?=
 =?us-ascii?Q?LqHO8ykYeMwhOhFl1N28kVMBK6Kw/mXSTokb9mt6zK9DV7iVcMrr/+Y9DY/R?=
 =?us-ascii?Q?UDI/hIAZR5PE6j5OwQIQnAVN5rhHB/Qcn3GsN6A+XHoR/OwQHiyeU9FfXloA?=
 =?us-ascii?Q?BnVsW4OxlErT+ykjtmJ12iplwjjRD/8+T75tmBUsYnzNNqNkNBFHBlQnrjd/?=
 =?us-ascii?Q?/AiT6XTcAjkeQ14VLjnbYBia0L84Ci//jepSXmnbLxSjq2R1QXkQuTJ8iq1R?=
 =?us-ascii?Q?4xIsWB/AvaSdtHXcTqjWrCqFVAs8tvDQkLqrumgu7aGxFOLqBx6mn0B3AHiY?=
 =?us-ascii?Q?Mk6jNRQtdcD4EvNVF6NvLOhaoW5PUluirya/tSx3uqy3RDdPghPmyi4Fa1uX?=
 =?us-ascii?Q?3l6zrboxXZC6jBfx///Y+2zUIlO6JW6osTfGFtabCf3HzoE2rJS83hDau9WE?=
 =?us-ascii?Q?oHfifRrZ8ulQxAYepVDDptWe76OJX8VnwHBZwgzyggd/P+aJLGwK0fPan4E8?=
 =?us-ascii?Q?T9JfnFTgt6TAJzjnNDxHt5QaMi2PdmHUhCTr3UMYBoJVmUn38DT2E29EW8kW?=
 =?us-ascii?Q?cK18jLG4ec0q1RcXWNwWKSJsovJcjhwH2einhQ9rB9xbMJPmegBEyaFNIuvb?=
 =?us-ascii?Q?BV7mDS8tW6wzc8EV6YCvn66wg4Otfb3CVTZGlBlUCEGm9jXiM61OC+K3/4ty?=
 =?us-ascii?Q?rqkTMPPCtbQvVnDVhUYVeG9rJTD5zZ340nziSRXcTQmNMjwlk3cb/7BZv6rW?=
 =?us-ascii?Q?1b04NsLGMjPHJij/hD0tncxf3y+dXCglfYcqmHJoPJe1u7Mas1dEDYBiJOi1?=
 =?us-ascii?Q?YH/g9lnI+waK5thIuCC7W4XlTayGTt7zuMQF/bvnlAibiuQgLrwa5lHR+3Qv?=
 =?us-ascii?Q?Ad4pEuiH8Z79oMkasmDFlAkJ39DsIohR16OYYe/hT2WnynHCXvqc1bfaEGA0?=
 =?us-ascii?Q?XRka2B1Ngspj9gozOc5FLaHNVYH1IxY9drfZnyRkRswLMPQepLVJ8fl2no2w?=
 =?us-ascii?Q?vxkUExo/esbEUt8FoqigXvtWmHJNuLqEczW1giRE5f2vZY/3BULHO/6D4cqo?=
 =?us-ascii?Q?awBRoQIHOPEkHP1oc2Gb2sFO41pgsw7Rer0hmGmr4LDlbJED+IiVK0oIOebF?=
 =?us-ascii?Q?iHLXReOlMyADRG9rJV8AZE2mj/BhyjwnnWaAmpMbBnRmMqo23jONLzl0PnBH?=
 =?us-ascii?Q?Zrxl3HNclTSzgAkjLLL7WBwmgtWZKZNBuaM7ynSCscSoxhu3ZeEUGdpxceVQ?=
 =?us-ascii?Q?VpdwQEOZMwxEJanm7hGFxVQcW6zacFoHyJ+jUXwVCxTEsiHkgbtVHxhHW3Pq?=
 =?us-ascii?Q?dR4ykwO6tZ2CT7imftYwhqG9hK/R5G3F8EytS522hayo09rxWnuoY1QMDUHs?=
 =?us-ascii?Q?fpsRfJowt55TsZgDwNipEYRhyF5c3KnxY9T37wWay7VdMo99Ib8yYJFInXJ6?=
 =?us-ascii?Q?wSjNa5jNV0dgztJaZeCFXRp1M5QiL0B+Gy4u3tvC2r7YdJT8u1vCfyOOCiAd?=
 =?us-ascii?Q?URb8cT7cClQ01lJHU+5S1rYnRdTyxSyNB0AO97SUJq6xy6PQW1wz6T1v3Shw?=
 =?us-ascii?Q?gIyfX1lx/zBkM/nWCkXOzetqAIl8ggTwbhUbMwliBXPYOLLK?=
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
X-OriginatorOrg: citrix.com
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-AuthSource: SA6PR03MB7760.namprd03.prod.outlook.com
X-MS-Exchange-CrossTenant-Network-Message-Id: 3d170837-cb66-4bbe-8729-08de79c7d16d
X-MS-Exchange-CrossTenant-originalarrivaltime: 04 Mar 2026 08:27:05.2047
 (UTC)
X-MS-Exchange-CrossTenant-fromentityheader: Hosted
X-MS-Exchange-CrossTenant-id: 335836de-42ef-43a2-b145-348c2ee9ca5b
X-MS-Exchange-CrossTenant-mailboxtype: HOSTED
X-MS-Exchange-CrossTenant-userprincipalname: HhSft+Gk+Ds6Ow5KbwaTpSwm8v4ydaNLLjROa91pDoCASXWu5itzqvHcVqLKYgR9GsYSDmk5oYoPrIXGjI7VQg==
X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS4PR03MB8471

Reviewed-by: Owen Smith <owen.smith@citrix.com>

________________________________________
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
Sent: 26 February 2026 10:59 AM
To: win-pv-devel@lists.xenproject.org
Cc: Tu Dinh; Owen Smith
Subject: [RFC PATCH 4/6] Report VPD 0xB2 Logical Block Provisioning

This VPD page is required for the detection of discard features by
Classpnp.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
---
 src/xenvbd/target.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/src/xenvbd/target.c b/src/xenvbd/target.c
index 5109281..3d48ade 100644
--- a/src/xenvbd/target.c
+++ b/src/xenvbd/target.c
@@ -680,6 +680,7 @@ static const UCHAR SupportedPages[] =3D {
     VPD_DEVICE_IDENTIFIERS,
     VPD_BLOCK_LIMITS,
     VPD_BLOCK_DEVICE_CHARACTERISTICS,
+    VPD_LOGICAL_BLOCK_PROVISIONING,
 };

 static FORCEINLINE VOID
@@ -879,6 +880,39 @@ TargetInquiryB1(
     Srb->SrbStatus =3D SRB_STATUS_SUCCESS;
 }

+static VOID
+TargetInquiryB2(
+    IN  PXENVBD_TARGET                      Target,
+    IN  PSCSI_REQUEST_BLOCK                 Srb
+    )
+{
+    PVPD_LOGICAL_BLOCK_PROVISIONING_PAGE    Data =3D Srb->DataBuffer;
+    ULONG                                   Length =3D Srb->DataTransferLe=
ngth;
+
+    UNREFERENCED_PARAMETER(Target);
+
+    Srb->SrbStatus =3D SRB_STATUS_ERROR;
+
+    if (Data =3D=3D NULL)
+        return;
+
+    RtlZeroMemory(Data, Length);
+
+    if (Length < sizeof(VPD_LOGICAL_BLOCK_PROVISIONING_PAGE))
+        return;
+
+    Data->PageCode =3D VPD_LOGICAL_BLOCK_PROVISIONING;
+    Data->PageLength[1] =3D 4;
+
+    // Even if the current backend doesn't support discard, we might want =
to
+    // offer discard again when the backend changes. So we have to say tha=
t
+    // discard is unconditionally supported here.
+    Data->LBPU =3D 1;
+
+    Srb->DataTransferLength =3D sizeof(VPD_LOGICAL_BLOCK_PROVISIONING_PAGE=
);
+    Srb->SrbStatus =3D SRB_STATUS_SUCCESS;
+}
+
 static DECLSPEC_NOINLINE VOID
 TargetInquiry(
     IN  PXENVBD_TARGET      Target,
@@ -902,6 +936,9 @@ TargetInquiry(
         case VPD_BLOCK_DEVICE_CHARACTERISTICS:
             TargetInquiryB1(Target, Srb);
             break;
+        case VPD_LOGICAL_BLOCK_PROVISIONING:
+            TargetInquiryB2(Target, Srb);
+            break;
         default:
             Srb->SrbStatus =3D SRB_STATUS_ERROR;
             break;
--
2.51.2.windows.1



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Wed Mar 04 08:27:55 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Wed, 04 Mar 2026 08:27:55 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1245151.1544506 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxhaE-00070C-T4; Wed, 04 Mar 2026 08:27:54 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1245151.1544506; Wed, 04 Mar 2026 08:27:54 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxhaE-000705-QR; Wed, 04 Mar 2026 08:27:54 +0000
Received: by outflank-mailman (input) for mailman id 1245151;
 Wed, 04 Mar 2026 08:27:53 +0000
Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254]
 helo=se1-gles-sth1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=Dykl=BE=citrix.com=owen.smith@srs-se1.protection.inumbo.net>)
 id 1vxhaD-0006zv-GI
 for win-pv-devel@lists.xenproject.org; Wed, 04 Mar 2026 08:27:53 +0000
Received: from SJ2PR03CU001.outbound.protection.outlook.com
 (mail-westusazlp170120002.outbound.protection.outlook.com
 [2a01:111:f403:c001::2])
 by se1-gles-sth1.inumbo.com (Halon) with ESMTPS
 id 08ea90c1-17a4-11f1-b164-2bf370ae4941;
 Wed, 04 Mar 2026 09:27:52 +0100 (CET)
Received: from SA6PR03MB7760.namprd03.prod.outlook.com (2603:10b6:806:43c::5)
 by BY1PR03MB7970.namprd03.prod.outlook.com (2603:10b6:a03:5b5::21)
 with Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9654.22; Wed, 4 Mar
 2026 08:27:50 +0000
Received: from SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38]) by SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38%7]) with mapi id 15.20.9654.022; Wed, 4 Mar 2026
 08:27:50 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: 08ea90c1-17a4-11f1-b164-2bf370ae4941
ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;
 b=H6PHPARpkkVaTTRPDHlTikcGtOvaHPp8HvlIC3qfBvV9tBh9SNLZcYIqoqrMYxeAZYH2kB1L33H2OHbzCU6wpK+fejZ7XYebolmt11FC7Hn4oWeTpkVdINllhj90QFAFYzghTzC8qX1AaDLBMXgHIfeJ2JgZBWgtErX2Ve68AzcGtzmK5BBQ2FcQHPzEvsNTqZmm1AmTjnZTZXUr1j2AaZ6nV1694oevlQp6aPBoAgPt9rPc1fl01LcDonOHUDMed+iih20Vosnx/6wAtmqDqJuIz0eG4zHKPvjlMnAqH+pqNIk0d5RBXR1Ztk8VmVfo9g3rVIamHZSDG4AITPGqcg==
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=JomGpP21U2Qru1FDvOcnHy+Rw7SbA7Dz650T5JMQ7SU=;
 b=fGb3UAlmGsRuEBzVRgUga2iCkqZcUr+kG20V66RR5qD/N4o9U2WvlndM3hq2eeGCDSvNBtGCFNmkgBNagRxOP3ftndwBnfHN3Fr33WWg0ue3eEVNj4G8CtDKiOry4Wa1NOBNdN8lLLQVXGEDhVhWKl0rPY67VdywVylYk9wTt4k9FPplvXOOUtLvq76zyVqoTdtVmK3kw6By+U2sVDBTw4RkrjiWFfPCMVM85M6nnXOA1lSNSiDa9EFk2nTja2BszfLhSnZsO2hzq3lwoPdWHx9YvcdQ4ZzeuSS0YjhqGzcteZByo1mxQ/U7jWBHk+XX1MUUPzsbMR43BuLPAF4iTg==
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
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com;
 s=selector1;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=JomGpP21U2Qru1FDvOcnHy+Rw7SbA7Dz650T5JMQ7SU=;
 b=l096LZ2W0g8WJXVP8q9Vte2LoPRDFNwGGXisJ3K+bR8u/gthneEF4AxlRjFWbVzE0IChxJolxQGzbaXBXSA2te09nOGIIG32t/nDe3hqvtGF3Rl02WwBOX4B456fjHawZhLnLC3kv/je6vh7XgzbLIjn7FrSWKGkmwH6trjCxDk=
From: Owen Smith <owen.smith@citrix.com>
To: Tu Dinh <ngoc-tu.dinh@vates.tech>, "win-pv-devel@lists.xenproject.org"
	<win-pv-devel@lists.xenproject.org>
Subject: Re: [RFC PATCH 5/6] Check Service Action when handling Read Capacity
 16
Thread-Topic: [RFC PATCH 5/6] Check Service Action when handling Read Capacity
 16
Thread-Index: AQHcpw8HMGEo69R2lECJVGbqnNFVk7WeE3Ek
Date: Wed, 4 Mar 2026 08:27:50 +0000
Message-ID:
 <SA6PR03MB776057C1B0DB07B0D9A92D58FE7CA@SA6PR03MB7760.namprd03.prod.outlook.com>
References: <20260226105922.1916-1-ngoc-tu.dinh@vates.tech>
 <20260226105922.1916-6-ngoc-tu.dinh@vates.tech>
In-Reply-To: <20260226105922.1916-6-ngoc-tu.dinh@vates.tech>
Accept-Language: en-GB, en-US
Content-Language: en-GB
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
msip_labels:
authentication-results: dkim=none (message not signed)
 header.d=none;dmarc=none action=none header.from=citrix.com;
x-ms-publictraffictype: Email
x-ms-traffictypediagnostic: SA6PR03MB7760:EE_|BY1PR03MB7970:EE_
x-ms-office365-filtering-correlation-id: f65bd987-96f8-402f-712f-08de79c7ec43
x-ms-exchange-senderadcheck: 1
x-ms-exchange-antispam-relay: 0
x-microsoft-antispam: BCL:0;ARA:13230040|376014|1800799024|366016|38070700021;
x-microsoft-antispam-message-info:
 uc9F58Grt1iS/CXEzRC7gqnZ1Pl1NIn2j9/pe+oqMkmrMug7eP00d4hOfZP7ApGlrIkRgyAaYLq8t51fJdEDOjGc2ob2awDK3je6GU0xvap7pn7II3YWBSmjPqOA6cUYy3Zcls6IvwXe8/1UThZPDtxwXvueU0/y7/mSFn4V9MKtgise3CvOrYsrjqrYJu2BQavcvR7kD6mFue2T0hfY8e9CQwB6QI/MMdE0k1uuYPWFsiJeVLLWCoUPhv0QKTKlW1+Rv+xe3QDQqRJyvZqTMkC3Pwg2wewDux3uKw/r7YP5Fh/RKBLLlS417e8lC/lZh72EvCmJIPBA+mxbTzAtKSJJn53L+NZ8S8X9Q9QE+Ry2TeBCtZkb0HchHpsfgEvWraSbLB+xJfd12soWjxGfLs5wn5e+ycdL37DF7WVkM8kngMBH82ZIhKynzYaKu+iCefM/TwwqKVRmc++C0Nm4aYVwAh/jrd5s3DCv7X8+Jan2PafAV6IuwwsvhdCoBgjTxJ3EM+A5J3Yj6AxMvtlz74xjZzjijJ0oI0SHiWyMwgtAVUD0RkkS35rUCz96c+YcEZnnM8t4r4IHUmjWg8c+nsqk8qUCphvIWRPOVrZpGHJfMRWuQv5m25aLDYcMtRa7CPap0q1ZWWcyEv6z5xP1GndCbLnLFZMK47WnhQPhJfcTELyptPqPaqc6HjYcdoyN0uZfBp38ExO5qeWCSWfUJMlOGpD5lA9X+bS2YrBRfZM=
x-forefront-antispam-report:
 CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SA6PR03MB7760.namprd03.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(1800799024)(366016)(38070700021);DIR:OUT;SFP:1101;
x-ms-exchange-antispam-messagedata-chunkcount: 1
x-ms-exchange-antispam-messagedata-0:
 =?us-ascii?Q?IhFI58YHE3mEGB20EstyAw4GqslXu1PjJiSb9sxXMrTaCft9RWfNtgI5MiPq?=
 =?us-ascii?Q?lZ5P2PvO6PYAs1XDiB3fUQnI1yIDzcwzkC/eSLX6FU+BHOx6uixvWBIg/ono?=
 =?us-ascii?Q?DI4RsK7uWOrmtF5hH4XS1MT6NVOF84IkIBHaCx7U5E8YaqjaJg4Ew/IYxOp/?=
 =?us-ascii?Q?giFX2rI8uCqar5h9WC0XHbL1k0pYTFwLiklkqGVIUkkvpt3d5DyM6m/o0xBv?=
 =?us-ascii?Q?nVzgS0Er9ZzoteEuFk41i78MhZMlgwQ4W39nB8y4NOJW97ja8yRqaY80dYtG?=
 =?us-ascii?Q?TK5ZSQ8WF3mYaR6pdQvlqbUm68STFXb87Oax9oYaWmcQN48zo6SU1SXLGwt6?=
 =?us-ascii?Q?aH4f/47AkSRg43RLfdi3jUf+lIIO8RJMyZI8xQOfNrTkezNtZvyY5Z8+TCGV?=
 =?us-ascii?Q?tvs0c2wY5UGmfM3OrxSG6tolFpbWPmx7N9Gpz2CcOu23caEBsikZ4WvaolN7?=
 =?us-ascii?Q?RcOKDFfed5DF8aADpnwRLevWQVhxOuY6evRCDxLSgbvtQ0FqdeEgKFGHWNBr?=
 =?us-ascii?Q?TORMb973wbZ+EfmH1E5GM0G2d+pRPD2duOvxSE0oKmwgEv4PcF6OD47KtnGa?=
 =?us-ascii?Q?VjaihbcQbtQFge7Kgx7e8TYFXsNl6wxQCgFVJK7L2Cl0zaj7b0rDZE32onm4?=
 =?us-ascii?Q?M/SHnRjE9d4evJ8blSTjncMy5dVNIW99FO4IWmQCRABbJVXu8HEHdFNL1Tlu?=
 =?us-ascii?Q?lO3PbDyzZXHPKzpzr+nHd93hhROHpsObWsix4Vfi24660gOlHQFNanI3jiAd?=
 =?us-ascii?Q?U3m6eNBr/8SE3nb/2cVEFn8DoMgFgb2bxlI0Jyo3+82270gAD5ZdezHqybme?=
 =?us-ascii?Q?61qI9BRr6qTXiXJZsr//92z1l4Div42lR8VjVNV4IK8/N/kLwDWRXi6AnVCV?=
 =?us-ascii?Q?4n63Ji4dPT9XD1fjyu4Q0fxl4qiaCgPUv/bIte+GCItYTqJXYgoc2VG/d62s?=
 =?us-ascii?Q?oNEicW6FO8m1TZPYBF39rSyj/YwOZHAUijExTEkCF4LFoZEBsRR2CZCMouz+?=
 =?us-ascii?Q?Uno2AR+m2hQRlOJTple43OW1zsdM5N7o1d0Pg5qTbUxyhGHELFhCE2bmo8Hn?=
 =?us-ascii?Q?sSE9OecXw8blh3f7DsA0Fz8oszADLYVWSKj+RqV+oOlNz7ZzUfPkE01OLzKs?=
 =?us-ascii?Q?99xnXWLnDa1SkAZw9atqaB87DOdDy910qbiTvyS59/msddmAbpwUhk1P2Kmr?=
 =?us-ascii?Q?uIB0q5HLauZU2FuseHwNggozydegWswARVUp807s/QB9Fodj63cTC8KggcCH?=
 =?us-ascii?Q?JBjXU8ESSqHFfLthAboDWLXcSXSILTZvYKnzNZLHv4J3hdd8A6y57nluGKwp?=
 =?us-ascii?Q?h/F7x6lZkJY7amo2z+DwWX1+imwH/PsxA/0an/+Bvj/tAjGIZqskMGQQprw3?=
 =?us-ascii?Q?TuCXpvK1SJYSoESvTrr82jsLT7T24uou6PUKuWWbZIBVz/3XP46y/4V5xfAX?=
 =?us-ascii?Q?okd+x8YcQuOCEQFCdmBp8PvT4v4gARZFxamKc/pyzbIIO5D2QyemmmclBETA?=
 =?us-ascii?Q?ZHrXBHKfM8BHv6qx7I/iy49uU42ta6K+fBK+Tg5x4/va+pdt6Q4BYD2TCHVa?=
 =?us-ascii?Q?d5SniJ0TMns1SHbZqRpWdQGz3LHVa3HBUzz8vLztyq+v/+PngmABhYGlXEhs?=
 =?us-ascii?Q?XFBsYUBCAbnMTpDe4U7iaeVcI53LLLSsHOtfXzLzh3iZvJvmeL6rRNA7/KUo?=
 =?us-ascii?Q?KMVPCRAOZX5av0lfmzNMIcchChEJCRbkx/3Rj4S3NZ1MYdWe?=
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
X-OriginatorOrg: citrix.com
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-AuthSource: SA6PR03MB7760.namprd03.prod.outlook.com
X-MS-Exchange-CrossTenant-Network-Message-Id: f65bd987-96f8-402f-712f-08de79c7ec43
X-MS-Exchange-CrossTenant-originalarrivaltime: 04 Mar 2026 08:27:50.1891
 (UTC)
X-MS-Exchange-CrossTenant-fromentityheader: Hosted
X-MS-Exchange-CrossTenant-id: 335836de-42ef-43a2-b145-348c2ee9ca5b
X-MS-Exchange-CrossTenant-mailboxtype: HOSTED
X-MS-Exchange-CrossTenant-userprincipalname: cEuQSa3t50IH7fSQ4He3dIO9QY80Db83WJs8aFGuKOBvY9lD105pLxe5EA5mh94HgxfZwcQ9cBcH7RFEel7DbQ==
X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY1PR03MB7970

Reviewed-by: Owen Smith <owen.smith@citrix.com>

________________________________________
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
Sent: 26 February 2026 10:59 AM
To: win-pv-devel@lists.xenproject.org
Cc: Tu Dinh; Owen Smith
Subject: [RFC PATCH 5/6] Check Service Action when handling Read Capacity 1=
6

Read Capacity 16 shares the same opcode with other Service Action In 16
subcommands.

Add an explicit check for SERVICE_ACTION_READ_CAPACITY16.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
---
 include/xencdb.h    |  8 ++++++++
 src/xenvbd/target.c | 26 ++++++++++++++++++++++++--
 2 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/include/xencdb.h b/include/xencdb.h
index 492d50d..594e9fe 100644
--- a/include/xencdb.h
+++ b/include/xencdb.h
@@ -261,6 +261,14 @@ FORCEINLINE UCHAR Cdb_EVPD(const SCSI_REQUEST_BLOCK* c=
onst srb)
     return Cdb_EVPDRaw(srb->CdbLength, srb->Cdb);
 }

+FORCEINLINE UCHAR Cdb_ServiceAction(const SCSI_REQUEST_BLOCK* const srb)
+{
+    if (srb->CdbLength > 6)
+        return srb->Cdb[1] & 0x1F;
+    else
+        return 0;
+}
+
 FORCEINLINE const char* Cdb_OperationName(UCHAR op)
 {
 #define _SCSIOP_NAME(x) case x: return #x;
diff --git a/src/xenvbd/target.c b/src/xenvbd/target.c
index 3d48ade..2cae479 100644
--- a/src/xenvbd/target.c
+++ b/src/xenvbd/target.c
@@ -636,6 +636,28 @@ fail1:
     Error("fail1\n");
 }

+static DECLSPEC_NOINLINE VOID
+TargetServiceActionIn16(
+    IN  PXENVBD_TARGET      Target,
+    IN  PSCSI_REQUEST_BLOCK Srb
+    )
+{
+    UCHAR                   ServiceAction =3D Cdb_ServiceAction(Srb);
+
+    switch (ServiceAction){
+    case SERVICE_ACTION_READ_CAPACITY16:
+        TargetReadCapacity16(Target, Srb);
+        return;
+    default:
+        Trace("Target[%d] : Unsupported SCSIOP_SERVICE_ACTION_IN16 "
+              "service action (%02hhx)\n",
+              TargetGetTargetId(Target),
+              ServiceAction);
+        Srb->SrbStatus =3D SRB_STATUS_INVALID_REQUEST;
+        break;
+    }
+}
+
 static FORCEINLINE VOID
 TargetInquiryStd(
     IN  PXENVBD_TARGET      Target,
@@ -1063,8 +1085,8 @@ TargetStartIo(
         TargetReadCapacity(Target, Srb);
         break;

-    case SCSIOP_READ_CAPACITY16:
-        TargetReadCapacity16(Target, Srb);
+    case SCSIOP_SERVICE_ACTION_IN16:
+        TargetServiceActionIn16(Target, Srb);
         break;

     case SCSIOP_MEDIUM_REMOVAL:
--
2.51.2.windows.1



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Wed Mar 04 08:32:25 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Wed, 04 Mar 2026 08:32:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1245157.1544510 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxhea-0008EJ-9E; Wed, 04 Mar 2026 08:32:24 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1245157.1544510; Wed, 04 Mar 2026 08:32:24 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxhea-0008EC-5g; Wed, 04 Mar 2026 08:32:24 +0000
Received: by outflank-mailman (input) for mailman id 1245157;
 Wed, 04 Mar 2026 08:32:23 +0000
Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50]
 helo=se1-gles-flk1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=Dykl=BE=citrix.com=owen.smith@srs-se1.protection.inumbo.net>)
 id 1vxheY-0008E2-NU
 for win-pv-devel@lists.xenproject.org; Wed, 04 Mar 2026 08:32:23 +0000
Received: from BYAPR05CU005.outbound.protection.outlook.com
 (mail-westusazlp170100001.outbound.protection.outlook.com
 [2a01:111:f403:c000::1])
 by se1-gles-flk1.inumbo.com (Halon) with ESMTPS
 id a834dc12-17a4-11f1-9ccf-f158ae23cfc8;
 Wed, 04 Mar 2026 09:32:19 +0100 (CET)
Received: from SA6PR03MB7760.namprd03.prod.outlook.com (2603:10b6:806:43c::5)
 by BY1PR03MB7970.namprd03.prod.outlook.com (2603:10b6:a03:5b5::21)
 with Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9654.22; Wed, 4 Mar
 2026 08:32:14 +0000
Received: from SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38]) by SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38%7]) with mapi id 15.20.9654.022; Wed, 4 Mar 2026
 08:32:14 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: a834dc12-17a4-11f1-9ccf-f158ae23cfc8
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==
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-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
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com;
 s=selector1;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=iux+kzWjZspfpVyP5lYO8Spjq4LZOm+7qf22ONcLl/8=;
 b=yLSV1kDX/QII9eUepTjURFROdF+y1pQlIf2c2C+QvVNwBEpFOgoI3bPd7ESsMvblEF73E7wTZ/HJg79m1XiWFHuADZKtJNRBxqNd8p4do/Gp8f8SrrYIZsUXalhMJ0gBuhQF9xceax7Ay0gH/bh4ymfsG4y9oESIIUpPeegkuMg=
From: Owen Smith <owen.smith@citrix.com>
To: Tu Dinh <ngoc-tu.dinh@vates.tech>, "win-pv-devel@lists.xenproject.org"
	<win-pv-devel@lists.xenproject.org>
Subject: Re: [RFC PATCH 6/6] Remove XenDisk
Thread-Topic: [RFC PATCH 6/6] Remove XenDisk
Thread-Index: AQHcpw8J8/5r9gR8eEeS2Wh4JDfN6rWeE4JZ
Date: Wed, 4 Mar 2026 08:32:13 +0000
Message-ID:
 <SA6PR03MB7760D5FA973CC19465CCAE00FE7CA@SA6PR03MB7760.namprd03.prod.outlook.com>
References: <20260226105922.1916-1-ngoc-tu.dinh@vates.tech>
 <20260226105922.1916-7-ngoc-tu.dinh@vates.tech>
In-Reply-To: <20260226105922.1916-7-ngoc-tu.dinh@vates.tech>
Accept-Language: en-GB, en-US
Content-Language: en-GB
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
msip_labels:
authentication-results: dkim=none (message not signed)
 header.d=none;dmarc=none action=none header.from=citrix.com;
x-ms-publictraffictype: Email
x-ms-traffictypediagnostic: SA6PR03MB7760:EE_|BY1PR03MB7970:EE_
x-ms-office365-filtering-correlation-id: 33c4813b-9772-4092-a487-08de79c88972
x-ms-exchange-senderadcheck: 1
x-ms-exchange-antispam-relay: 0
x-microsoft-antispam:
 BCL:0;ARA:13230040|376014|1800799024|366016|38070700021|13003099007;
x-microsoft-antispam-message-info:
 0MN8upLcOrJNDhTWSOolrwyHiJp0mp1wuqYJZHElBMYjZ0xZ/c4IzxZGfHKaD4KL6mMLk0lIwWB2/IPDEACTKbP+3yM4ocXacSltK3Au8nXcgGdhx8UZEPfhrlzGiXF4ahYS4ne94g9j2/IfGRi8Js1OITgrLNin9JDEEIdmydrudzwxEmWh6hPUHVJratbx/qtPSJM0I89ddg+MhcDeHEfnIQuj9EuvAc2bCsoyDsq9cVTjDEPscdetlA360f59JnhNQRDQeFrqmWATFkbU6y71nsoi4si8galO8r33LmJZ1tsgyjjkZ894JRzhkfLcuQRT8weyHVEtrBasyR/vdYH6nupzd3eOAbFSmHE+hL13FuXGwDEJXWX2z8aRiLTYXzo/IkhgOfAM24D3r2CTjkJwVivl+pkO65WcCWQQRkchhxfWezV5f7VaxQ+DPq2ELxgE6b7edJl+yOg9dZ5E92lkgzHWA8eMvDxv48dhx4EpbAwT2w7E3Xz1Qdbf5a//RO8i4os3gqwmZvKXJPylyBvL9b8qrsCRMJXNoXUliCaLb7dZgYJXHdseQGdvBIljkDT6HCjbv3+3Le0rWHqyKuRrqFAzTKR8jP1Fpq2H7p9XnfAUS8NXqt8NLDaChZcM1rI5UBTEL9qcwmbLT4iPtBVHcmxNMayXUdiw4S3MELXqpXLLIR6BZ7TfdmAuMQLbGgnAkklf79C1Y33woZlmZAyzjHfggBskmDKnIoxli9A=
x-forefront-antispam-report:
 CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SA6PR03MB7760.namprd03.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(1800799024)(366016)(38070700021)(13003099007);DIR:OUT;SFP:1101;
x-ms-exchange-antispam-messagedata-chunkcount: 1
x-ms-exchange-antispam-messagedata-0:
 =?us-ascii?Q?FbubbDjSDcvpMwIA2eSFJRmX8zUb2emWBHJnXGuq68nSZU/1oql29fs9Vppg?=
 =?us-ascii?Q?TYbPowN/6hKIdx6RDE0xmQF7wO7+6azCgxfN2/j68ibltTSdGO28fOKZJyW0?=
 =?us-ascii?Q?wtDaG3Qug3GkucL0wTrYk5X22Wn/7dJxIdirDYbl90Bo5/3A+ZpGQkxruq2H?=
 =?us-ascii?Q?0pPos8TQO8byuNyOPAfeWRNqcOKc9Xc6YRm7kFpbBDU8ogCZ003N5NsirKdj?=
 =?us-ascii?Q?c27ukMFavFY9lG/sViPZI7T69oa2dH7VMulI6PIi6NhM7zM6Guvha62ltDqE?=
 =?us-ascii?Q?K0rUV4gejkssRjw1SeHxvZvFGYWy1VTyAwVB0nWbdWcMFxDYx2bVKCzlKoWS?=
 =?us-ascii?Q?y+BojmqhUIqDmUkOkUNGE7nV3d7X+47UtK6LQ4leyz0nuHBVR0oMvxTiHY3N?=
 =?us-ascii?Q?SjTMsvDQGbzcbMuh4T4e5f0CGJq4yEHgHsZ9wrUg39RUMIg8X5pN0Q/18gEO?=
 =?us-ascii?Q?bfTnaPrzNl4/9yT1pcdsv3I6AAAQehD27n1Of7uyENvMKOWUFyJA259MzlMy?=
 =?us-ascii?Q?tV54WBelhlgLfKsNgC8zpBrRUFFIzFsZBhdJCDEhph/Co1ymQVVz9bAYyBnH?=
 =?us-ascii?Q?Yvvnvun/Va5RMpDIQ0qDItM8iSQUbyPeXwpcgb9ZlQUOn9QqFKcdDcfTSBT2?=
 =?us-ascii?Q?xIEAf/6rgacuy/owwugaVgCDexStYOnk3/O26OZLGafL1nUYgL95SHU+Bsho?=
 =?us-ascii?Q?elal7lPKQFg4DysE+/f9L4Ib+4ZFT29G21XHTrkAjbeoXWXdYuO2vvvvoaJd?=
 =?us-ascii?Q?fYoFTo1qZmiPNiXIao1HEGp8GdGTbhNwYRzi0eREtVSv9wyaL2VQQjw+t2zi?=
 =?us-ascii?Q?gwzVeoUolKuYi4ptpMLisGLQ23S9U0g4rJQ7yx6JmYtAgdP1U/J8pXDfqh6U?=
 =?us-ascii?Q?uZoTh7VWvxAYBW5pPe1Uzb5Zfsl+VKEJbvrbXcqWF7S3cOge0bEgPwf2Sk9G?=
 =?us-ascii?Q?m8ptNxWQ/glnVe+AEiW/+MAJFDoZZoaL3OdpXWmyz0MyrGaAuMY/ZQ2AZ1RS?=
 =?us-ascii?Q?k3yyJ+tK5xdmGhi879wOZv3xlWz2aVtLvGgXVnvQYpMeQbVyVkWpLXiIcSoY?=
 =?us-ascii?Q?a2AyThJNFNZqp75T3IdEk171juWrYlyofhjdj6cNJ1h51BcDd9oS5pZRTQk+?=
 =?us-ascii?Q?UE8bsbDz9a+8I06Tqj6pYkGI83+ylaYrsar2D6MGmIU99Mlzda9co+74qt7a?=
 =?us-ascii?Q?Ei1DAvY6J14+K6k5BeMvkSZouikHwelg5zlU5p9pJuJGDqE8Dq/xbq9nFo3X?=
 =?us-ascii?Q?iBQPibBMe7KhuyCHct44Fpffs4NdvF0uQVDU+FLQwI5eoxI9X3TtgCnAQMe1?=
 =?us-ascii?Q?OHjGDMw2RGdR0piQTJ72OW64A+gxFuLQKA7mlmjEHNDboY+jNh/wZ8EZ1QBK?=
 =?us-ascii?Q?9kYpRXJHXx4k+Qs2KNxNDkNWArBGkcPDspV7cDILbUfVr+cnOdT7yekb+lr0?=
 =?us-ascii?Q?Ez0/gCroCKIEyN7kq8gNVRL/qjAi2s2Z4iJThtpCgizaey5F2RkSvwB2vsZT?=
 =?us-ascii?Q?269ItUOUiLti5K/nOGCJFUcpoydE+A/6mPRyM40dhISa8ubhDHJ4T9vrRiMr?=
 =?us-ascii?Q?snlvzTUqLKC6E9mjhKed3/0ajVnHVsjIrssoRSgIYDd6D7+a8ry6rglJpZYS?=
 =?us-ascii?Q?xglXrJk/gG1U+U8Sv8G9qx6U0XhFHlEMW7jcDxCtjBrYdxpBPP4Et0tZpvTD?=
 =?us-ascii?Q?HupFXQWxMbLTocuJT0+yH6kfgeLQBrLgbfjht3NqIYyzDIoE?=
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
X-OriginatorOrg: citrix.com
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-AuthSource: SA6PR03MB7760.namprd03.prod.outlook.com
X-MS-Exchange-CrossTenant-Network-Message-Id: 33c4813b-9772-4092-a487-08de79c88972
X-MS-Exchange-CrossTenant-originalarrivaltime: 04 Mar 2026 08:32:13.9107
 (UTC)
X-MS-Exchange-CrossTenant-fromentityheader: Hosted
X-MS-Exchange-CrossTenant-id: 335836de-42ef-43a2-b145-348c2ee9ca5b
X-MS-Exchange-CrossTenant-mailboxtype: HOSTED
X-MS-Exchange-CrossTenant-userprincipalname: SrPPehLTH36Otu6OLB8fqDdClvl+BDjcXSpsW35hZ4qc9aRdlnbr7kgaR/SVG1KWcQD4lHv5gH2E7jbu6TIphQ==
X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY1PR03MB7970


This patch was prepared on the v1 of my series, refactoring the features an=
d 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 DiskIn=
fo 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@vates.tech>
Sent: 26 February 2026 10:59 AM
To: win-pv-devel@lists.xenproject.org
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@vates.tech>
---
 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 =3D "xenvbd.sln"
 $ArchivePath =3D "xenvbd"
-$ProjectList =3D @( "xencrsh", "xendisk", "xenvbd" )
+$ProjectList =3D @( "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 =3D (_TEXT);                       \
-            const CHAR  *_File =3D __FILE__;                      \
-            ULONG       _Line =3D __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 =3D (_TEXT1);                     \
-            const CHAR  *_Text2 =3D (_TEXT2);                     \
-            const CHAR  *_File =3D __FILE__;                      \
-            ULONG       _Line =3D __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 =3D (ULONGLONG)(_X);    \
-            ULONGLONG   _Rval =3D (ULONGLONG)(_Y);    \
-            if (!(_Lval _OP _Rval)) {               \
-                Error("%s =3D %llu\n", #_X, _Lval);   \
-                Error("%s =3D %llu\n", #_Y, _Rval);   \
-                ASSERT(_X _OP _Y);                  \
-            }                                       \
-        } while (FALSE)
-
-#define ASSERT3S(_X, _OP, _Y)                       \
-        do {                                        \
-            LONGLONG    _Lval =3D (LONGLONG)(_X);     \
-            LONGLONG    _Rval =3D (LONGLONG)(_Y);     \
-            if (!(_Lval _OP _Rval)) {               \
-                Error("%s =3D %lld\n", #_X, _Lval);   \
-                Error("%s =3D %lld\n", #_Y, _Rval);   \
-                ASSERT(_X _OP _Y);                  \
-            }                                       \
-        } while (FALSE)
-
-#define ASSERT3P(_X, _OP, _Y)                       \
-        do {                                        \
-            PVOID   _Lval =3D (PVOID)(_X);            \
-            PVOID   _Rval =3D (PVOID)(_Y);            \
-            if (!(_Lval _OP _Rval)) {               \
-                Error("%s =3D %p\n", #_X, _Lval);     \
-                Error("%s =3D %p\n", #_Y, _Rval);     \
-                ASSERT(_X _OP _Y);                  \
-            }                                       \
-        } while (FALSE)
-
-#define ASSERTREFCOUNT(_X, _OP, _Y, _Z)             \
-        do {                                        \
-            LONG    _L =3D (LONG)(_X);                \
-            LONG    _R =3D (LONG)(_Y);                \
-            if (!(_L _OP _R)) {                     \
-                Error("%s:%s =3D %d\n", (_Z), #_X, _L); \
-                Error("%s:%s =3D %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 =3D 0;
-    while (Offset < Length) {
-        if (*((PUCHAR)Buffer + Offset) !=3D 0) {
-            Error("%s: non-zero byte in %s (0x%p+0x%x)\n", Caller, Name, B=
uffer, 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 =3D 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 =3D 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, =3D=3D, __DriverGetDriverObject());
-
-    Trace("=3D=3D=3D=3D>\n");
-
-    ParametersKey =3D __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("<=3D=3D=3D=3D\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, =3D=3D, __DriverGetDriverObject());
-
-    status =3D 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 =3D (PXENDISK_DX)DeviceObject->DeviceExtension;
-    ASSERT3P(Dx->DeviceObject, =3D=3D, DeviceObject);
-
-    if (Dx->DevicePnpState =3D=3D Deleted) {
-        PIO_STACK_LOCATION  StackLocation =3D IoGetCurrentIrpStackLocation=
(Irp);
-        UCHAR               MajorFunction =3D StackLocation->MajorFunction=
;
-        UCHAR               MinorFunction =3D StackLocation->MinorFunction=
;
-
-        status =3D STATUS_NO_SUCH_DEVICE;
-
-        if (MajorFunction =3D=3D IRP_MJ_PNP) {
-            /* FDO and PDO deletions can block after being marked deleted,=
 but before IoDeleteDevice */
-            if (MinorFunction =3D=3D IRP_MN_SURPRISE_REMOVAL || MinorFunct=
ion =3D=3D IRP_MN_REMOVE_DEVICE)
-                status =3D STATUS_SUCCESS;
-
-            ASSERT((MinorFunction !=3D IRP_MN_CANCEL_REMOVE_DEVICE) && (Mi=
norFunction !=3D IRP_MN_CANCEL_STOP_DEVICE));
-        }
-
-        Irp->IoStatus.Status =3D status;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
-        goto done;
-    }
-
-    status =3D STATUS_NOT_SUPPORTED;
-    switch (Dx->Type) {
-    case PHYSICAL_DEVICE_OBJECT: {
-        PXENDISK_PDO    Pdo =3D Dx->Pdo;
-
-        status =3D PdoDispatch(Pdo, Irp);
-        break;
-    }
-    case FUNCTION_DEVICE_OBJECT: {
-        PXENDISK_FDO    Fdo =3D Dx->Fdo;
-
-        status =3D 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(), =3D=3D, NULL);
-    UNREFERENCED_PARAMETER(RegistryPath);
-
-    ExInitializeDriverRuntime(DrvRtPoolNxOptIn);
-
-    Trace("=3D=3D=3D=3D>\n");
-
-    __DriverSetDriverObject(DriverObject);
-
-    DriverObject->DriverUnload =3D DriverUnload;
-
-    Verbose("XENDISK %d.%d.%d (%d) (%02d.%02d.%04d)\n",
-            MAJOR_VERSION,
-            MINOR_VERSION,
-            MICRO_VERSION,
-            BUILD_NUMBER,
-            DAY,
-            MONTH,
-            YEAR);
-
-    status =3D RegistryInitialize(DriverObject, RegistryPath);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status =3D RegistryOpenParametersKey(KEY_READ, &ParametersKey);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    __DriverSetParametersKey(ParametersKey);
-
-    DriverObject->DriverExtension->AddDevice =3D AddDevice;
-
-    for (Index =3D 0; Index <=3D IRP_MJ_MAXIMUM_FUNCTION; Index++) {
-#pragma prefast(suppress:28169) // No __drv_dispatchType annotation
-#pragma prefast(suppress:28168) // No matching __drv_dispatchType annotati=
on for IRP_MJ_CREATE
-        DriverObject->MajorFunction[Index] =3D Dispatch;
-    }
-
-    Trace("<=3D=3D=3D=3D\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 str=
uct/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 =3D Fdo->Dx;
-
-    // We can never transition out of the deleted state
-    ASSERT(Dx->DevicePnpState !=3D Deleted || State =3D=3D Deleted);
-
-    Dx->PreviousDevicePnpState =3D Dx->DevicePnpState;
-    Dx->DevicePnpState =3D State;
-}
-
-static FORCEINLINE VOID
-__FdoRestoreDevicePnpState(
-    IN  PXENDISK_FDO        Fdo,
-    IN  DEVICE_PNP_STATE    State
-    )
-{
-    PXENDISK_DX             Dx =3D Fdo->Dx;
-
-    if (Dx->DevicePnpState =3D=3D State)
-        Dx->DevicePnpState =3D Dx->PreviousDevicePnpState;
-}
-
-static FORCEINLINE DEVICE_PNP_STATE
-__FdoGetDevicePnpState(
-    IN  PXENDISK_FDO    Fdo
-    )
-{
-    PXENDISK_DX         Dx =3D Fdo->Dx;
-
-    return Dx->DevicePnpState;
-}
-
-static FORCEINLINE VOID
-__FdoSetDevicePowerState(
-    IN  PXENDISK_FDO        Fdo,
-    IN  DEVICE_POWER_STATE  State
-    )
-{
-    PXENDISK_DX             Dx =3D Fdo->Dx;
-
-    Dx->DevicePowerState =3D State;
-}
-
-static FORCEINLINE DEVICE_POWER_STATE
-__FdoGetDevicePowerState(
-    IN  PXENDISK_FDO    Fdo
-    )
-{
-    PXENDISK_DX         Dx =3D Fdo->Dx;
-
-    return Dx->DevicePowerState;
-}
-
-static FORCEINLINE VOID
-__FdoSetSystemPowerState(
-    IN  PXENDISK_FDO        Fdo,
-    IN  SYSTEM_POWER_STATE  State
-    )
-{
-    PXENDISK_DX              Dx =3D Fdo->Dx;
-
-    Dx->SystemPowerState =3D State;
-}
-
-static FORCEINLINE SYSTEM_POWER_STATE
-__FdoGetSystemPowerState(
-    IN  PXENDISK_FDO    Fdo
-    )
-{
-    PXENDISK_DX         Dx =3D 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 =3D (PXENDISK_DX)DeviceObject->DeviceExtension;
-    ASSERT3U(Dx->Type, =3D=3D, PHYSICAL_DEVICE_OBJECT);
-
-    InsertTailList(&Fdo->Dx->ListEntry, &Dx->ListEntry);
-    ASSERT3U(Fdo->References, !=3D, 0);
-    Fdo->References++;
-}
-
-VOID
-FdoRemovePhysicalDeviceObject(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PDEVICE_OBJECT  DeviceObject
-    )
-{
-    PXENDISK_DX         Dx;
-
-    Dx =3D (PXENDISK_DX)DeviceObject->DeviceExtension;
-    ASSERT3U(Dx->Type, =3D=3D, PHYSICAL_DEVICE_OBJECT);
-
-    RemoveEntryList(&Dx->ListEntry);
-    ASSERT3U(Fdo->References, !=3D, 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 =3D=3D 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 =3D 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(), =3D=3D, PASSIVE_LEVEL);
-
-    Irp =3D IoAllocateIrp(DeviceObject->StackSize, FALSE);
-
-    status =3D STATUS_INSUFFICIENT_RESOURCES;
-    if (Irp =3D=3D NULL)
-        goto fail1;
-
-    StackLocation =3D IoGetNextIrpStackLocation(Irp);
-
-    StackLocation->MajorFunction =3D IRP_MJ_PNP;
-    StackLocation->MinorFunction =3D IRP_MN_QUERY_ID;
-    StackLocation->Flags =3D 0;
-    StackLocation->Parameters.QueryId.IdType =3D Type;
-    StackLocation->DeviceObject =3D DeviceObject;
-    StackLocation->FileObject =3D NULL;
-
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
-    IoSetCompletionRoutine(Irp,
-                           FdoQueryIdCompletion,
-                           &Event,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    // Default completion status
-    Irp->IoStatus.Status =3D STATUS_NOT_SUPPORTED;
-
-    status =3D IoCallDriver(DeviceObject, Irp);
-    if (status =3D=3D STATUS_PENDING) {
-        (VOID) KeWaitForSingleObject(&Event,
-                                     Executive,
-                                     KernelMode,
-                                     FALSE,
-                                     NULL);
-        status =3D Irp->IoStatus.Status;
-    } else {
-        ASSERT3U(status, =3D=3D, Irp->IoStatus.Status);
-    }
-
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status =3D 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 =3D FdoQueryId(Fdo,
-                        PhysicalDeviceObject,
-                        BusQueryDeviceID,
-                        DeviceID);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status =3D FdoQueryId(Fdo,
-                        PhysicalDeviceObject,
-                        BusQueryInstanceID,
-                        InstanceID);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status =3D 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 =3D Relations->Count;
-    ASSERT(Count !=3D 0);
-
-    PhysicalDeviceObject =3D __FdoAllocate(sizeof (PDEVICE_OBJECT) * Count=
);
-
-    status =3D STATUS_NO_MEMORY;
-    if (PhysicalDeviceObject =3D=3D NULL)
-        goto fail1;
-
-    RtlCopyMemory(PhysicalDeviceObject,
-                  Relations->Objects,
-                  sizeof (PDEVICE_OBJECT) * Count);
-
-    // Remove any PDOs that do not appear in the device list
-    ListEntry =3D Fdo->Dx->ListEntry.Flink;
-    while (ListEntry !=3D &Fdo->Dx->ListEntry) {
-        PLIST_ENTRY     Next =3D ListEntry->Flink;
-        PXENDISK_DX     Dx =3D CONTAINING_RECORD(ListEntry, XENDISK_DX, Li=
stEntry);
-        PXENDISK_PDO    Pdo =3D Dx->Pdo;
-
-        for (Index =3D 0; Index < Count; Index++) {
-            if (PdoGetPhysicalDeviceObject(Pdo) =3D=3D PhysicalDeviceObjec=
t[Index]) {
-#pragma prefast(suppress:6387)  // PhysicalDeviceObject[Index] could be NU=
LL
-                PhysicalDeviceObject[Index] =3D NULL; // avoid duplication
-                break;
-            }
-        }
-
-        ListEntry =3D Next;
-    }
-
-    // Walk the list and create PDO filters for any new devices
-    for (Index =3D 0; Index < Count; Index++) {
-#pragma warning(suppress:6385)  // Reading invalid data from 'PhysicalDevi=
ceObject'
-        if (PhysicalDeviceObject[Index] !=3D 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 =3D 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(), =3D=3D, PASSIVE_LEVEL);
-
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoForwardIrpSynchronously,
-                           &Event,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-    if (status =3D=3D STATUS_PENDING) {
-        (VOID) KeWaitForSingleObject(&Event,
-                                     Executive,
-                                     KernelMode,
-                                     FALSE,
-                                     NULL);
-        status =3D Irp->IoStatus.Status;
-    } else {
-        ASSERT3U(status, =3D=3D, Irp->IoStatus.Status);
-    }
-
-    return status;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-FdoStartDevice(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    POWER_STATE         PowerState;
-    NTSTATUS            status;
-
-    status =3D IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status =3D FdoForwardIrpSynchronously(Fdo, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    __FdoSetSystemPowerState(Fdo, PowerSystemWorking);
-    __FdoSetDevicePowerState(Fdo, PowerDeviceD0);
-
-    PowerState.DeviceState =3D 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 =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    __FdoSetDevicePnpState(Fdo, StopPending);
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoQueryStopDevice,
-                           Fdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-
-    __FdoRestoreDevicePnpState(Fdo, StopPending);
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoCancelStopDevice,
-                           Fdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    if (__FdoGetDevicePowerState(Fdo) !=3D PowerDeviceD0)
-        goto done;
-
-    PowerState.DeviceState =3D PowerDeviceD3;
-    PoSetPowerState(Fdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
-
-    __FdoSetDevicePowerState(Fdo, PowerDeviceD3);
-    __FdoSetSystemPowerState(Fdo, PowerSystemShutdown);
-
-done:
-    __FdoSetDevicePnpState(Fdo, Stopped);
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoStopDevice,
-                           Fdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    __FdoSetDevicePnpState(Fdo, RemovePending);
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoQueryRemoveDevice,
-                           Fdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    __FdoRestoreDevicePnpState(Fdo, RemovePending);
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoCancelRemoveDevice,
-                           Fdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    __FdoSetDevicePnpState(Fdo, SurpriseRemovePending);
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoSurpriseRemoval,
-                           Fdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    if (__FdoGetDevicePowerState(Fdo) !=3D PowerDeviceD0)
-        goto done;
-
-    PowerState.DeviceState =3D PowerDeviceD3;
-    PoSetPowerState(Fdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
-
-    __FdoSetDevicePowerState(Fdo, PowerDeviceD3);
-    __FdoSetSystemPowerState(Fdo, PowerSystemShutdown);
-
-done:
-    __FdoSetDevicePnpState(Fdo, Deleted);
-
-    IoReleaseRemoveLockAndWait(&Fdo->Dx->RemoveLock, Irp);
-
-    status =3D FdoForwardIrpSynchronously(Fdo, Irp);
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    __FdoAcquireMutex(Fdo);
-    ASSERT3U(Fdo->References, !=3D, 0);
-    --Fdo->References;
-    __FdoReleaseMutex(Fdo);
-
-    if (Fdo->References =3D=3D 0)
-        FdoDestroy(Fdo);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D 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 =3D 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 =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-    if (status =3D=3D STATUS_PENDING) {
-        (VOID) KeWaitForSingleObject(&Event,
-                                     Executive,
-                                     KernelMode,
-                                     FALSE,
-                                     NULL);
-        status =3D Irp->IoStatus.Status;
-    } else {
-        ASSERT3U(status, =3D=3D, Irp->IoStatus.Status);
-    }
-
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    StackLocation =3D IoGetCurrentIrpStackLocation(Irp);
-    if (StackLocation->Parameters.QueryDeviceRelations.Type !=3D BusRelati=
ons)
-        goto done;
-
-    Relations =3D (PDEVICE_RELATIONS)Irp->IoStatus.Information;
-
-    __FdoAcquireMutex(Fdo);
-
-    if (Relations->Count !=3D 0)
-        __FdoEnumerate(Fdo, Relations);
-
-    for (ListEntry =3D Fdo->Dx->ListEntry.Flink;
-         ListEntry !=3D &Fdo->Dx->ListEntry;
-         ListEntry =3D ListEntry->Flink) {
-        PXENDISK_DX     Dx =3D CONTAINING_RECORD(ListEntry, XENDISK_DX, Li=
stEntry);
-        PXENDISK_PDO    Pdo =3D Dx->Pdo;
-
-        ASSERT3U(Dx->Type, =3D=3D, PHYSICAL_DEVICE_OBJECT);
-
-        if (PdoGetDevicePnpState(Pdo) =3D=3D Present)
-            PdoSetDevicePnpState(Pdo, Enumerated);
-    }
-
-    __FdoReleaseMutex(Fdo);
-
-    Trace("%d PDO(s)\n", Relations->Count);
-
-    status =3D STATUS_SUCCESS;
-
-done:
-    IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-
-    Irp->IoStatus.Status =3D status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-
-fail2:
-    IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-    MinorFunction =3D StackLocation->MinorFunction;
-
-    switch (StackLocation->MinorFunction) {
-    case IRP_MN_START_DEVICE:
-        status =3D FdoStartDevice(Fdo, Irp);
-        break;
-
-    case IRP_MN_QUERY_STOP_DEVICE:
-        status =3D FdoQueryStopDevice(Fdo, Irp);
-        break;
-
-    case IRP_MN_CANCEL_STOP_DEVICE:
-        status =3D FdoCancelStopDevice(Fdo, Irp);
-        break;
-
-    case IRP_MN_STOP_DEVICE:
-        status =3D FdoStopDevice(Fdo, Irp);
-        break;
-
-    case IRP_MN_QUERY_REMOVE_DEVICE:
-        status =3D FdoQueryRemoveDevice(Fdo, Irp);
-        break;
-
-    case IRP_MN_SURPRISE_REMOVAL:
-        status =3D FdoSurpriseRemoval(Fdo, Irp);
-        break;
-
-    case IRP_MN_REMOVE_DEVICE:
-        status =3D FdoRemoveDevice(Fdo, Irp);
-        break;
-
-    case IRP_MN_CANCEL_REMOVE_DEVICE:
-        status =3D FdoCancelRemoveDevice(Fdo, Irp);
-        break;
-
-    case IRP_MN_QUERY_DEVICE_RELATIONS:
-        status =3D FdoQueryDeviceRelations(Fdo, Irp);
-        break;
-
-    default:
-        status =3D IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-        if (!NT_SUCCESS(status))
-            goto fail1;
-
-        IoCopyCurrentIrpStackLocationToNext(Irp);
-        IoSetCompletionRoutine(Irp,
-                               __FdoDispatchPnp,
-                               Fdo,
-                               TRUE,
-                               TRUE,
-                               TRUE);
-
-        status =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-        break;
-    }
-
-    return status;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    Irp->IoStatus.Status =3D 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 =3D (PXENDISK_FDO) Context;
-    PIO_STACK_LOCATION  StackLocation;
-    POWER_STATE         PowerState;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    StackLocation =3D IoGetCurrentIrpStackLocation(Irp);
-    PowerState =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-    PowerState =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-    DeviceState =3D StackLocation->Parameters.Power.State.DeviceState;
-    PowerAction =3D StackLocation->Parameters.Power.ShutdownType;
-
-    Trace("=3D=3D=3D=3D> (%s:%s)\n",
-          PowerDeviceStateName(DeviceState),
-          PowerActionName(PowerAction));
-
-    if (DeviceState =3D=3D __FdoGetDevicePowerState(Fdo)) {
-        IoSkipCurrentIrpStackLocation(Irp);
-        status =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-        goto done;
-    }
-
-    status =3D (DeviceState < __FdoGetDevicePowerState(Fdo)) ?
-             __FdoSetDevicePowerUp(Fdo, Irp) :
-             __FdoSetDevicePowerDown(Fdo, Irp);
-
-done:
-    Trace("<=3D=3D=3D=3D (%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 =3D (PXENDISK_FDO) Context;
-    PIO_STACK_LOCATION  StackLocation;
-    SYSTEM_POWER_STATE  SystemState;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    StackLocation =3D IoGetCurrentIrpStackLocation(Irp);
-    SystemState =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-    SystemState =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-    SystemState =3D StackLocation->Parameters.Power.State.SystemState;
-    PowerAction =3D StackLocation->Parameters.Power.ShutdownType;
-
-    Trace("=3D=3D=3D=3D> (%s:%s)\n",
-          PowerSystemStateName(SystemState),
-          PowerActionName(PowerAction));
-
-    if (SystemState =3D=3D __FdoGetSystemPowerState(Fdo)) {
-        IoSkipCurrentIrpStackLocation(Irp);
-        status =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-        goto done;
-    }
-
-    status =3D (SystemState < __FdoGetSystemPowerState(Fdo)) ?
-             __FdoSetSystemPowerUp(Fdo, Irp) :
-             __FdoSetSystemPowerDown(Fdo, Irp);
-
-done:
-    Trace("<=3D=3D=3D=3D (%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 =3D IoGetCurrentIrpStackLocation(Irp);
-
-    switch (StackLocation->MinorFunction) {
-    case IRP_MN_SET_POWER:
-        status =3D __FdoSetDevicePower(Fdo, Irp);
-        break;
-
-    default:
-        IoSkipCurrentIrpStackLocation(Irp);
-        status =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-        break;
-    }
-
-    return status;
-}
-
-static NTSTATUS
-FdoSystemPower(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    NTSTATUS            status;
-
-    StackLocation =3D IoGetCurrentIrpStackLocation(Irp);
-
-    switch (StackLocation->MinorFunction) {
-    case IRP_MN_SET_POWER:
-        status =3D __FdoSetSystemPower(Fdo, Irp);
-        break;
-
-    default:
-        IoSkipCurrentIrpStackLocation(Irp);
-        status =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-    PowerType =3D StackLocation->Parameters.Power.Type;
-
-    switch (PowerType) {
-    case DevicePowerState:
-        status =3D FdoDevicePower(Fdo, Irp);
-        break;
-
-    case SystemPowerState:
-        status =3D FdoSystemPower(Fdo, Irp);
-        break;
-
-    default:
-        IoSkipCurrentIrpStackLocation(Irp);
-        status =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoDispatchDefault,
-                           Fdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    Irp->IoStatus.Status =3D status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-NTSTATUS
-FdoDispatch(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    NTSTATUS            status;
-
-    StackLocation =3D IoGetCurrentIrpStackLocation(Irp);
-
-    switch (StackLocation->MajorFunction) {
-    case IRP_MJ_PNP:
-        status =3D FdoDispatchPnp(Fdo, Irp);
-        break;
-
-    case IRP_MJ_POWER:
-        status =3D FdoDispatchPower(Fdo, Irp);
-        break;
-
-    default:
-        status =3D 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 =3D IoGetAttachedDeviceReference(PhysicalDeviceObjec=
t);
-    DeviceType =3D LowerDeviceObject->DeviceType;
-    ObDereferenceObject(LowerDeviceObject);
-
-#pragma prefast(suppress:28197) // Possibly leaking memory 'FilterDeviceOb=
ject'
-    status =3D IoCreateDevice(DriverGetDriverObject(),
-                            sizeof (XENDISK_DX),
-                            NULL,
-                            DeviceType,
-                            FILE_DEVICE_SECURE_OPEN,
-                            FALSE,
-                            &FilterDeviceObject);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    Dx =3D (PXENDISK_DX)FilterDeviceObject->DeviceExtension;
-    RtlZeroMemory(Dx, sizeof (XENDISK_DX));
-
-    Dx->Type =3D FUNCTION_DEVICE_OBJECT;
-    Dx->DeviceObject =3D FilterDeviceObject;
-    Dx->DevicePnpState =3D Added;
-    Dx->SystemPowerState =3D PowerSystemShutdown;
-    Dx->DevicePowerState =3D PowerDeviceD3;
-
-    IoInitializeRemoveLock(&Dx->RemoveLock, FDO_TAG, 0, 0);
-
-    Fdo =3D __FdoAllocate(sizeof (XENDISK_FDO));
-
-    status =3D STATUS_NO_MEMORY;
-    if (Fdo =3D=3D NULL)
-        goto fail2;
-
-    LowerDeviceObject =3D IoAttachDeviceToDeviceStack(FilterDeviceObject,
-                                                    PhysicalDeviceObject);
-
-    status =3D STATUS_UNSUCCESSFUL;
-    if (LowerDeviceObject =3D=3D NULL)
-        goto fail3;
-
-    Fdo->Dx =3D Dx;
-    Fdo->PhysicalDeviceObject =3D PhysicalDeviceObject;
-    Fdo->LowerDeviceObject =3D LowerDeviceObject;
-
-    InitializeMutex(&Fdo->Mutex);
-    InitializeListHead(&Dx->ListEntry);
-    Fdo->References =3D 1;
-
-    Verbose("%p\n", FilterDeviceObject);
-
-    Dx->Fdo =3D Fdo;
-
-#pragma prefast(suppress:28182)  // Dereferencing NULL pointer
-    FilterDeviceObject->DeviceType =3D LowerDeviceObject->DeviceType;
-    FilterDeviceObject->Characteristics =3D LowerDeviceObject->Characteris=
tics;
-
-    FilterDeviceObject->Flags |=3D LowerDeviceObject->Flags;
-    FilterDeviceObject->Flags &=3D ~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 =3D Fdo->LowerDeviceObject;
-    PXENDISK_DX         Dx =3D Fdo->Dx;
-    PDEVICE_OBJECT      FilterDeviceObject =3D Dx->DeviceObject;
-
-    ASSERT(IsListEmpty(&Dx->ListEntry));
-    ASSERT3U(Fdo->References, =3D=3D, 0);
-    ASSERT3U(__FdoGetDevicePnpState(Fdo), =3D=3D, Deleted);
-
-    Dx->Fdo =3D NULL;
-
-    RtlZeroMemory(&Fdo->Mutex, sizeof (MUTEX));
-
-    Fdo->LowerDeviceObject =3D NULL;
-    Fdo->PhysicalDeviceObject =3D NULL;
-    Fdo->Dx =3D 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 =3D 0;
-
-    status =3D KeWaitForSingleObject(&Mutex->Event,
-                                   Executive,
-                                   KernelMode,
-                                   FALSE,
-                                   &Timeout);
-    if (status =3D=3D STATUS_TIMEOUT)
-        return FALSE;
-
-    ASSERT(NT_SUCCESS(status));
-
-    ASSERT3P(Mutex->Owner, =3D=3D, NULL);
-    Mutex->Owner =3D KeGetCurrentThread();
-
-    return TRUE;
-}
-
-static FORCEINLINE VOID
-__drv_maxIRQL(PASSIVE_LEVEL)
-AcquireMutex(
-    IN  PMUTEX  Mutex
-    )
-{
-    NTSTATUS    status;
-
-    status =3D KeWaitForSingleObject(&Mutex->Event,
-                                   Executive,
-                                   KernelMode,
-                                   FALSE,
-                                   NULL);
-
-    ASSERT(NT_SUCCESS(status));
-
-    ASSERT3P(Mutex->Owner, =3D=3D, NULL);
-    Mutex->Owner =3D KeGetCurrentThread();
-}
-
-static FORCEINLINE VOID
-__drv_maxIRQL(PASSIVE_LEVEL)
-ReleaseMutex(
-    IN  PMUTEX  Mutex
-    )
-{
-    ASSERT3P(Mutex->Owner, =3D=3D, KeGetCurrentThread());
-    Mutex->Owner =3D 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 =3D Pdo->Dx;
-
-    // We can never transition out of the deleted state
-    ASSERT(Dx->DevicePnpState !=3D Deleted || State =3D=3D Deleted);
-
-    Dx->PreviousDevicePnpState =3D Dx->DevicePnpState;
-    Dx->DevicePnpState =3D 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 =3D Pdo->Dx;
-
-    if (Dx->DevicePnpState =3D=3D State)
-        Dx->DevicePnpState =3D Dx->PreviousDevicePnpState;
-}
-
-static FORCEINLINE DEVICE_PNP_STATE
-__PdoGetDevicePnpState(
-    IN  PXENDISK_PDO    Pdo
-    )
-{
-    PXENDISK_DX         Dx =3D 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 =3D Pdo->Dx;
-
-    Dx->DevicePowerState =3D State;
-}
-
-static FORCEINLINE DEVICE_POWER_STATE
-__PdoGetDevicePowerState(
-    IN  PXENDISK_PDO    Pdo
-    )
-{
-    PXENDISK_DX         Dx =3D Pdo->Dx;
-
-    return Dx->DevicePowerState;
-}
-
-static FORCEINLINE VOID
-__PdoSetSystemPowerState(
-    IN  PXENDISK_PDO        Pdo,
-    IN  SYSTEM_POWER_STATE  State
-    )
-{
-    PXENDISK_DX             Dx =3D Pdo->Dx;
-
-    Dx->SystemPowerState =3D State;
-}
-
-static FORCEINLINE SYSTEM_POWER_STATE
-__PdoGetSystemPowerState(
-    IN  PXENDISK_PDO    Pdo
-    )
-{
-    PXENDISK_DX         Dx =3D 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 =3D Fdo;
-    FdoAddPhysicalDeviceObject(Fdo, Pdo->Dx->DeviceObject);
-}
-
-static FORCEINLINE VOID
-__PdoUnlink(
-    IN  PXENDISK_PDO    Pdo
-    )
-{
-    PXENDISK_FDO        Fdo =3D Pdo->Fdo;
-
-    ASSERT(Fdo !=3D NULL);
-
-    FdoRemovePhysicalDeviceObject(Fdo, Pdo->Dx->DeviceObject);
-
-    Pdo->Fdo =3D 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 =3D 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 =3D 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(), =3D=3D, PASSIVE_LEVEL);
-
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __PdoForwardIrpSynchronously,
-                           &Event,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-    if (status =3D=3D STATUS_PENDING) {
-        (VOID) KeWaitForSingleObject(&Event,
-                                     Executive,
-                                     KernelMode,
-                                     FALSE,
-                                     NULL);
-        status =3D Irp->IoStatus.Status;
-    } else {
-        ASSERT3U(status, =3D=3D, 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 =3D 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 =3D 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) =3D 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 =3D STATUS_NO_MEMORY;
-    Irp =3D IoAllocateIrp((CCHAR)(Pdo->LowerDeviceObject->StackSize + 1), =
FALSE);
-    if (Irp =3D=3D NULL)
-        goto fail1;
-
-    Stack =3D IoGetNextIrpStackLocation(Irp);
-    Stack->MajorFunction =3D IRP_MJ_SCSI;
-    Stack->Parameters.Scsi.Srb =3D Srb;
-
-    IoSetCompletionRoutine(Irp,
-                            __PdoSendAwaitSrb,
-                            Srb,
-                            TRUE,
-                            TRUE,
-                            TRUE);
-    Irp->UserIosb =3D &IoStatus;
-    Irp->UserEvent =3D &Event;
-
-    Irp->MdlAddress =3D IoAllocateMdl(Srb->DataBuffer,
-                                    Srb->DataTransferLength,
-                                    FALSE,
-                                    FALSE,
-                                    Irp);
-    if (Irp->MdlAddress =3D=3D NULL)
-        goto fail2;
-
-#pragma warning(disable:6320)
-    __try {
-        MmProbeAndLockPages(Irp->MdlAddress, KernelMode, IoWriteAccess);
-    } __except (EXCEPTION_EXECUTE_HANDLER) {
-        status =3D GetExceptionCode();
-
-        goto fail3;
-    }
-#pragma warning(default:6320)
-
-    Srb->OriginalRequest =3D Irp;
-
-    status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-    if (status =3D=3D STATUS_PENDING) {
-        (VOID) KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE,=
 NULL);
-        status =3D 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("=3D=3D=3D=3D>\n");
-
-    Length =3D sizeof(READ_CAPACITY16_DATA);
-
-    status =3D STATUS_NO_MEMORY;
-    Capacity =3D __PdoAllocate(Length);
-    if (Capacity =3D=3D NULL)
-        goto fail1;
-
-    RtlZeroMemory(&Srb, sizeof(SCSI_REQUEST_BLOCK));
-    Srb.Length =3D sizeof(SCSI_REQUEST_BLOCK);
-    Srb.SrbFlags =3D 0;
-    Srb.Function =3D SRB_FUNCTION_EXECUTE_SCSI;
-    Srb.DataBuffer =3D Capacity;
-    Srb.DataTransferLength =3D Length;
-    Srb.TimeOutValue =3D (ULONG)-1;
-    Srb.CdbLength =3D 16;
-
-    Cdb =3D (PCDB)&Srb.Cdb[0];
-    Cdb->READ_CAPACITY16.OperationCode =3D SCSIOP_READ_CAPACITY16;
-    Cdb->READ_CAPACITY16.ServiceAction =3D SERVICE_ACTION_READ_CAPACITY16;
-    *(PULONG)Cdb->READ_CAPACITY16.AllocationLength =3D _byteswap_ulong(Len=
gth);
-
-    status =3D PdoSendAwaitSrb(Pdo, &Srb);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status =3D STATUS_UNSUCCESSFUL;
-    if (Srb.DataTransferLength < Length)
-        goto fail3;
-
-    *SectorSize =3D _byteswap_ulong(Capacity->BytesPerBlock);
-    *PhysSectorSize =3D *SectorSize << Capacity->LogicalPerPhysicalExponen=
t;
-    *SectorCount =3D _byteswap_uint64(Capacity->LogicalBlockAddress.QuadPa=
rt) + 1;
-
-    __PdoFree(Capacity);
-
-    Trace("<=3D=3D=3D=3D\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("=3D=3D=3D=3D>\n");
-
-    Length =3D sizeof(VPD_BLOCK_LIMITS_PAGE);
-    *Supported =3D FALSE;
-
-    status =3D STATUS_NO_MEMORY;
-    BlockLimits =3D __PdoAllocate(Length);
-    if (BlockLimits =3D=3D NULL)
-        goto fail1;
-
-    RtlZeroMemory(&Srb, sizeof(SCSI_REQUEST_BLOCK));
-    Srb.Length =3D sizeof(SCSI_REQUEST_BLOCK);
-    Srb.SrbFlags =3D 0;
-    Srb.Function =3D SRB_FUNCTION_EXECUTE_SCSI;
-    Srb.DataBuffer =3D BlockLimits;
-    Srb.DataTransferLength =3D Length;
-    Srb.TimeOutValue =3D (ULONG)-1;
-    Srb.CdbLength =3D 6;
-
-    Cdb =3D (PCDB)&Srb.Cdb[0];
-    Cdb->CDB6INQUIRY3.OperationCode =3D SCSIOP_INQUIRY;
-    Cdb->CDB6INQUIRY3.PageCode =3D 0xB0;
-    Cdb->CDB6INQUIRY3.EnableVitalProductData =3D 1;
-    Cdb->CDB6INQUIRY3.AllocationLength =3D (UCHAR)Length;
-
-    status =3D PdoSendAwaitSrb(Pdo, &Srb);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status =3D STATUS_UNSUCCESSFUL;
-    if (Srb.DataTransferLength < Length)
-        goto fail3;
-
-    *Supported =3D BlockLimits->UGAValid;
-
-    __PdoFree(BlockLimits);
-
-    Trace("<=3D=3D=3D=3D\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 =3D sizeof(UNMAP_LIST_HEADER) +
-             (Count * sizeof(UNMAP_BLOCK_DESCRIPTOR));
-
-    status =3D STATUS_NO_MEMORY;
-    Unmap =3D __PdoAllocate(Length);
-    if (Unmap =3D=3D NULL)
-        goto fail1;
-
-    RtlZeroMemory(&Srb, sizeof(SCSI_REQUEST_BLOCK));
-    Srb.Length =3D sizeof(SCSI_REQUEST_BLOCK);
-    Srb.SrbFlags =3D 0;
-    Srb.Function =3D SRB_FUNCTION_EXECUTE_SCSI;
-    Srb.DataBuffer =3D Unmap;
-    Srb.DataTransferLength =3D Length;
-    Srb.TimeOutValue =3D (ULONG)-1;
-    Srb.CdbLength =3D 10;
-
-    Cdb =3D (PCDB)&Srb.Cdb[0];
-    Cdb->UNMAP.OperationCode =3D SCSIOP_UNMAP;
-    *(PUSHORT)Cdb->UNMAP.AllocationLength =3D _byteswap_ushort((USHORT)Len=
gth);
-
-    *(PUSHORT)Unmap->DataLength =3D _byteswap_ushort((USHORT)(Length - FIE=
LD_OFFSET(UNMAP_LIST_HEADER, BlockDescrDataLength)));
-    *(PUSHORT)Unmap->BlockDescrDataLength =3D _byteswap_ushort((USHORT)(Le=
ngth - FIELD_OFFSET(UNMAP_LIST_HEADER, Descriptors[0])));
-
-    for (Index =3D 0; Index < Count; ++Index) {
-        PUNMAP_BLOCK_DESCRIPTOR Block =3D &Unmap->Descriptors[Index];
-        PDEVICE_DATA_SET_RANGE  Range =3D &Ranges[Index];
-
-        ULONG   LengthInSectors =3D (ULONG)(Range->LengthInBytes / Pdo->Se=
ctorSize);
-        ULONG64 OffsetInSectors =3D (ULONG64)(Range->StartingOffset / Pdo-=
>SectorSize);
-
-        *(PULONG64)Block->StartingLba =3D _byteswap_uint64(OffsetInSectors=
);
-        *(PULONG)Block->LbaCount =3D _byteswap_ulong(LengthInSectors);
-    }
-
-    status =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-
-    if (StackLocation->Parameters.DeviceIoControl.InputBufferLength <
-        sizeof (STORAGE_PROPERTY_QUERY))
-        return PdoCompleteIrp(Pdo, Irp, STATUS_INFO_LENGTH_MISMATCH);
-
-    Query =3D Irp->AssociatedIrp.SystemBuffer;
-
-    Trace("%s %s\n", PropertyIdName(Query->PropertyId), QueryTypeName(Quer=
y->QueryType));
-
-    switch (Query->PropertyId) {
-    case StorageDeviceTrimProperty:
-        if (!Pdo->InterceptTrim || !Pdo->DiscardSupported) {
-            status =3D PdoForwardIrpAndForget(Pdo, Irp);
-            break;
-        }
-
-        if (Query->QueryType =3D=3D PropertyStandardQuery) {
-            PDEVICE_TRIM_DESCRIPTOR Trim;
-
-            if (StackLocation->Parameters.DeviceIoControl.OutputBufferLeng=
th <
-                sizeof (DEVICE_TRIM_DESCRIPTOR))
-                return PdoCompleteIrp(Pdo, Irp, STATUS_BUFFER_OVERFLOW);
-
-            Trim =3D Irp->AssociatedIrp.SystemBuffer;
-
-            RtlZeroMemory(Trim, sizeof(DEVICE_TRIM_DESCRIPTOR));
-
-            Trim->Version =3D sizeof(DEVICE_TRIM_DESCRIPTOR);
-            Trim->Size =3D sizeof(DEVICE_TRIM_DESCRIPTOR);
-            Trim->TrimEnabled =3D TRUE;
-
-            Irp->IoStatus.Information =3D sizeof(DEVICE_TRIM_DESCRIPTOR);
-        } else {
-            Irp->IoStatus.Information =3D 0;
-        }
-
-        status =3D PdoCompleteIrp(Pdo, Irp, STATUS_SUCCESS);
-        break;
-
-    case StorageAccessAlignmentProperty: {
-        if (Query->QueryType =3D=3D PropertyStandardQuery) {
-            PSTORAGE_ACCESS_ALIGNMENT_DESCRIPTOR AccessAlignment;
-
-            if (StackLocation->Parameters.DeviceIoControl.OutputBufferLeng=
th <
-                sizeof (STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR))
-                return PdoCompleteIrp(Pdo, Irp, STATUS_BUFFER_OVERFLOW);
-
-            AccessAlignment =3D Irp->AssociatedIrp.SystemBuffer;
-
-            RtlZeroMemory(AccessAlignment, sizeof(STORAGE_ACCESS_ALIGNMENT=
_DESCRIPTOR));
-
-            AccessAlignment->Version =3D sizeof(STORAGE_ACCESS_ALIGNMENT_D=
ESCRIPTOR);
-            AccessAlignment->Size =3D sizeof(STORAGE_ACCESS_ALIGNMENT_DESC=
RIPTOR);
-            AccessAlignment->BytesPerCacheLine =3D 0;
-            AccessAlignment->BytesOffsetForCacheAlignment =3D 0;
-            AccessAlignment->BytesPerLogicalSector =3D Pdo->SectorSize;
-            AccessAlignment->BytesPerPhysicalSector =3D Pdo->PhysSectorSiz=
e;
-            AccessAlignment->BytesOffsetForSectorAlignment =3D 0;
-
-            Irp->IoStatus.Information =3D sizeof(STORAGE_ACCESS_ALIGNMENT_=
DESCRIPTOR);
-        } else {
-            Irp->IoStatus.Information =3D 0;
-        }
-
-        status =3D PdoCompleteIrp(Pdo, Irp, STATUS_SUCCESS);
-        break;
-    }
-    default:
-        status =3D 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 =3D Irp->AssociatedIrp.SystemBuffer;
-
-    switch (Attributes->Action) {
-    case DeviceDsmAction_Trim:
-        if (!Pdo->InterceptTrim || !Pdo->DiscardSupported) {
-            status =3D PdoForwardIrpAndForget(Pdo, Irp);
-            break;
-        }
-
-        Ranges =3D (PDEVICE_DATA_SET_RANGE)((PUCHAR)Attributes + Attribute=
s->DataSetRangesOffset);
-        NumRanges =3D Attributes->DataSetRangesLength / sizeof(DEVICE_DATA=
_SET_RANGE);
-
-        status =3D PdoSendTrimSynchronous(Pdo, Ranges, NumRanges);
-
-        status =3D PdoCompleteIrp(Pdo, Irp, status);
-        break;
-
-    default:
-        status =3D 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 =3D IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    StackLocation =3D IoGetCurrentIrpStackLocation(Irp);
-    ControlCode =3D StackLocation->Parameters.DeviceIoControl.IoControlCod=
e;
-    Method =3D METHOD_FROM_CTL_CODE(ControlCode);
-
-    switch (ControlCode) {
-    case IOCTL_STORAGE_QUERY_PROPERTY:
-        ASSERT(Method =3D=3D METHOD_BUFFERED);
-        status =3D PdoQueryProperty(Pdo, Irp);
-        break;
-
-    case IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES:
-        ASSERT(Method =3D=3D METHOD_BUFFERED);
-        status =3D PdoManageDataSetAttributes(Pdo, Irp);
-        break;
-
-    default:
-        status =3D PdoForwardIrpAndForget(Pdo, Irp);
-        break;
-    }
-
-    return status;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    Irp->IoStatus.Status =3D 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 =3D IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status =3D PdoForwardIrpSynchronously(Pdo, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status =3D PdoSendReadCapacity16Synchronous(Pdo,
-                                              &SectorSize,
-                                              &PhysSectorSize,
-                                              &SectorCount);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    status =3D PdoSendInquiryB0Synchronous(Pdo,
-                                         &DiscardSupported);
-    if (!NT_SUCCESS(status))
-        goto fail4;
-
-    Pdo->SectorSize =3D SectorSize;
-    Pdo->PhysSectorSize =3D PhysSectorSize;
-    Pdo->DiscardSupported =3D DiscardSupported;
-
-    Size =3D SectorSize * SectorCount;
-    Size >>=3D 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 =3D PowerDeviceD0;
-    PoSetPowerState(Pdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
-
-    __PdoSetDevicePnpState(Pdo, Started);
-
-    IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-
-    Irp->IoStatus.Status =3D 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 =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    __PdoSetDevicePnpState(Pdo, StopPending);
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __PdoQueryStopDevice,
-                           Pdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-
-    __PdoRestoreDevicePnpState(Pdo, StopPending);
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __PdoCancelStopDevice,
-                           Pdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D Context;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-
-    Pdo->PhysSectorSize =3D 0;
-    Pdo->SectorSize =3D 0;
-
-    return STATUS_SUCCESS;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-PdoStopDevice(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    POWER_STATE         PowerState;
-    NTSTATUS            status;
-
-    status =3D IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    if (__PdoGetDevicePowerState(Pdo) !=3D PowerDeviceD0)
-        goto done;
-
-    __PdoSetDevicePowerState(Pdo, PowerDeviceD3);
-    __PdoSetSystemPowerState(Pdo, PowerSystemShutdown);
-
-    PowerState.DeviceState =3D PowerDeviceD3;
-    PoSetPowerState(Pdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
-
-done:
-    __PdoSetDevicePnpState(Pdo, Stopped);
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __PdoStopDevice,
-                           Pdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    __PdoSetDevicePnpState(Pdo, RemovePending);
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __PdoQueryRemoveDevice,
-                           Pdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    __PdoRestoreDevicePnpState(Pdo, RemovePending);
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __PdoCancelRemoveDevice,
-                           Pdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    __PdoSetDevicePnpState(Pdo, SurpriseRemovePending);
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __PdoSurpriseRemoval,
-                           Pdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-PdoRemoveDevice(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    PXENDISK_FDO        Fdo =3D __PdoGetFdo(Pdo);
-    POWER_STATE         PowerState;
-    NTSTATUS            status;
-
-    status =3D IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    if (__PdoGetDevicePowerState(Pdo) !=3D PowerDeviceD0)
-        goto done;
-
-    __PdoSetDevicePowerState(Pdo, PowerDeviceD3);
-    __PdoSetSystemPowerState(Pdo, PowerSystemShutdown);
-
-    PowerState.DeviceState =3D PowerDeviceD3;
-    PoSetPowerState(Pdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
-
-done:
-    FdoAcquireMutex(Fdo);
-    __PdoSetDevicePnpState(Pdo, Deleted);
-    FdoReleaseMutex(Fdo);
-
-    IoReleaseRemoveLockAndWait(&Pdo->Dx->RemoveLock, Irp);
-
-    status =3D PdoForwardIrpSynchronously(Pdo, Irp);
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    Pdo->PhysSectorSize =3D 0;
-    Pdo->SectorSize =3D 0;
-
-    FdoAcquireMutex(Fdo);
-    PdoDestroy(Pdo);
-    FdoReleaseMutex(Fdo);
-
-    IoInvalidateDeviceRelations(FdoGetPhysicalDeviceObject(Fdo),
-                                BusRelations);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-PdoEject(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    PXENDISK_FDO        Fdo =3D __PdoGetFdo(Pdo);
-    NTSTATUS            status;
-
-    __PdoSetDevicePnpState(Pdo, Deleted);
-
-    status =3D 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 =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-    MinorFunction =3D StackLocation->MinorFunction;
-
-    switch (StackLocation->MinorFunction) {
-    case IRP_MN_START_DEVICE:
-        status =3D PdoStartDevice(Pdo, Irp);
-        break;
-
-    case IRP_MN_QUERY_STOP_DEVICE:
-        status =3D PdoQueryStopDevice(Pdo, Irp);
-        break;
-
-    case IRP_MN_CANCEL_STOP_DEVICE:
-        status =3D PdoCancelStopDevice(Pdo, Irp);
-        break;
-
-    case IRP_MN_STOP_DEVICE:
-        status =3D PdoStopDevice(Pdo, Irp);
-        break;
-
-    case IRP_MN_QUERY_REMOVE_DEVICE:
-        status =3D PdoQueryRemoveDevice(Pdo, Irp);
-        break;
-
-    case IRP_MN_SURPRISE_REMOVAL:
-        status =3D PdoSurpriseRemoval(Pdo, Irp);
-        break;
-
-    case IRP_MN_REMOVE_DEVICE:
-        status =3D PdoRemoveDevice(Pdo, Irp);
-        break;
-
-    case IRP_MN_CANCEL_REMOVE_DEVICE:
-        status =3D PdoCancelRemoveDevice(Pdo, Irp);
-        break;
-
-    case IRP_MN_EJECT:
-        status =3D PdoEject(Pdo, Irp);
-        break;
-
-    default:
-        status =3D IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-        if (!NT_SUCCESS(status))
-            goto fail1;
-
-        IoCopyCurrentIrpStackLocationToNext(Irp);
-        IoSetCompletionRoutine(Irp,
-                               __PdoDispatchPnp,
-                               Pdo,
-                               TRUE,
-                               TRUE,
-                               TRUE);
-
-        status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-        break;
-    }
-
-    return status;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    Irp->IoStatus.Status =3D 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 =3D (PXENDISK_PDO) Context;
-    PIO_STACK_LOCATION  StackLocation;
-    POWER_STATE         PowerState;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    StackLocation =3D IoGetCurrentIrpStackLocation(Irp);
-    PowerState =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-    PowerState =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-    DeviceState =3D StackLocation->Parameters.Power.State.DeviceState;
-    PowerAction =3D StackLocation->Parameters.Power.ShutdownType;
-
-    Trace("=3D=3D=3D=3D> (%s:%s)\n",
-          PowerDeviceStateName(DeviceState),
-          PowerActionName(PowerAction));
-
-    if (DeviceState =3D=3D __PdoGetDevicePowerState(Pdo)) {
-        IoSkipCurrentIrpStackLocation(Irp);
-        status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-        goto done;
-    }
-
-    status =3D DeviceState < __PdoGetDevicePowerState(Pdo) ?
-             __PdoSetDevicePowerUp(Pdo, Irp) :
-             __PdoSetDevicePowerDown(Pdo, Irp);
-
-done:
-    Trace("<=3D=3D=3D=3D (%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 =3D (PXENDISK_PDO) Context;
-    PIO_STACK_LOCATION  StackLocation;
-    SYSTEM_POWER_STATE  SystemState;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    StackLocation =3D IoGetCurrentIrpStackLocation(Irp);
-    SystemState =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-    SystemState =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-    SystemState =3D StackLocation->Parameters.Power.State.SystemState;
-    PowerAction =3D StackLocation->Parameters.Power.ShutdownType;
-
-    Trace("=3D=3D=3D=3D> (%s:%s)\n",
-          PowerSystemStateName(SystemState),
-          PowerActionName(PowerAction));
-
-    if (SystemState =3D=3D __PdoGetSystemPowerState(Pdo)) {
-        IoSkipCurrentIrpStackLocation(Irp);
-        status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-        goto done;
-    }
-
-    status =3D SystemState < __PdoGetSystemPowerState(Pdo) ?
-             __PdoSetSystemPowerUp(Pdo, Irp) :
-             __PdoSetSystemPowerDown(Pdo, Irp);
-
-done:
-    Trace("<=3D=3D=3D=3D (%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 =3D IoGetCurrentIrpStackLocation(Irp);
-
-    switch (StackLocation->MinorFunction) {
-    case IRP_MN_SET_POWER:
-        status =3D __PdoSetDevicePower(Pdo, Irp);
-        break;
-
-    default:
-        IoSkipCurrentIrpStackLocation(Irp);
-        status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-        break;
-    }
-
-    return status;
-}
-
-static NTSTATUS
-PdoSystemPower(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    NTSTATUS            status;
-    PIO_STACK_LOCATION  StackLocation;
-
-    StackLocation =3D IoGetCurrentIrpStackLocation(Irp);
-
-    switch (StackLocation->MinorFunction) {
-    case IRP_MN_SET_POWER:
-        status =3D __PdoSetSystemPower(Pdo, Irp);
-        break;
-
-    default:
-        IoSkipCurrentIrpStackLocation(Irp);
-        status =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-    PowerType =3D StackLocation->Parameters.Power.Type;
-
-    switch (PowerType) {
-    case DevicePowerState:
-        status =3D PdoDevicePower(Pdo, Irp);
-        break;
-
-    case SystemPowerState:
-        status =3D PdoSystemPower(Pdo, Irp);
-        break;
-
-    default:
-        IoSkipCurrentIrpStackLocation(Irp);
-        status =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __PdoDispatchDefault,
-                           Pdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    Irp->IoStatus.Status =3D status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-NTSTATUS
-PdoDispatch(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    NTSTATUS            status;
-
-    StackLocation =3D IoGetCurrentIrpStackLocation(Irp);
-
-    switch (StackLocation->MajorFunction) {
-    case IRP_MJ_DEVICE_CONTROL:
-        status =3D PdoDispatchControl(Pdo, Irp);
-        break;
-
-    case IRP_MJ_PNP:
-        status =3D PdoDispatchPnp(Pdo, Irp);
-        break;
-
-    case IRP_MJ_POWER:
-        status =3D PdoDispatchPower(Pdo, Irp);
-        break;
-
-    default:
-        status =3D 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 =3D IoGetAttachedDeviceReference(PhysicalDeviceObjec=
t);
-    DeviceType =3D LowerDeviceObject->DeviceType;
-    ObDereferenceObject(LowerDeviceObject);
-
-#pragma prefast(suppress:28197) // Possibly leaking memory 'PhysicalDevice=
Object'
-    status =3D IoCreateDevice(DriverGetDriverObject(),
-                            sizeof(XENDISK_DX),
-                            NULL,
-                            DeviceType,
-                            FILE_DEVICE_SECURE_OPEN,
-                            FALSE,
-                            &FilterDeviceObject);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    Dx =3D (PXENDISK_DX)FilterDeviceObject->DeviceExtension;
-    RtlZeroMemory(Dx, sizeof (XENDISK_DX));
-
-    Dx->Type =3D PHYSICAL_DEVICE_OBJECT;
-    Dx->DeviceObject =3D FilterDeviceObject;
-    Dx->DevicePnpState =3D Present;
-    Dx->SystemPowerState =3D PowerSystemShutdown;
-    Dx->DevicePowerState =3D PowerDeviceD3;
-
-    IoInitializeRemoveLock(&Dx->RemoveLock, PDO_TAG, 0, 0);
-
-    Pdo =3D __PdoAllocate(sizeof (XENDISK_PDO));
-
-    status =3D STATUS_NO_MEMORY;
-    if (Pdo =3D=3D NULL)
-        goto fail2;
-
-    LowerDeviceObject =3D IoAttachDeviceToDeviceStack(FilterDeviceObject,
-                                                    PhysicalDeviceObject);
-
-    status =3D STATUS_UNSUCCESSFUL;
-    if (LowerDeviceObject =3D=3D NULL)
-        goto fail3;
-
-    Pdo->Dx =3D Dx;
-    Pdo->PhysicalDeviceObject =3D PhysicalDeviceObject;
-    Pdo->LowerDeviceObject =3D LowerDeviceObject;
-
-    __PdoSetName(Pdo, DeviceID, InstanceID);
-
-    ParametersKey =3D DriverGetParametersKey();
-
-    Pdo->InterceptTrim =3D TRUE;
-
-    status =3D RegistryQueryDwordValue(ParametersKey,
-                                     "InterceptTrim",
-                                     &InterceptTrim);
-    if (NT_SUCCESS(status))
-        Pdo->InterceptTrim =3D (InterceptTrim !=3D 0) ? TRUE : FALSE;
-
-    Verbose("%p (%s)\n", FilterDeviceObject, __PdoGetName(Pdo));
-
-    Dx->Pdo =3D Pdo;
-
-#pragma prefast(suppress:28182) // Dereferencing NULL pointer
-    FilterDeviceObject->DeviceType =3D LowerDeviceObject->DeviceType;
-    FilterDeviceObject->Characteristics =3D LowerDeviceObject->Characteris=
tics;
-
-    FilterDeviceObject->Flags |=3D LowerDeviceObject->Flags;
-    FilterDeviceObject->Flags &=3D ~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 =3D Pdo->LowerDeviceObject;
-    PXENDISK_DX         Dx =3D Pdo->Dx;
-    PDEVICE_OBJECT      FilterDeviceObject =3D Dx->DeviceObject;
-
-    ASSERT3U(__PdoGetDevicePnpState(Pdo), =3D=3D, Deleted);
-
-    __PdoUnlink(Pdo);
-
-    Verbose("%s\n", __PdoGetName(Pdo));
-
-    Dx->Pdo =3D NULL;
-
-    Pdo->InterceptTrim =3D FALSE;
-    Pdo->DiscardSupported =3D FALSE;
-
-    RtlZeroMemory(Pdo->Name, sizeof (Pdo->Name));
-
-    Pdo->PhysicalDeviceObject =3D NULL;
-    Pdo->LowerDeviceObject =3D NULL;
-    Pdo->Dx =3D 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_T=
YPE, 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, =3D=3D, NULL);
-
-    status =3D RtlUpcaseUnicodeString(&RegistryPath, Path, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    ASSERT3P(RegistryDriverObject, =3D=3D, NULL);
-    RegistryDriverObject =3D DriverObject;
-
-    ASSERT3P(__IoOpenDriverRegistryKey, =3D=3D, NULL);
-    RtlInitUnicodeString(&Unicode, L"IoOpenDriverRegistryKey");
-
-    Func =3D MmGetSystemRoutineAddress(&Unicode);
-    if (Func !=3D NULL)
-        __IoOpenDriverRegistryKey =3D (IOOPENDRIVERREGISTRYKEY)Func;
-
-    return STATUS_SUCCESS;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
-}
-
-VOID
-RegistryTeardown(
-    VOID
-    )
-{
-    __IoOpenDriverRegistryKey =3D NULL;
-
-    RegistryDriverObject =3D NULL;
-
-    RtlFreeUnicodeString(&RegistryPath);
-    RegistryPath.Buffer =3D NULL;
-    RegistryPath.MaximumLength =3D RegistryPath.Length =3D 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 =3D 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[] =3D L"\\Registry\\Machine\\";
-    ULONG               Length;
-    UNICODE_STRING      Unicode;
-    NTSTATUS            status;
-
-    Length =3D (ULONG)wcslen(Prefix);
-
-    status =3D STATUS_INVALID_PARAMETER;
-    if (_wcsnicmp(Path, Prefix, Length) !=3D 0)
-        goto fail1;
-
-    RtlInitUnicodeString(&Unicode, Prefix);
-
-    status =3D RegistryOpenKey(NULL, &Unicode, KEY_ALL_ACCESS, Parent);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    *ChildPath =3D 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 =3D __RegistryAllocate(Path->MaximumLength + sizeof (WCHAR));
-
-    status =3D STATUS_NO_MEMORY;
-    if (Buffer =3D=3D NULL)
-        goto fail1;
-
-    RtlCopyMemory(Buffer, Path->Buffer, Path->Length);
-
-    Root =3D Parent;
-
-    if (Parent !=3D NULL) {
-        ChildPath =3D Buffer;
-    } else {
-        status =3D RegistryOpenRoot(Buffer, &Parent, &ChildPath);
-        if (!NT_SUCCESS(status))
-            goto fail2;
-    }
-
-    ChildName =3D __wcstok_r(ChildPath, L"\\", &Context);
-
-    status =3D STATUS_INVALID_PARAMETER;
-    if (ChildName =3D=3D NULL)
-        goto fail3;
-
-    Child =3D NULL;
-
-    while (ChildName !=3D NULL) {
-        UNICODE_STRING      Unicode;
-        OBJECT_ATTRIBUTES   Attributes;
-
-        RtlInitUnicodeString(&Unicode, ChildName);
-
-        InitializeObjectAttributes(&Attributes,
-                                   &Unicode,
-                                   OBJ_CASE_INSENSITIVE |
-                                   OBJ_KERNEL_HANDLE |
-                                   OBJ_OPENIF,
-                                   Parent,
-                                   NULL);
-
-        status =3D ZwCreateKey(&Child,
-                             KEY_ALL_ACCESS,
-                             &Attributes,
-                             0,
-                             NULL,
-                             Options,
-                             NULL
-                             );
-        if (!NT_SUCCESS(status))
-            goto fail4;
-
-        ChildName =3D __wcstok_r(NULL, L"\\", &Context);
-
-        if (Parent !=3D Root)
-            ZwClose(Parent);
-
-        Parent =3D Child;
-    }
-
-    ASSERT(Child !=3D NULL);
-
-    *Key =3D Child;
-
-    __RegistryFree(Buffer);
-
-    return STATUS_SUCCESS;
-
-fail4:
-fail3:
-    if (Parent !=3D 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 !=3D NULL) {
-        status =3D __IoOpenDriverRegistryKey(RegistryDriverObject,
-                                           DriverRegKeyParameters,
-                                           DesiredAccess,
-                                           0,
-                                           Key);
-        if (!NT_SUCCESS(status))
-            goto fail1;
-
-        goto done;
-    }
-
-    status =3D RegistryOpenKey(NULL, &RegistryPath, DesiredAccess, &Servic=
eKey);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status =3D 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 =3D 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 =3D IoOpenDeviceRegistryKey(DeviceObject,
-                                     PLUGPLAY_REGKEY_DEVICE,
-                                     KEY_READ,
-                                     &SubKey);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    Length =3D 0;
-    status =3D ZwQueryKey(SubKey,
-                        KeyNameInformation,
-                        NULL,
-                        0,
-                        &Length);
-    if (status !=3D STATUS_BUFFER_OVERFLOW &&
-        status !=3D STATUS_BUFFER_TOO_SMALL)
-        goto fail2;
-
-#pragma prefast(suppress:6102)
-    Info =3D __RegistryAllocate(Length + sizeof (WCHAR));
-
-    status =3D STATUS_NO_MEMORY;
-    if (Info =3D=3D NULL)
-        goto fail3;
-
-    status =3D ZwQueryKey(SubKey,
-                        KeyNameInformation,
-                        Info,
-                        Length,
-                        &Length);
-    if (!NT_SUCCESS(status))
-        goto fail4;
-
-    Info->Name[Info->NameLength / sizeof (WCHAR)] =3D '\0';
-
-    Cursor =3D wcsrchr(Info->Name, L'\\');
-    ASSERT(Cursor !=3D NULL);
-
-    *Cursor =3D L'\0';
-
-    RtlInitUnicodeString(&Unicode, Info->Name);
-
-    status =3D 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 =3D RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status =3D 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 =3D RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status =3D 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 =3D RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status =3D RegistryOpenKey(Key, &Unicode, KEY_ALL_ACCESS, &SubKey);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status =3D 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 =3D ZwQueryKey(Key,
-                        KeyFullInformation,
-                        NULL,
-                        0,
-                        &Size);
-    if (status !=3D STATUS_BUFFER_OVERFLOW &&
-        status !=3D STATUS_BUFFER_TOO_SMALL)
-        goto fail1;
-
-#pragma prefast(suppress:6102)
-    Full =3D __RegistryAllocate(Size);
-
-    status =3D STATUS_NO_MEMORY;
-    if (Full =3D=3D NULL)
-        goto fail2;
-
-    status =3D ZwQueryKey(Key,
-                        KeyFullInformation,
-                        Full,
-                        Size,
-                        &Size);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    Size =3D FIELD_OFFSET(KEY_BASIC_INFORMATION, Name) +
-           Full->MaxNameLen;
-
-    Basic =3D __RegistryAllocate(Size);
-    status =3D STATUS_NO_MEMORY;
-    if (Basic =3D=3D NULL)
-        goto fail4;
-
-    for (Index =3D 0; Index < Full->SubKeys; Index++) {
-        ULONG           Ignore;
-        UNICODE_STRING  Unicode;
-        ANSI_STRING     Ansi;
-
-        status =3D ZwEnumerateKey(Key,
-                                Index,
-                                KeyBasicInformation,
-                                Basic,
-                                Size,
-                                &Ignore);
-        if (!NT_SUCCESS(status))
-            goto fail5;
-
-        Unicode.MaximumLength =3D (USHORT)Basic->NameLength;
-        Unicode.Buffer =3D Basic->Name;
-        Unicode.Length =3D (USHORT)Basic->NameLength;
-
-        Ansi.MaximumLength =3D (USHORT)((Basic->NameLength / sizeof (WCHAR=
)) + sizeof (CHAR));
-        Ansi.Buffer =3D __RegistryAllocate(Ansi.MaximumLength);
-
-        status =3D STATUS_NO_MEMORY;
-        if (Ansi.Buffer =3D=3D NULL)
-            goto fail6;
-
-        status =3D RtlUnicodeStringToAnsiString(&Ansi, &Unicode, FALSE);
-        ASSERT(NT_SUCCESS(status));
-
-        Ansi.Length =3D (USHORT)(strlen(Ansi.Buffer) * sizeof (CHAR));
-
-        status =3D Callback(Context, Key, &Ansi);
-
-        __RegistryFree(Ansi.Buffer);
-        Ansi.Buffer =3D 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_STRIN=
G, ULONG),
-    IN  PVOID                       Context
-    )
-{
-    ULONG                           Size;
-    NTSTATUS                        status;
-    PKEY_FULL_INFORMATION           Full;
-    PKEY_VALUE_BASIC_INFORMATION    Basic;
-    ULONG                           Index;
-
-    status =3D ZwQueryKey(Key,
-                        KeyFullInformation,
-                        NULL,
-                        0,
-                        &Size);
-    if (status !=3D STATUS_BUFFER_OVERFLOW &&
-        status !=3D STATUS_BUFFER_TOO_SMALL)
-        goto fail1;
-
-#pragma prefast(suppress:6102)
-    Full =3D __RegistryAllocate(Size);
-
-    status =3D STATUS_NO_MEMORY;
-    if (Full =3D=3D NULL)
-        goto fail2;
-
-    status =3D ZwQueryKey(Key,
-                        KeyFullInformation,
-                        Full,
-                        Size,
-                        &Size);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    Size =3D FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name) +
-           Full->MaxValueNameLen;
-
-    Basic =3D __RegistryAllocate(Size);
-    status =3D STATUS_NO_MEMORY;
-    if (Basic =3D=3D NULL)
-        goto fail4;
-
-    for (Index =3D 0; Index < Full->Values; Index++) {
-        ULONG           Ignore;
-        UNICODE_STRING  Unicode;
-        ANSI_STRING     Ansi;
-
-        status =3D ZwEnumerateValueKey(Key,
-                                     Index,
-                                     KeyValueBasicInformation,
-                                     Basic,
-                                     Size,
-                                     &Ignore);
-        if (!NT_SUCCESS(status))
-            goto fail5;
-
-        Unicode.MaximumLength =3D (USHORT)Basic->NameLength;
-        Unicode.Buffer =3D Basic->Name;
-        Unicode.Length =3D (USHORT)Basic->NameLength;
-
-        Ansi.MaximumLength =3D (USHORT)((Basic->NameLength / sizeof (WCHAR=
)) + sizeof (CHAR));
-        Ansi.Buffer =3D __RegistryAllocate(Ansi.MaximumLength);
-
-        status =3D RtlUnicodeStringToAnsiString(&Ansi, &Unicode, FALSE);
-        ASSERT(NT_SUCCESS(status));
-
-        Ansi.Length =3D (USHORT)(strlen(Ansi.Buffer) * sizeof (CHAR));
-
-        status =3D 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 =3D RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status =3D 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 =3D RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status =3D ZwQueryValueKey(Key,
-                             &Unicode,
-                             KeyValuePartialInformation,
-                             NULL,
-                             0,
-                             &Size);
-    if (status !=3D STATUS_BUFFER_OVERFLOW &&
-        status !=3D STATUS_BUFFER_TOO_SMALL)
-        goto fail2;
-
-#pragma prefast(suppress:6102)
-    Partial =3D __RegistryAllocate(Size);
-
-    status =3D STATUS_NO_MEMORY;
-    if (Partial =3D=3D NULL)
-        goto fail3;
-
-    status =3D ZwQueryValueKey(Key,
-                             &Unicode,
-                             KeyValuePartialInformation,
-                             Partial,
-                             Size,
-                             &Size);
-    if (!NT_SUCCESS(status))
-        goto fail4;
-
-    status =3D STATUS_INVALID_PARAMETER;
-    if (Partial->Type !=3D REG_DWORD ||
-        Partial->DataLength !=3D sizeof (ULONG))
-        goto fail5;
-
-    *Value =3D *(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 =3D RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    Partial =3D __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMAT=
ION, Data) +
-                                 sizeof (ULONG));
-
-    status =3D STATUS_NO_MEMORY;
-    if (Partial =3D=3D NULL)
-        goto fail2;
-
-    Partial->TitleIndex =3D 0;
-    Partial->Type =3D REG_DWORD;
-    Partial->DataLength =3D sizeof (ULONG);
-    *(PULONG)Partial->Data =3D Value;
-
-    status =3D 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 =3D __RegistryAllocate(sizeof (ANSI_STRING) * 2);
-
-    status =3D STATUS_NO_MEMORY;
-    if (Ansi =3D=3D NULL)
-        goto fail1;
-
-    Length =3D (ULONG)wcslen(Buffer);
-    Ansi[0].MaximumLength =3D (USHORT)(Length + 1) * sizeof (CHAR);
-    Ansi[0].Buffer =3D __RegistryAllocate(Ansi[0].MaximumLength);
-
-    status =3D STATUS_NO_MEMORY;
-    if (Ansi[0].Buffer =3D=3D NULL)
-        goto fail2;
-
-    RtlInitUnicodeString(&Unicode, Buffer);
-    status =3D RtlUnicodeStringToAnsiString(&Ansi[0], &Unicode, FALSE);
-    ASSERT(NT_SUCCESS(status));
-
-    Ansi[0].Length =3D (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 =3D 0;
-    Count =3D 0;
-    for (;;) {
-        ULONG   Length;
-
-        Length =3D (ULONG)wcslen(&Buffer[Index]);
-        if (Length =3D=3D 0)
-            break;
-
-        Index +=3D Length + 1;
-        Count++;
-    }
-
-    Ansi =3D __RegistryAllocate(sizeof (ANSI_STRING) * (Count + 1));
-
-    status =3D STATUS_NO_MEMORY;
-    if (Ansi =3D=3D NULL)
-        goto fail1;
-
-    for (Index =3D 0; Index < Count; Index++) {
-        ULONG           Length;
-        UNICODE_STRING  Unicode;
-
-        Length =3D (ULONG)wcslen(Buffer);
-        Ansi[Index].MaximumLength =3D (USHORT)(Length + 1) * sizeof (CHAR)=
;
-        Ansi[Index].Buffer =3D __RegistryAllocate(Ansi[Index].MaximumLengt=
h);
-
-        status =3D STATUS_NO_MEMORY;
-        if (Ansi[Index].Buffer =3D=3D NULL)
-            goto fail2;
-
-        RtlInitUnicodeString(&Unicode, Buffer);
-
-        status =3D RtlUnicodeStringToAnsiString(&Ansi[Index], &Unicode, FA=
LSE);
-        ASSERT(NT_SUCCESS(status));
-
-        Ansi[Index].Length =3D (USHORT)Length * sizeof (CHAR);
-        Buffer +=3D Length + 1;
-    }
-
-    return Ansi;
-
-fail2:
-    while (--Index >=3D 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 =3D RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status =3D ZwQueryValueKey(Key,
-                             &Unicode,
-                             KeyValuePartialInformation,
-                             NULL,
-                             0,
-                             &Size);
-    if (status !=3D STATUS_BUFFER_OVERFLOW &&
-        status !=3D STATUS_BUFFER_TOO_SMALL)
-        goto fail2;
-
-#pragma prefast(suppress:6102)
-    Value =3D __RegistryAllocate(Size);
-
-    status =3D STATUS_NO_MEMORY;
-    if (Value =3D=3D NULL)
-        goto fail3;
-
-    status =3D ZwQueryValueKey(Key,
-                             &Unicode,
-                             KeyValuePartialInformation,
-                             Value,
-                             Size,
-                             &Size);
-    if (!NT_SUCCESS(status))
-        goto fail4;
-
-    switch (Value->Type) {
-    case REG_SZ:
-        status =3D STATUS_NO_MEMORY;
-        *Array =3D RegistrySzToAnsi((PWCHAR)Value->Data);
-        break;
-
-    case REG_MULTI_SZ:
-        status =3D STATUS_NO_MEMORY;
-        *Array =3D RegistryMultiSzToAnsi((PWCHAR)Value->Data);
-        break;
-
-    default:
-        status =3D STATUS_INVALID_PARAMETER;
-        *Array =3D NULL;
-        break;
-    }
-
-    if (*Array =3D=3D NULL)
-        goto fail5;
-
-    if (Type !=3D NULL)
-        *Type =3D 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 =3D RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status =3D ZwQueryValueKey(Key,
-                             &Unicode,
-                             KeyValuePartialInformation,
-                             NULL,
-                             0,
-                             &Size);
-    if (status !=3D STATUS_BUFFER_OVERFLOW &&
-        status !=3D STATUS_BUFFER_TOO_SMALL)
-        goto fail2;
-
-#pragma prefast(suppress:6102)
-    Partial =3D __RegistryAllocate(Size);
-
-    status =3D STATUS_NO_MEMORY;
-    if (Partial =3D=3D NULL)
-        goto fail3;
-
-    status =3D ZwQueryValueKey(Key,
-                             &Unicode,
-                             KeyValuePartialInformation,
-                             Partial,
-                             Size,
-                             &Size);
-    if (!NT_SUCCESS(status))
-        goto fail4;
-
-    switch (Partial->Type) {
-    case REG_BINARY:
-        *Buffer =3D __RegistryAllocate(Partial->DataLength);
-
-        status =3D STATUS_NO_MEMORY;
-        if (*Buffer =3D=3D NULL)
-            break;
-
-        *Length =3D Partial->DataLength;
-        RtlCopyMemory(*Buffer, Partial->Data, Partial->DataLength);
-        break;
-
-    default:
-        status =3D STATUS_INVALID_PARAMETER;
-        *Buffer =3D NULL;
-        break;
-    }
-
-    if (*Buffer =3D=3D 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 =3D RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    Partial =3D __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMAT=
ION, Data) +
-                                 Length);
-
-    status =3D STATUS_NO_MEMORY;
-    if (Partial =3D=3D NULL)
-        goto fail2;
-
-    Partial->TitleIndex =3D 0;
-    Partial->Type =3D REG_BINARY;
-    Partial->DataLength =3D Length;
-    RtlCopyMemory(Partial->Data, Buffer, Partial->DataLength);
-
-    status =3D 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 =3D ZwQueryKey(Key,
-                        KeyNameInformation,
-                        NULL,
-                        0,
-                        &Size);
-    if (status !=3D STATUS_BUFFER_OVERFLOW &&
-        status !=3D STATUS_BUFFER_TOO_SMALL)
-        goto fail1;
-
-    // Name information is not intrinsically NULL terminated
-#pragma prefast(suppress:6102)
-    Value =3D __RegistryAllocate(Size + sizeof (WCHAR));
-
-    status =3D STATUS_NO_MEMORY;
-    if (Value =3D=3D NULL)
-        goto fail2;
-
-    status =3D ZwQueryKey(Key,
-                        KeyNameInformation,
-                        Value,
-                        Size,
-                        &Size);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    Value->Name[Value->NameLength / sizeof (WCHAR)] =3D L'\0';
-    *Array =3D RegistrySzToAnsi((PWCHAR)Value->Name);
-
-    status =3D STATUS_NO_MEMORY;
-    if (*Array =3D=3D 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\\CurrentC=
ontrolSet\\Control");
-
-    status =3D RegistryOpenKey(NULL, &Unicode, KEY_READ, &Key);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status =3D 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 =3D (ULONG)strlen(Prefix);
-
-    Option =3D __strtok_r(Ansi[0].Buffer, " ", &Context);
-    while (Option !=3D NULL) {
-        if (strncmp(Prefix, Option, Length) =3D=3D 0)
-            goto found;
-
-        Option =3D __strtok_r(NULL, " ", &Context);
-    }
-
-    status =3D STATUS_OBJECT_NAME_NOT_FOUND;
-    goto fail3;
-
-found:
-    *Value =3D __RegistryAllocate(sizeof (ANSI_STRING) * 2);
-
-    status =3D STATUS_NO_MEMORY;
-    if (*Value =3D=3D NULL)
-        goto fail4;
-
-    Length =3D (ULONG)strlen(Option);
-    (*Value)[0].MaximumLength =3D (USHORT)(Length + 1) * sizeof (CHAR);
-    (*Value)[0].Buffer =3D __RegistryAllocate((*Value)[0].MaximumLength);
-
-    status =3D STATUS_NO_MEMORY;
-    if ((*Value)[0].Buffer =3D=3D NULL)
-        goto fail5;
-
-    RtlCopyMemory((*Value)[0].Buffer, Option, Length * sizeof (CHAR));
-
-    (*Value)[0].Length =3D (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 =3D Ansi->Length + 1;
-    Partial =3D __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMAT=
ION, Data) +
-                                 Length * sizeof (WCHAR));
-
-    status =3D STATUS_NO_MEMORY;
-    if (Partial =3D=3D NULL)
-        goto fail1;
-
-    Partial->TitleIndex =3D 0;
-    Partial->Type =3D REG_SZ;
-    Partial->DataLength =3D Length * sizeof (WCHAR);
-
-    Unicode.MaximumLength =3D (UCHAR)Partial->DataLength;
-    Unicode.Buffer =3D (PWCHAR)Partial->Data;
-    Unicode.Length =3D 0;
-
-    status =3D 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 =3D 1;
-    for (Index =3D 0; Ansi[Index].Buffer !=3D NULL; Index++)
-        Length +=3D Ansi[Index].Length + 1;
-
-    Partial =3D __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMAT=
ION, Data) +
-                               Length * sizeof (WCHAR));
-
-    status =3D STATUS_NO_MEMORY;
-    if (Partial =3D=3D NULL)
-        goto fail1;
-
-    Partial->TitleIndex =3D 0;
-    Partial->Type =3D REG_MULTI_SZ;
-    Partial->DataLength =3D Length * sizeof (WCHAR);
-
-    Unicode.MaximumLength =3D (USHORT)Partial->DataLength;
-    Unicode.Buffer =3D (PWCHAR)Partial->Data;
-    Unicode.Length =3D 0;
-
-    for (Index =3D 0; Ansi[Index].Buffer !=3D NULL; Index++) {
-        status =3D RtlAnsiStringToUnicodeString(&Unicode, &Ansi[Index], FA=
LSE);
-        if (!NT_SUCCESS(status))
-            goto fail2;
-
-        Length =3D Unicode.Length / sizeof (WCHAR);
-
-        ASSERT3U(Unicode.MaximumLength, >=3D, (Length + 1) * sizeof (WCHAR=
));
-        Unicode.MaximumLength -=3D (USHORT)((Length + 1) * sizeof (WCHAR))=
;
-        Unicode.Buffer +=3D Length + 1;
-        Unicode.Length =3D 0;
-    }
-    *Unicode.Buffer =3D 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 =3D RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    switch (Type) {
-    case REG_SZ:
-        status =3D STATUS_NO_MEMORY;
-        Partial =3D RegistryAnsiToSz(Array);
-        break;
-
-    case REG_MULTI_SZ:
-        status =3D STATUS_NO_MEMORY;
-        Partial =3D RegistryAnsiToMultiSz(Array);
-        break;
-
-    default:
-        status =3D STATUS_INVALID_PARAMETER;
-        Partial =3D NULL;
-        break;
-    }
-
-    if (Partial =3D=3D NULL)
-        goto fail2;
-
-    status =3D 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 =3D=3D NULL)
-        return;
-
-    for (Index =3D 0; Array[Index].Buffer !=3D 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 =3D TRUE;
-    __ThreadWake(Thread);
-}
-
-VOID
-ThreadAlert(
-    IN  PXENDISK_THREAD Thread
-    )
-{
-    __ThreadAlert(Thread);
-}
-
-KSTART_ROUTINE  ThreadFunction;
-
-VOID
-ThreadFunction(
-    IN  PVOID       Argument
-    )
-{
-    PXENDISK_THREAD Self =3D Argument;
-    NTSTATUS        status;
-
-    status =3D Self->Function(Self, Self->Context);
-
-    if (InterlockedDecrement(&Self->References) =3D=3D 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(), =3D=3D, PASSIVE_LEVEL);
-
-    (*Thread) =3D __ThreadAllocate(sizeof (XENDISK_THREAD));
-
-    status =3D STATUS_NO_MEMORY;
-    if (*Thread =3D=3D NULL)
-        goto fail1;
-
-    (*Thread)->Function =3D Function;
-    (*Thread)->Context =3D Context;
-    (*Thread)->Alerted =3D FALSE;
-    (*Thread)->References =3D 2; // One for us, one for the thread functio=
n
-
-    KeInitializeEvent(&(*Thread)->Event, NotificationEvent, FALSE);
-
-    status =3D PsCreateSystemThread(&Handle,
-                                  STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_AL=
L,
-                                  NULL,
-                                  NULL,
-                                  NULL,
-                                  ThreadFunction,
-                                  *Thread);
-    if (!NT_SUCCESS(status)) {
-        --(*Thread)->References;    // Fake thread function termination
-        goto fail2;
-    }
-
-    status =3D 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) =3D=3D 0)
-        __ThreadFree(*Thread);
-
-    *Thread =3D 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(), =3D=3D, PASSIVE_LEVEL);
-    ASSERT3P(KeGetCurrentThread(), !=3D, Thread->Thread);
-
-    (VOID) KeWaitForSingleObject(Thread->Thread,
-                                 Executive,
-                                 KernelMode,
-                                 FALSE,
-                                 NULL);
-
-    References =3D InterlockedDecrement(&Thread->References);
-    ASSERT3U(References, =3D=3D, 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 =3D 'ODP',
-    FUNCTION_DEVICE_OBJECT =3D 'ODF'
-} DEVICE_OBJECT_TYPE, *PDEVICE_OBJECT_TYPE;
-
-typedef enum _DEVICE_PNP_STATE {
-    Invalid =3D 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_VERS=
ION,BUILD_NUMBER
-#define VER_PRODUCTVERSION_STR      MAJOR_VERSION_STR "." MINOR_VERSION_ST=
R "." 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=3D"$Windows NT$"
+
+[Version]
+Signature=3D"$Windows NT$"
 Class=3DSCSIAdapter
-ClassGUID=3D{4D36E97B-E325-11CE-BFC1-08002BE10318}
-Provider=3D%Vendor%
+ClassGUID=3D{4D36E97B-E325-11CE-BFC1-08002BE10318}
+Provider=3D%Vendor%
 CatalogFile=3Dxenvbd.cat
 DriverVer=3D@INF_DATE@,@MAJOR_VERSION@.@MINOR_VERSION@.@MICRO_VERSION@.@BU=
ILD_NUMBER@
 DriverPackageDisplayName=3D%DiskDesc%
 PnpLockdown=3D1

-[DestinationDirs]
-DefaultDestDir=3D12
+[DestinationDirs]
+DefaultDestDir=3D12

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

-[Manufacturer]
+[Manufacturer]
 %Vendor%=3DInst,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=3DXenVbd_Copyfiles
 ; TODO: Remove during next PDO version bump
 FeatureScore=3D0xFE
@@ -67,43 +66,23 @@ FeatureScore=3D0xFE
 [XenVbd_Copyfiles]
 xenvbd.sys
 xencrsh.sys
-xendisk.sys
-
-[XenVbd_Inst.HW]
-AddReg=3DXenVbd_AddReg
-
-[XenVbd_AddReg]
-HKR,,"UpperFilters",0x00010000,"xendisk"

-[XenVbd_Inst.Services]
+[XenVbd_Inst.Services]
 AddService=3Dxenvbd,2,XenVbd_Service,
-AddService=3Dxendisk,,XenDisk_Service,

-[XenDisk_Service]
-DisplayName=3D%XenDiskName%
+[XenVbd_Service]
+DisplayName=3D%XenVbdName%
 ServiceType=3D%SERVICE_KERNEL_DRIVER%
 StartType=3D%SERVICE_BOOT_START%
 ErrorControl=3D%SERVICE_ERROR_NORMAL%
-ServiceBinary=3D%12%\xendisk.sys
-LoadOrderGroup=3D"Scsi Miniport"
-AddReg=3DXenDisk_Parameters
-
-[XenDisk_Parameters]
-HKR,"Parameters",,0x00000010
-
-[XenVbd_Service]
-DisplayName=3D%XenVbdName%
-ServiceType=3D%SERVICE_KERNEL_DRIVER%
-StartType=3D%SERVICE_BOOT_START%
-ErrorControl=3D%SERVICE_ERROR_NORMAL%
-ServiceBinary=3D%12%\xenvbd.sys
+ServiceBinary=3D%12%\xenvbd.sys
 LoadOrderGroup=3D"Scsi Miniport"
 AddReg=3DXenVbd_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 =3D "@VENDOR_NAME@"
-DiskDesc =3D "@PRODUCT_NAME@ PV Storage Host Adapter Package"
+DiskDesc =3D "@PRODUCT_NAME@ PV Storage Host Adapter Package"
 XenVbdName=3D "@PRODUCT_NAME@ PV Storage Host Adapter"
-XenDiskName=3D "@PRODUCT_NAME@ PV Storage Filter"
 UnplugKey=3D"SYSTEM\CurrentControlSet\Services\XEN\Unplug"
 ForceUnplugKey=3D"SYSTEM\CurrentControlSet\Services\XEN\ForceUnplug"
 PnpKey=3D"SYSTEM\CurrentControlSet\Control\Pnp"
 PartMgrKey=3D"SYSTEM\CurrentControlSet\Services\PartMgr\Parameters"
 DiskKey=3D"SYSTEM\CurrentControlSet\Services\Disk"

-SERVICE_BOOT_START =3D 0x0
-SERVICE_SYSTEM_START =3D 0x1
-SERVICE_AUTO_START =3D 0x2
-SERVICE_DEMAND_START =3D 0x3
-SERVICE_DISABLED =3D 0x4
-
-SERVICE_KERNEL_DRIVER =3D 0x1
-SERVICE_ERROR_IGNORE =3D 0x0
-SERVICE_ERROR_NORMAL =3D 0x1
-SERVICE_ERROR_SEVERE =3D 0x2
-SERVICE_ERROR_CRITICAL =3D 0x3
+SERVICE_BOOT_START =3D 0x0
+SERVICE_SYSTEM_START =3D 0x1
+SERVICE_AUTO_START =3D 0x2
+SERVICE_DEMAND_START =3D 0x3
+SERVICE_DISABLED =3D 0x4
+
+SERVICE_KERNEL_DRIVER =3D 0x1
+SERVICE_ERROR_IGNORE =3D 0x0
+SERVICE_ERROR_NORMAL =3D 0x1
+SERVICE_ERROR_SEVERE =3D 0x2
+SERVICE_ERROR_CRITICAL =3D 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                =3D 0;
-    Data->DeviceSpecificParameter   =3D FrontendGetReadOnly(Target->Fronte=
nd) ?
+    Data->DeviceSpecificParameter   =3D FrontendGetReadOnly(Target->Fronte=
nd) ?
                                                     MODE_DSP_WRITE_PROTECT=
 : 0;
     Size =3D sizeof(MODE_PARAMETER_HEADER);

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

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

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

-    *(PUSHORT)Data->ModeDataLength =3D _byteswap_ushort((USHORT)ModeDataLe=
ngth +
+    *(PUSHORT)Data->ModeDataLength =3D _byteswap_ushort((USHORT)ModeDataLe=
ngth +
                                                       sizeof(MODE_PARAMETE=
R_HEADER10) - 2);
     *(PUSHORT)Data->BlockDescriptorLength =3D _byteswap_ushort((USHORT)Blo=
ckDescrLength);

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



From win-pv-devel-bounces@lists.xenproject.org Wed Mar 04 11:29:01 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Wed, 04 Mar 2026 11:29:01 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1245308.1544676 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxkPT-0006Mq-KE; Wed, 04 Mar 2026 11:28:59 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1245308.1544676; Wed, 04 Mar 2026 11:28:59 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxkPT-0006Mj-HV; Wed, 04 Mar 2026 11:28:59 +0000
Received: by outflank-mailman (input) for mailman id 1245308;
 Wed, 04 Mar 2026 11:28:58 +0000
Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50]
 helo=se1-gles-flk1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=4oJa=BE=bounce.vates.tech=bounce-md_30504962.69a81774.v1-04625656220342a79533f157667b14a8@srs-se1.protection.inumbo.net>)
 id 1vxkPS-0006MX-4L
 for win-pv-devel@lists.xenproject.org; Wed, 04 Mar 2026 11:28:58 +0000
Received: from mail177-30.suw61.mandrillapp.com
 (mail177-30.suw61.mandrillapp.com [198.2.177.30])
 by se1-gles-flk1.inumbo.com (Halon) with ESMTPS
 id 5324de60-17bd-11f1-9ccf-f158ae23cfc8;
 Wed, 04 Mar 2026 12:28:54 +0100 (CET)
Received: from pmta14.mandrill.prod.suw01.rsglab.com (localhost [127.0.0.1])
 by mail177-30.suw61.mandrillapp.com (Mailchimp) with ESMTP id
 4fQr5w5qJWzP0JvK3
 for <win-pv-devel@lists.xenproject.org>; Wed,  4 Mar 2026 11:28:52 +0000 (GMT)
Received: from [37.26.189.201] by mandrillapp.com id
 04625656220342a79533f157667b14a8; Wed, 04 Mar 2026 11:28:52 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: 5324de60-17bd-11f1-9ccf-f158ae23cfc8
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com;
	s=mte1; t=1772623732; x=1772893732;
	bh=Zxv65rv8oTLmw5Ppmi6JVLPSlUCv0UZ4cJuyDQtwmqs=;
	h=From:Subject:Message-Id:To:Cc:References:In-Reply-To:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=zexjt1S6z6xrb45x8dZP39u/EokVZqBhDVAGHEhCuJ+kFKH6IT+BAdfyYNB/0lLBt
	 qqkKcJweiQBpQpfNJtQtusdgx7isGS0L4EGHp9dK+jx3VtTWFPxAhXaJvThoQaWCC4
	 Yq+dzl2oRUH7fT38abfe9aBSXMZTSNz0T9gTBZJRiOZqdDTmiQD9/vafdkijTF1tMK
	 z1CPnzzVmxaLizj9cs18EwqBxLRzoM0FDgGj+HqtHlL8NcJgbc8qhVVkOMbyucGQBE
	 X+7YFzvC3CywCipXouXuMCgXua15e1tuvixO29OMnbAJaiJykM51LnjlvQXHqln36k
	 oVlse1pCyxHbA==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1;
	t=1772623732; x=1772884232; i=ngoc-tu.dinh@vates.tech;
	bh=Zxv65rv8oTLmw5Ppmi6JVLPSlUCv0UZ4cJuyDQtwmqs=;
	h=From:Subject:Message-Id:To:Cc:References:In-Reply-To:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=efi7U5tYczJxi1yByiq1JymqQVPF3biRPUcucD8aZqqhWf17MlZsWhZKgw+IF9Jdh
	 RfDOJm7deITEOrCDaZsRE8ZtuSqUnd+s14RQQ+M4A7fMO4yuZk+0VINeC+zlynjq5g
	 6p6F6KR+OYmM79Fochd1CbvA6uT8lfIaetX5uu+GmovVrBb2Mg7Mb9yZ287S5gIZiH
	 afh1fWjL5DZdsG8pnxDeVi5y8MsfqU3QCMg4lk8M4KQJbHQmdoFcpV0a/uoemAatWo
	 PH5XAsjCQLowCLbM4S1f4Jru7HDsx73l6KqgKgCnhjsfh/HJfZUVlTWQLCpTbfi+X8
	 swFWfbkLKRt/w==
From: "Tu Dinh" <ngoc-tu.dinh@vates.tech>
Subject: =?utf-8?Q?Re:=20[PATCH=202/4=20v2]=20Refactor=20Features=20and=20DiskInfo?=
X-Bm-Disclaimer: Yes
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1772623730739
Message-Id: <f1a3c2d1-4385-406c-9965-8ca547584efc@vates.tech>
To: "Owen Smith" <owen.smith@citrix.com>, win-pv-devel@lists.xenproject.org
Cc: "Owen Smith" <owen.smith@cloud.com>
References: <20260303093628.1743-1-owen.smith@citrix.com> <20260303093628.1743-2-owen.smith@citrix.com>
In-Reply-To: <20260303093628.1743-2-owen.smith@citrix.com>
X-Native-Encoded: 1
X-Report-Abuse: =?UTF-8?Q?Please=20forward=20a=20copy=20of=20this=20message,=20including=20all=20headers,=20to=20abuse@mandrill.com.=20You=20can=20also=20report=20abuse=20here:=20https://mandrillapp.com/contact/abuse=3Fid=3D30504962.04625656220342a79533f157667b14a8?=
X-Mandrill-User: md_30504962
Feedback-ID: 30504962:30504962.20260304:md
Date: Wed, 04 Mar 2026 11:28:52 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit

On 03/03/2026 10:36, Owen Smith wrote:
> From: Owen Smith <owen.smith@cloud.com>
> 
> Make the XENVBD_FEATURES structure contain ring protocol related
> feature flags and values, including which ring operations the backend
> exposes to the frontend. The backend may fail any operation with
> BLKIF_OP_ENOTSUPP, which instructs the frontend to stop issuing these
> operations, and in response the frontend will disable the associated
> feature flags.
> 
> Make the XENVBD_DISKINFO structure contain the backend storage
> parameters, such as disk size, physical layout and disk specific flags.
> 
> Zeroing the XENVBD_FEATURES structure and re-reading it on connection
> will allow feature flags to be modified when the backend changes.
> 
> Signed-off-by: Owen Smith <owen.smith@cloud.com>

Reviewed-by: Tu Dinh <ngoc-tu.dinh@vates.tech>

> ---
>   src/xenvbd/frontend.c | 203 ++++++++++++++++++------------------------
>   src/xenvbd/frontend.h |  12 +--
>   src/xenvbd/ring.c     |   2 +-
>   src/xenvbd/target.c   |   8 +-
>   4 files changed, 99 insertions(+), 126 deletions(-)
> 
> diff --git a/src/xenvbd/frontend.c b/src/xenvbd/frontend.c
> index 9f157fe..912fc7e 100644
> --- a/src/xenvbd/frontend.c
> +++ b/src/xenvbd/frontend.c
> @@ -184,7 +184,7 @@ FrontendGetDiscard(
>       IN  PXENVBD_FRONTEND    Frontend
>       )
>   {
> -    return Frontend->DiskInfo.Discard;
> +    return Frontend->Features.Discard;
>   }
>   //FRONTEND_GET_PROPERTY(FlushCache, BOOLEAN)
>   BOOLEAN
> @@ -192,7 +192,7 @@ FrontendGetFlushCache(
>       IN  PXENVBD_FRONTEND    Frontend
>       )
>   {
> -    return Frontend->DiskInfo.FlushCache;
> +    return Frontend->Features.FlushCache;
>   }
>   //FRONTEND_GET_PROPERTY(Barrier, BOOLEAN)
>   BOOLEAN
> @@ -200,7 +200,7 @@ FrontendGetBarrier(
>       IN  PXENVBD_FRONTEND    Frontend
>       )
>   {
> -    return Frontend->DiskInfo.Barrier;
> +    return Frontend->Features.Barrier;
>   }
>   FRONTEND_GET_PROPERTY(MaxQueues, ULONG)
>   FRONTEND_GET_PROPERTY(NumQueues, ULONG)
> @@ -240,15 +240,15 @@ FrontendRemoveFeature(
>       switch (BlkifOperation) {
>       case BLKIF_OP_FLUSH_DISKCACHE:
>           Verbose("FLUSH_DISKCACHE\n");
> -        Frontend->DiskInfo.FlushCache = FALSE;
> +        Frontend->Features.FlushCache = FALSE;
>           break;
>       case BLKIF_OP_WRITE_BARRIER:
>           Verbose("WRITE_BARRIER\n");
> -        Frontend->DiskInfo.Barrier = FALSE;
> +        Frontend->Features.Barrier = FALSE;
>           break;
>       case BLKIF_OP_DISCARD:
>           Verbose("DISCARD\n");
> -        Frontend->DiskInfo.Discard = FALSE;
> +        Frontend->Features.Discard = FALSE;
>           break;
>       case BLKIF_OP_INDIRECT:
>           Verbose("INDIRECT\n");
> @@ -824,10 +824,78 @@ __Units(
>       return "GB";
>   }
>   
> -__drv_requiresIRQL(DISPATCH_LEVEL)
> -static VOID
> -__ReadDiskInfo(
> -    __in  PXENVBD_FRONTEND  Frontend
> +static FORCEINLINE VOID
> +FrontendReadFeatures(
> +    IN  PXENVBD_FRONTEND    Frontend
> +    )
> +{
> +    BOOLEAN                 DiscardFeature = FALSE;
> +    BOOLEAN                 DiscardEnable = TRUE;
> +
> +    FrontendReadFeature(Frontend,
> +                        FeatureRemovable,
> +                        &Frontend->Features.Removable);
> +    FrontendReadValue32(Frontend,
> +                        FeatureMaxIndirectSegments,
> +                        TRUE,
> +                        &Frontend->Features.Indirect);
> +    FrontendReadFeature(Frontend,
> +                        FeaturePersistent,
> +                        &Frontend->Features.Persistent);
> +    FrontendReadFeature(Frontend,
> +                        FeatureBarrier,
> +                        &Frontend->Features.Barrier);
> +    FrontendReadFeature(Frontend,
> +                        FeatureFlushCache,
> +                        &Frontend->Features.FlushCache);
> +
> +    FrontendReadFeature(Frontend,
> +                        FeatureDiscard,
> +                        &DiscardFeature);
> +    FrontendReadFeature(Frontend,
> +                        FeatureDiscardEnable,
> +                        &DiscardEnable);
> +    Frontend->Features.Discard = DiscardFeature && DiscardEnable;
> +
> +    FrontendReadFeature(Frontend,
> +                        FeatureDiscardSecure,
> +                        &Frontend->Features.DiscardSecure);
> +    FrontendReadValue32(Frontend,
> +                        FeatureDiscardAlignment,
> +                        TRUE,
> +                        &Frontend->Features.DiscardAlignment);
> +    FrontendReadValue32(Frontend,
> +                        FeatureDiscardGranularity,
> +                        TRUE,
> +                        &Frontend->Features.DiscardGranularity);
> +
> +    Verbose("Target[%d] : Features: %s%s%s%s%s%s\n",
> +            Frontend->TargetId,
> +            Frontend->Features.Persistent ? "PERSISTENT " : "",
> +            Frontend->Features.Indirect > 0 ? "INDIRECT " : "",
> +            Frontend->Features.Removable ? "REMOVABLE " : "",
> +            Frontend->Features.Barrier ? "BARRIER " : "",
> +            Frontend->Features.FlushCache ? "FLUSH " : "",
> +            Frontend->Features.Discard ? "DISCARD " : "");
> +
> +    if (Frontend->Features.Indirect) {
> +        Verbose("Target[%d] : INDIRECT %x\n",
> +                    Frontend->TargetId,
> +                    Frontend->Features.Indirect);
> +    }
> +
> +    if (Frontend->Features.Discard) {
> +        Verbose("Target[%d] : DISCARD %s%x/%x\n",
> +                    Frontend->TargetId,
> +                    Frontend->Features.DiscardSecure ? "SECURE " : "",
> +                    Frontend->Features.DiscardAlignment,
> +                    Frontend->Features.DiscardGranularity);
> +    }
> +}
> +
> +static FORCEINLINE VOID
> +FrontendReadDiskInfo(
> +    IN  PXENVBD_FRONTEND    Frontend
>       )
>   {
>       BOOLEAN                 Changed;
> @@ -873,92 +941,6 @@ __ReadDiskInfo(
>             Frontend->DiskInfo.DiskInfo);
>   }
>   
> -static FORCEINLINE VOID
> -FrontendReadFeatures(
> -    IN  PXENVBD_FRONTEND    Frontend
> -    )
> -{
> -    BOOLEAN                 Changed;
> -
> -    Changed = FrontendReadFeature(Frontend,
> -                                  FeatureRemovable,
> -                                  &Frontend->Features.Removable);
> -    Changed |= FrontendReadValue32(Frontend,
> -                                   FeatureMaxIndirectSegments,
> -                                   TRUE,
> -                                   &Frontend->Features.Indirect);
> -    Changed |= FrontendReadFeature(Frontend,
> -                                   FeaturePersistent,
> -                                   &Frontend->Features.Persistent);
> -
> -    if (!Changed)
> -        return;
> -
> -    Verbose("Target[%d] : Features: %s%s%s\n",
> -            Frontend->TargetId,
> -            Frontend->Features.Persistent ? "PERSISTENT " : "",
> -            Frontend->Features.Indirect ? "INDIRECT " : "",
> -            Frontend->Features.Removable ? "REMOVABLE" : "");
> -
> -    if (Frontend->Features.Indirect) {
> -        Verbose("Target[%d] : INDIRECT %x\n",
> -                    Frontend->TargetId,
> -                    Frontend->Features.Indirect);
> -    }
> -}
> -
> -static FORCEINLINE VOID
> -FrontendReadDiskInfo(
> -    IN  PXENVBD_FRONTEND    Frontend
> -    )
> -{
> -    BOOLEAN                 DiscardFeature = FALSE;
> -    BOOLEAN                 DiscardEnable = TRUE;
> -
> -    FrontendReadFeature(Frontend,
> -                        FeatureBarrier,
> -                        &Frontend->DiskInfo.Barrier);
> -    FrontendReadFeature(Frontend,
> -                        FeatureFlushCache,
> -                        &Frontend->DiskInfo.FlushCache);
> -
> -    // discard related
> -    FrontendReadFeature(Frontend,
> -                        FeatureDiscard,
> -                        &DiscardFeature);
> -    FrontendReadFeature(Frontend,
> -                        FeatureDiscardEnable,
> -                        &DiscardEnable);
> -
> -    Frontend->DiskInfo.Discard = DiscardFeature && DiscardEnable;
> -
> -    FrontendReadFeature(Frontend,
> -                        FeatureDiscardSecure,
> -                        &Frontend->DiskInfo.DiscardSecure);
> -    FrontendReadValue32(Frontend,
> -                        FeatureDiscardAlignment,
> -                        TRUE,
> -                        &Frontend->DiskInfo.DiscardAlignment);
> -    FrontendReadValue32(Frontend,
> -                        FeatureDiscardGranularity,
> -                        TRUE,
> -                        &Frontend->DiskInfo.DiscardGranularity);
> -
> -    Verbose("Target[%d] : Features: %s%s%s\n",
> -                Frontend->TargetId,
> -                Frontend->DiskInfo.Barrier ? "BARRIER " : "",
> -                Frontend->DiskInfo.FlushCache ?  "FLUSH " : "",
> -                Frontend->DiskInfo.Discard ? "DISCARD " : "");
> -
> -    if (Frontend->DiskInfo.Discard) {
> -        Verbose("Target[%d] : DISCARD %s%x/%x\n",
> -                    Frontend->TargetId,
> -                    Frontend->DiskInfo.DiscardSecure ? "SECURE " : "",
> -                    Frontend->DiskInfo.DiscardAlignment,
> -                    Frontend->DiskInfo.DiscardGranularity);
> -    }
> -}
> -
>   static FORCEINLINE VOID
>   FrontendReadInquiryOverrides(
>       IN  PXENVBD_FRONTEND    Frontend
> @@ -1142,8 +1124,6 @@ FrontendPrepare(
>               Frontend->BackendDomain,
>               Frontend->BackendPath);
>   
> -    FrontendReadFeatures(Frontend);
> -
>       return STATUS_SUCCESS;
>   
>   fail7:
> @@ -1314,7 +1294,6 @@ abort:
>           goto fail6;
>   
>       // read disk info
> -    __ReadDiskInfo(Frontend);
>       FrontendReadDiskInfo(Frontend);
>   
>       // read inquiry data
> @@ -1332,6 +1311,7 @@ abort:
>   
>   fail7:
>       Error("Fail7\n");
> +    RtlZeroMemory(&Frontend->Features, sizeof(XENVBD_FEATURES));
>   fail6:
>       Error("Fail6\n");
>   fail5:
> @@ -1370,14 +1350,7 @@ FrontendDisconnect(
>       Frontend->Page83.Data = NULL;
>       Frontend->Page83.Size = 0;
>   
> -    // clear some disk info values, so they can be re-read on connect
> -    // allows migration to a backend with different supported features
> -    Frontend->DiskInfo.Barrier = FALSE;
> -    Frontend->DiskInfo.FlushCache = FALSE;
> -    Frontend->DiskInfo.Discard = FALSE;
> -    Frontend->DiskInfo.DiscardSecure = FALSE;
> -    Frontend->DiskInfo.DiscardAlignment = 0;
> -    Frontend->DiskInfo.DiscardGranularity = 0;
> +    RtlZeroMemory(&Frontend->Features, sizeof(XENVBD_FEATURES));
>   }
>   __drv_requiresIRQL(DISPATCH_LEVEL)
>   static FORCEINLINE VOID
> @@ -1649,9 +1622,9 @@ FrontendDebugCallback(
>                    Frontend->Features.Persistent ? "PERSISTENT " : "",
>                    Frontend->Features.Indirect > 0 ? "INDIRECT " : "",
>                    Frontend->Features.Removable ? "REMOVABLE " : "",
> -                 Frontend->DiskInfo.Barrier ? "BARRIER " : "",
> -                 Frontend->DiskInfo.FlushCache ? "FLUSH " : "",
> -                 Frontend->DiskInfo.Discard ? "DISCARD " : "");
> +                 Frontend->Features.Barrier ? "BARRIER " : "",
> +                 Frontend->Features.FlushCache ? "FLUSH " : "",
> +                 Frontend->Features.Discard ? "DISCARD " : "");
>   
>       if (Frontend->Features.Indirect > 0) {
>           XENBUS_DEBUG(Printf,
> @@ -1659,13 +1632,13 @@ FrontendDebugCallback(
>                        "INDIRECT %x\n",
>                        Frontend->Features.Indirect);
>       }
> -    if (Frontend->DiskInfo.Discard) {
> +    if (Frontend->Features.Discard) {
>           XENBUS_DEBUG(Printf,
>                        &Frontend->DebugInterface,
>                        "DISCARD %s%x/%x\n",
> -                     Frontend->DiskInfo.DiscardSecure ? "SECURE " : "",
> -                     Frontend->DiskInfo.DiscardAlignment,
> -                     Frontend->DiskInfo.DiscardGranularity);
> +                     Frontend->Features.DiscardSecure ? "SECURE " : "",
> +                     Frontend->Features.DiscardAlignment,
> +                     Frontend->Features.DiscardGranularity);
>       }
>   
>       XENBUS_DEBUG(Printf,
> @@ -1834,7 +1807,7 @@ FrontendBackend(
>           KeAcquireSpinLock(&Frontend->StateLock, &Irql);
>           // Only attempt this if Active, Active is set/cleared on D3->D0/D0->D3
>           if (Frontend->Active) {
> -            __ReadDiskInfo(Frontend);
> +            FrontendReadDiskInfo(Frontend);
>               __CheckBackendForEject(Frontend);
>           }
>           KeReleaseSpinLock(&Frontend->StateLock, Irql);
> diff --git a/src/xenvbd/frontend.h b/src/xenvbd/frontend.h
> index a83c1f0..34f91b4 100644
> --- a/src/xenvbd/frontend.h
> +++ b/src/xenvbd/frontend.h
> @@ -56,6 +56,12 @@ typedef struct _XENVBD_FEATURES {
>       ULONG                       Indirect;
>       BOOLEAN                     Persistent;
>       BOOLEAN                     Removable;
> +    BOOLEAN                     Barrier;
> +    BOOLEAN                     FlushCache;
> +    BOOLEAN                     Discard;
> +    BOOLEAN                     DiscardSecure;
> +    ULONG                       DiscardAlignment;
> +    ULONG                       DiscardGranularity;
>   } XENVBD_FEATURES, *PXENVBD_FEATURES;
>   
>   typedef struct _XENVBD_DISKINFO {
> @@ -63,12 +69,6 @@ typedef struct _XENVBD_DISKINFO {
>       ULONG                       SectorSize;
>       ULONG                       PhysSectorSize;
>       ULONG                       DiskInfo;
> -    BOOLEAN                     Barrier;
> -    BOOLEAN                     FlushCache;
> -    BOOLEAN                     Discard;
> -    BOOLEAN                     DiscardSecure;
> -    ULONG                       DiscardAlignment;
> -    ULONG                       DiscardGranularity;
>   } XENVBD_DISKINFO, *PXENVBD_DISKINFO;
>   
>   typedef struct _XENVBD_FRONTEND XENVBD_FRONTEND, *PXENVBD_FRONTEND;
> diff --git a/src/xenvbd/ring.c b/src/xenvbd/ring.c
> index 86a71ac..50f8d58 100644
> --- a/src/xenvbd/ring.c
> +++ b/src/xenvbd/ring.c
> @@ -914,7 +914,7 @@ BlkifRingPrepareSyncCache(
>       InitializeListHead(&List);
>       Srb->SrbStatus = SRB_STATUS_PENDING;
>   
> -    if (FrontendGetDiskInfo(Frontend)->FlushCache)
> +    if (FrontendGetFeatures(Frontend)->FlushCache)
>           Operation = BLKIF_OP_FLUSH_DISKCACHE;
>       else
>           Operation = BLKIF_OP_WRITE_BARRIER;
> diff --git a/src/xenvbd/target.c b/src/xenvbd/target.c
> index f07ee8b..a07fc45 100644
> --- a/src/xenvbd/target.c
> +++ b/src/xenvbd/target.c
> @@ -806,7 +806,7 @@ TargetInquiryB0(
>       IN  PSCSI_REQUEST_BLOCK Srb
>       )
>   {
> -    PXENVBD_DISKINFO        DiskInfo = FrontendGetDiskInfo(Target->Frontend);
> +    PXENVBD_FEATURES        Features = FrontendGetFeatures(Target->Frontend);
>       PVPD_BLOCK_LIMITS_PAGE  Data = Srb->DataBuffer;
>       ULONG                   Length = Srb->DataTransferLength;
>   
> @@ -822,10 +822,10 @@ TargetInquiryB0(
>       Data->PageCode = 0xB0;
>       Data->PageLength[1] = 0x3C; // as per spec
>   
> -    *(PULONG)Data->OptimalUnmapGranularity = _byteswap_ulong(DiskInfo->DiscardGranularity);
> -    *(PULONG)Data->UnmapGranularityAlignment = _byteswap_ulong(DiskInfo->DiscardAlignment);
> +    *(PULONG)Data->OptimalUnmapGranularity = _byteswap_ulong(Features->DiscardGranularity);
> +    *(PULONG)Data->UnmapGranularityAlignment = _byteswap_ulong(Features->DiscardAlignment);
>       // alignment is only valid if a granularity has been set
> -    Data->UGAValid = (DiskInfo->DiscardGranularity != 0) ? 1 : 0;
> +    Data->UGAValid = (Features->DiscardGranularity != 0) ? 1 : 0;
>   
>       Srb->DataTransferLength = sizeof(VPD_BLOCK_LIMITS_PAGE);
>       Srb->SrbStatus = SRB_STATUS_SUCCESS;



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Wed Mar 04 11:29:05 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Wed, 04 Mar 2026 11:29:05 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1245309.1544680 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxkPZ-0006Ou-Lr; Wed, 04 Mar 2026 11:29:05 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1245309.1544680; Wed, 04 Mar 2026 11:29:05 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxkPZ-0006On-Iv; Wed, 04 Mar 2026 11:29:05 +0000
Received: by outflank-mailman (input) for mailman id 1245309;
 Wed, 04 Mar 2026 11:29:04 +0000
Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50]
 helo=se1-gles-flk1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=zBEF=BE=bounce.vates.tech=bounce-md_30504962.69a8177d.v1-9c81fb1b737f40e3ab86df5dce3be7cd@srs-se1.protection.inumbo.net>)
 id 1vxkPY-0006MX-Gl
 for win-pv-devel@lists.xenproject.org; Wed, 04 Mar 2026 11:29:04 +0000
Received: from mail177-30.suw61.mandrillapp.com
 (mail177-30.suw61.mandrillapp.com [198.2.177.30])
 by se1-gles-flk1.inumbo.com (Halon) with ESMTPS
 id 58341f92-17bd-11f1-9ccf-f158ae23cfc8;
 Wed, 04 Mar 2026 12:29:02 +0100 (CET)
Received: from pmta14.mandrill.prod.suw01.rsglab.com (localhost [127.0.0.1])
 by mail177-30.suw61.mandrillapp.com (Mailchimp) with ESMTP id
 4fQr6540TLzP0MKvc
 for <win-pv-devel@lists.xenproject.org>; Wed,  4 Mar 2026 11:29:01 +0000 (GMT)
Received: from [37.26.189.201] by mandrillapp.com id
 9c81fb1b737f40e3ab86df5dce3be7cd; Wed, 04 Mar 2026 11:29:01 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: 58341f92-17bd-11f1-9ccf-f158ae23cfc8
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com;
	s=mte1; t=1772623741; x=1772893741;
	bh=GIiGK68VhjCmEro0W5JHUOG7DEJlqrXtOAaIIwtlTMM=;
	h=From:Subject:Message-Id:To:References:In-Reply-To:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=yKOSUHcMOimqsKRBSzd4T6D8pkx1zRicnUMnzY319gYHtsyxJhSW5P3lA7Ga4OFTz
	 hEQLm7A6sIpy4aMV9+WTUIZ0i3S0xx2b/4gXJYVHSwdqCHxtMSvrbIQUx4GTv3o67M
	 9GdDXFA9JkouAerR2vHBjN4TiUW/mod3+dSkrfGpSVg+n2y29cAfvuDdFJ5wtJVjjZ
	 IMwe8rbz6UsIKLIWSKRp7FhPyrcJV2ZCzpALKTMFJkSZACPvZ1BLfPJnOIrUjUjOhx
	 MK50VW044/sz4JFiMupGZSrqRXyEtr9JFc+ZCssZwyhn0ozEKSrTHeMSHrlEqUZ7pe
	 CuQGp3UGYtG1Q==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1;
	t=1772623741; x=1772884241; i=ngoc-tu.dinh@vates.tech;
	bh=GIiGK68VhjCmEro0W5JHUOG7DEJlqrXtOAaIIwtlTMM=;
	h=From:Subject:Message-Id:To:References:In-Reply-To:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=gLQlkl29wVOsV5GjGZwXUn/laKF5wBpzzNrfXzTfYjQ7ISZFIi0Yp5mmSuF1FhH5j
	 p6YQ3uCEsZVFhe59gq48oyCxBa4Rao4jaFAXLOibhss2vN5+RivPC+HXfG6dBot43B
	 08rTQOV8gXiJuPIyqanPYhsSbz7Wj/86hKc9HJsCh03CiVqrnWsB9j9tYZtx1pb97R
	 s+SlDyvAH0g638jfKvho0IvRn5t4uoiYcfuVVsAcuuPN/ekrddmFm2qs2q7o30CI0o
	 fAIBNgz8kWJANrQf5hnUKY4lrqkwEFYwt0v0a8q/ti/Q6HfdboGcEUFjYkIjaNuOqP
	 ZJGfvpUB6+OoQ==
From: "Tu Dinh" <ngoc-tu.dinh@vates.tech>
Subject: =?utf-8?Q?Re:=20[PATCH=204/4=20v2]=20Use=20NT=20Safe=20String=20printf=20in=20log.c?=
X-Bm-Disclaimer: Yes
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1772623740754
Message-Id: <3618d887-2aba-4e36-819b-b653fcc7c504@vates.tech>
To: "Owen Smith" <owen.smith@citrix.com>, win-pv-devel@lists.xenproject.org
References: <20260303093628.1743-1-owen.smith@citrix.com> <20260303093628.1743-4-owen.smith@citrix.com>
In-Reply-To: <20260303093628.1743-4-owen.smith@citrix.com>
X-Native-Encoded: 1
X-Report-Abuse: =?UTF-8?Q?Please=20forward=20a=20copy=20of=20this=20message,=20including=20all=20headers,=20to=20abuse@mandrill.com.=20You=20can=20also=20report=20abuse=20here:=20https://mandrillapp.com/contact/abuse=3Fid=3D30504962.9c81fb1b737f40e3ab86df5dce3be7cd?=
X-Mandrill-User: md_30504962
Feedback-ID: 30504962:30504962.20260304:md
Date: Wed, 04 Mar 2026 11:29:01 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit

On 03/03/2026 10:36, Owen Smith wrote:
> CodeQL generates a warning about using sprintf(). Switch to using
> RtlStringCbPrintf() when formatting debug messages.
> Avoid calling vDbgPrintExWithPrefix when RtlStringCbPrintf reports
> an error.
> 
> Signed-off-by: Owen Smith <owen.smith@citrix.com>

Acked-by: Tu Dinh <ngoc-tu.dinh@vates.tech>

> ---
>   src/xencrsh/log.c | 15 ++++++++++++---
>   1 file changed, 12 insertions(+), 3 deletions(-)
> 
> diff --git a/src/xencrsh/log.c b/src/xencrsh/log.c
> index a1e8a5a..5d3fcc0 100644
> --- a/src/xencrsh/log.c
> +++ b/src/xencrsh/log.c
> @@ -34,6 +34,7 @@
>   #include "driver.h"
>   #include "assert.h"
>   #include <stdio.h>
> +#include <ntstrsafe.h>
>   
>   static PVOID Port12 = ((PVOID)(ULONG_PTR)0x12);
>   
> @@ -252,10 +253,18 @@ LogVDebug(
>       IN  va_list     Args
>       )
>   {
> -    static CHAR Buffer[256];
> +    static CHAR     Buffer[256];
> +    NTSTATUS        status;
> +
> +    status = RtlStringCbPrintfA(Buffer,
> +                                sizeof(Buffer),
> +                                "%s|%s|%s:",
> +                                Module,
> +                                __Mode(),
> +                                Function);
> +    if (!NT_SUCCESS(status))
> +        return; // Buffer is not safe to use
>   
> -#pragma warning(suppress : 28719) // SDV
> -    sprintf(Buffer, "%s|%s|%s:", Module, __Mode(), Function);
>       Buffer[255] = 0;
>   
>       vDbgPrintExWithPrefix(Buffer,



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Wed Mar 04 11:32:21 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Wed, 04 Mar 2026 11:32:21 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1245313.1544684 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxkSi-0007aE-UF; Wed, 04 Mar 2026 11:32:20 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1245313.1544684; Wed, 04 Mar 2026 11:32:20 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxkSi-0007a6-RI; Wed, 04 Mar 2026 11:32:20 +0000
Received: by outflank-mailman (input) for mailman id 1245313;
 Wed, 04 Mar 2026 11:32:19 +0000
Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254]
 helo=se1-gles-sth1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=Q+vW=BE=bounce.vates.tech=bounce-md_30504962.69a81840.v1-a148b82ee87c473fae4b96204bedc508@srs-se1.protection.inumbo.net>)
 id 1vxkSh-0007Zy-Sv
 for win-pv-devel@lists.xenproject.org; Wed, 04 Mar 2026 11:32:19 +0000
Received: from mail178-23.suw51.mandrillapp.com
 (mail178-23.suw51.mandrillapp.com [198.2.178.23])
 by se1-gles-sth1.inumbo.com (Halon) with ESMTPS
 id cc38dead-17bd-11f1-b164-2bf370ae4941;
 Wed, 04 Mar 2026 12:32:18 +0100 (CET)
Received: from pmta13.mandrill.prod.suw01.rsglab.com (localhost [127.0.0.1])
 by mail178-23.suw51.mandrillapp.com (Mailchimp) with ESMTP id
 4fQr9r4LZwz35hd8M
 for <win-pv-devel@lists.xenproject.org>; Wed,  4 Mar 2026 11:32:16 +0000 (GMT)
Received: from [37.26.189.201] by mandrillapp.com id
 a148b82ee87c473fae4b96204bedc508; Wed, 04 Mar 2026 11:32:16 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: cc38dead-17bd-11f1-b164-2bf370ae4941
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com;
	s=mte1; t=1772623936; x=1772893936;
	bh=TKqRwzfTd/4Gfzp3IPIrEQaLJsQROWcBRPMxf27zUyw=;
	h=From:Subject:Message-Id:To:References:In-Reply-To:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=WPgGGh1Lw5PlEfHAro9oHocWRDeKZ7+5OISV4NeN/UJ4zfpX40Kt0VX7lnTnCcVnX
	 qT8Qp9+WjPFd8nHXottEypfqwTCnweTOGKCf4YCeXDwPh9cEDQm/+dTyMdHq/JtDvg
	 TufBSUPeNmc9s8lQX+2/AHHLm/l1A6M/beH6slKDQhT/9vqaQ7olq/hMDG9nqvWT7q
	 CwCh830ByZCovxRBs3iEgEHx34UtHsaMYu7GeyQ4pz0pCJ3e3qGdAAslumxIJ/+NcX
	 GPwnCOV6iVYsRWzQk5SE0nOKxvw6jXlS230/wsPnIxZH67m4k+15aZS/50SbcvBM7P
	 3ezhfqUBDYr+g==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1;
	t=1772623936; x=1772884436; i=ngoc-tu.dinh@vates.tech;
	bh=TKqRwzfTd/4Gfzp3IPIrEQaLJsQROWcBRPMxf27zUyw=;
	h=From:Subject:Message-Id:To:References:In-Reply-To:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=zToy90a7fCZ4TppmLJRL9jpgIrcsh6nwYIuSEjxVSIbag6CUjnmkBL1Idzy3P7ZlL
	 K79ktZ7x+wo6obKgCMYOUkfxjGXVenekcdX1EykKwEwdIyAtfkrPYyJgCR4ILQMbCy
	 xthJ4kFdx3KuewfDui2P/hs/8U4sPwU3X42rt6sKSsrSHc16C+z9kUcYMWRcoREUis
	 R0vs0GQrDAkn+i8NqKXL4opaNx40kdLd4ht2RbB6U42xG8QyxVDLH3rxKLabntvxcr
	 G54rBwPxBp6f5SRQ/AH7nqyTwXB2IN0lg7b/5VbpnsuxZuolHB4ekKtNQP/Ik2fDXY
	 DVC8vZ//jhJYg==
From: "Tu Dinh" <ngoc-tu.dinh@vates.tech>
Subject: =?utf-8?Q?Re:=20[RFC=20PATCH=206/6]=20Remove=20XenDisk?=
X-Bm-Disclaimer: Yes
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1772623935797
Message-Id: <320a12fa-fd91-44d4-940a-ad69ab7ffe25@vates.tech>
To: "Owen Smith" <owen.smith@citrix.com>, win-pv-devel@lists.xenproject.org
References: <20260226105922.1916-1-ngoc-tu.dinh@vates.tech> <20260226105922.1916-7-ngoc-tu.dinh@vates.tech> <SA6PR03MB7760D5FA973CC19465CCAE00FE7CA@SA6PR03MB7760.namprd03.prod.outlook.com>
In-Reply-To: <SA6PR03MB7760D5FA973CC19465CCAE00FE7CA@SA6PR03MB7760.namprd03.prod.outlook.com>
X-Native-Encoded: 1
X-Report-Abuse: =?UTF-8?Q?Please=20forward=20a=20copy=20of=20this=20message,=20including=20all=20headers,=20to=20abuse@mandrill.com.=20You=20can=20also=20report=20abuse=20here:=20https://mandrillapp.com/contact/abuse=3Fid=3D30504962.a148b82ee87c473fae4b96204bedc508?=
X-Mandrill-User: md_30504962
Feedback-ID: 30504962:30504962.20260304:md
Date: Wed, 04 Mar 2026 11:32:16 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit

Hi,

On 04/03/2026 09:32, Owen Smith wrote:
> 
> 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

Would you prefer that I rebase this patch on top of your patch "XenDisk: 
Report Discard support by issuing an Inquiry" or drop that altogether in 
favor of this patch?

> 
> ________________________________________
> From: Tu Dinh <ngoc-tu.dinh@vates.tech>
> Sent: 26 February 2026 10:59 AM
> To: win-pv-devel@lists.xenproject.org
> 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@vates.tech>
> ---
>   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
> 


--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Wed Mar 04 11:47:22 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Wed, 04 Mar 2026 11:47:22 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1245331.1544698 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxkhG-0001Of-BD; Wed, 04 Mar 2026 11:47:22 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1245331.1544698; Wed, 04 Mar 2026 11:47:22 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxkhG-0001OX-8Q; Wed, 04 Mar 2026 11:47:22 +0000
Received: by outflank-mailman (input) for mailman id 1245331;
 Wed, 04 Mar 2026 11:47:20 +0000
Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50]
 helo=se1-gles-flk1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=y3Ja=BE=bounce.vates.tech=bounce-md_30504962.69a81bc4.v1-04997e0cb8f94810ab9835dec39ac180@srs-se1.protection.inumbo.net>)
 id 1vxkhE-0001NV-CQ
 for win-pv-devel@lists.xenproject.org; Wed, 04 Mar 2026 11:47:20 +0000
Received: from mail178-23.suw51.mandrillapp.com
 (mail178-23.suw51.mandrillapp.com [198.2.178.23])
 by se1-gles-flk1.inumbo.com (Halon) with ESMTPS
 id e4f7519e-17bf-11f1-9ccf-f158ae23cfc8;
 Wed, 04 Mar 2026 12:47:18 +0100 (CET)
Received: from pmta13.mandrill.prod.suw01.rsglab.com (localhost [127.0.0.1])
 by mail178-23.suw51.mandrillapp.com (Mailchimp) with ESMTP id
 4fQrW83vm0z35hfJJ
 for <win-pv-devel@lists.xenproject.org>; Wed,  4 Mar 2026 11:47:16 +0000 (GMT)
Received: from [37.26.189.201] by mandrillapp.com id
 04997e0cb8f94810ab9835dec39ac180; Wed, 04 Mar 2026 11:47:16 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: e4f7519e-17bf-11f1-9ccf-f158ae23cfc8
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com;
	s=mte1; t=1772624836; x=1772894836;
	bh=Uvkej/u82UW1SUvjes+2nVXLI2O83vmpman+nOEj5ys=;
	h=From:Subject:Message-Id:To:References:In-Reply-To:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=gC2nybL8X7pNNA0a1357Q1rvBXtqBwLeFlgvB+3Vj2KL76DiOrxcRsGKo3ymNeGC1
	 H/Bw2bcYP+nmtGIDtWK4S/6NeuBg/GGOjDDEN4NRAb8vMpRsGzr6dwdnXzqd4/wdgp
	 /hUMyuzg1YVXse4H4y90pft+mdCXUJgzxIitlV8VgleJNt6GxQvNnC0yDRyqrFfxJl
	 qa0f1v5mrxrP0sravHznQ2xsD5l1B2XNzVdo+HdtHC+1m3kYAKlZmudRfTxP51kSsX
	 RjVoKjbXvboRl/h3pwvERAgbRnzSONhP6MJVbuJmBOpR50KYUMptdooJr/aONpJQJU
	 pgMAyXwsGbvBg==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1;
	t=1772624836; x=1772885336; i=ngoc-tu.dinh@vates.tech;
	bh=Uvkej/u82UW1SUvjes+2nVXLI2O83vmpman+nOEj5ys=;
	h=From:Subject:Message-Id:To:References:In-Reply-To:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=sI4Y5UKIBy/e4k4e9sRguIEWJr2JP0L9SM1GbGjyundT1xRo3gGAluaeM4hUE0fRu
	 Dm6CwYVQiEgcylrOB6ucCkVm98Mcy7eJ4Xa11oVFkAlVrB4fF0fd+zqtqjd03XJ1LI
	 FkHPXiK535aHWlGuQsa3eEmdvVe/xnX2OBWPbrkaEBiYmBsQI97VKZY+kGW0k1jRDg
	 KluxAkmVPwCSS1dbogNyc59sEx+l+epeGNX1TELA5v+wfQ15rTyg7fGIQlCaAKeMTb
	 P66iLVPncp9N5/82U//mKMnCmyd+WXmG1L4GY0K8Rg3VRKyo6yX6rmL5qLIVpjjurU
	 T/Xg65rTXmo7A==
From: "Tu Dinh" <ngoc-tu.dinh@vates.tech>
Subject: =?utf-8?Q?Re:=20[PATCH=203/4=20v2]=20Consolidate=20macro'ed=20access=20to=20properties?=
X-Bm-Disclaimer: Yes
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1772624835365
Message-Id: <529da80a-e9c4-4865-b550-4ef7b7eb36d7@vates.tech>
To: "Owen Smith" <owen.smith@citrix.com>, win-pv-devel@lists.xenproject.org
References: <20260303093628.1743-1-owen.smith@citrix.com> <20260303093628.1743-3-owen.smith@citrix.com>
In-Reply-To: <20260303093628.1743-3-owen.smith@citrix.com>
X-Native-Encoded: 1
X-Report-Abuse: =?UTF-8?Q?Please=20forward=20a=20copy=20of=20this=20message,=20including=20all=20headers,=20to=20abuse@mandrill.com.=20You=20can=20also=20report=20abuse=20here:=20https://mandrillapp.com/contact/abuse=3Fid=3D30504962.04997e0cb8f94810ab9835dec39ac180?=
X-Mandrill-User: md_30504962
Feedback-ID: 30504962:30504962.20260304:md
Date: Wed, 04 Mar 2026 11:47:16 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit

On 03/03/2026 10:36, Owen Smith wrote:
> Replace specific accessors for members of the XENVBD_CAPS,
> XENVBD_FEATURES and XENVBD_DISKINFO structures, with an
> accessor for the structure, and direct accesses for the structure
> members.
> Remove all manually implemented FrontendGet* accessors, using a
> new macro for returning a pointer to a member.
> 
> Signed-off-by: Owen Smith <owen.smith@citrix.com>

Reviewed-by: Tu Dinh <ngoc-tu.dinh@vates.tech>

> ---
>   src/xenvbd/frontend.c | 85 +++++++++++--------------------------------
>   src/xenvbd/frontend.h |  9 +----
>   src/xenvbd/target.c   | 29 +++++++++------
>   3 files changed, 40 insertions(+), 83 deletions(-)
> 
> diff --git a/src/xenvbd/frontend.c b/src/xenvbd/frontend.c
> index 912fc7e..ef60f9c 100644
> --- a/src/xenvbd/frontend.c
> +++ b/src/xenvbd/frontend.c
> @@ -130,6 +130,23 @@ FrontendGet ## _name ## (                       \
>       return __FrontendGet ## _name ## (Frontend);\
>   }
>   
> +
> +#define FRONTEND_GET_PROPERTY_PTR(_name, _type) \
> +static FORCEINLINE _type                        \
> +__FrontendGet ## _name ## (                     \
> +    IN  PXENVBD_FRONTEND    Frontend            \
> +    )                                           \
> +{                                               \
> +    return &Frontend-> ## _name ## ;            \
> +}                                               \
> +_type                                           \
> +FrontendGet ## _name ## (                       \
> +    IN  PXENVBD_FRONTEND    Frontend            \
> +    )                                           \
> +{                                               \
> +    return __FrontendGet ## _name ## (Frontend);\
> +}
> +
>   FRONTEND_GET_PROPERTY(Target, PXENVBD_TARGET)
>   FRONTEND_GET_PROPERTY(Ring, PXENVBD_RING)
>   FRONTEND_GET_PROPERTY(Granter, PXENVBD_GRANTER)
> @@ -138,74 +155,14 @@ FRONTEND_GET_PROPERTY(DeviceId, ULONG)
>   FRONTEND_GET_PROPERTY(BackendDomain, ULONG)
>   FRONTEND_GET_PROPERTY(BackendPath, PCHAR)
>   FRONTEND_GET_PROPERTY(FrontendPath, PCHAR)
> -//FRONTEND_GET_PROPERTY(Caps, PXENVBD_CAPS)
> -PXENVBD_CAPS
> -FrontendGetCaps(
> -    IN  PXENVBD_FRONTEND    Frontend
> -    )
> -{
> -    return &Frontend->Caps;
> -}
> -//FRONTEND_GET_PROPERTY(Features, PXENVBD_FEATURES)
> -PXENVBD_FEATURES
> -FrontendGetFeatures(
> -    IN  PXENVBD_FRONTEND    Frontend
> -    )
> -{
> -    return &Frontend->Features;
> -}
> -//FRONTEND_GET_PROPERTY(DiskInfo, PXENVBD_DISKINFO)
> -PXENVBD_DISKINFO
> -FrontendGetDiskInfo(
> -    IN  PXENVBD_FRONTEND    Frontend
> -    )
> -{
> -    return &Frontend->DiskInfo;
> -}
> -//FRONTEND_GET_PROPERTY(Connected, BOOLEAN)
> -BOOLEAN
> -FrontendGetConnected(
> -    IN  PXENVBD_FRONTEND    Frontend
> -    )
> -{
> -    return Frontend->Caps.Connected;
> -}
> -//FRONTEND_GET_PROPERTY(ReadOnly, BOOLEAN)
> -BOOLEAN
> -FrontendGetReadOnly(
> -    IN  PXENVBD_FRONTEND    Frontend
> -    )
> -{
> -    return !!(Frontend->DiskInfo.DiskInfo & VDISK_READONLY);
> -}
> -//FRONTEND_GET_PROPERTY(Discard, BOOLEAN)
> -BOOLEAN
> -FrontendGetDiscard(
> -    IN  PXENVBD_FRONTEND    Frontend
> -    )
> -{
> -    return Frontend->Features.Discard;
> -}
> -//FRONTEND_GET_PROPERTY(FlushCache, BOOLEAN)
> -BOOLEAN
> -FrontendGetFlushCache(
> -    IN  PXENVBD_FRONTEND    Frontend
> -    )
> -{
> -    return Frontend->Features.FlushCache;
> -}
> -//FRONTEND_GET_PROPERTY(Barrier, BOOLEAN)
> -BOOLEAN
> -FrontendGetBarrier(
> -    IN  PXENVBD_FRONTEND    Frontend
> -    )
> -{
> -    return Frontend->Features.Barrier;
> -}
>   FRONTEND_GET_PROPERTY(MaxQueues, ULONG)
>   FRONTEND_GET_PROPERTY(NumQueues, ULONG)
> +FRONTEND_GET_PROPERTY_PTR(Caps, PXENVBD_CAPS)
> +FRONTEND_GET_PROPERTY_PTR(Features, PXENVBD_FEATURES)
> +FRONTEND_GET_PROPERTY_PTR(DiskInfo, PXENVBD_DISKINFO)
>   
>   #undef FRONTEND_GET_PROPERTY
> +#undef FRONTEND_GET_PROPERTY_PTR
>   
>   //=============================================================================
>   #define FRONTEND_POOL_TAG            'tnFX'
> diff --git a/src/xenvbd/frontend.h b/src/xenvbd/frontend.h
> index 34f91b4..dc7b55f 100644
> --- a/src/xenvbd/frontend.h
> +++ b/src/xenvbd/frontend.h
> @@ -159,16 +159,11 @@ FRONTEND_GET_PROPERTY(DeviceId, ULONG)
>   FRONTEND_GET_PROPERTY(BackendDomain, ULONG)
>   FRONTEND_GET_PROPERTY(BackendPath, PCHAR)
>   FRONTEND_GET_PROPERTY(FrontendPath, PCHAR)
> +FRONTEND_GET_PROPERTY(MaxQueues, ULONG)
> +FRONTEND_GET_PROPERTY(NumQueues, ULONG)
>   FRONTEND_GET_PROPERTY(Caps, PXENVBD_CAPS)
>   FRONTEND_GET_PROPERTY(Features, PXENVBD_FEATURES)
>   FRONTEND_GET_PROPERTY(DiskInfo, PXENVBD_DISKINFO)
> -FRONTEND_GET_PROPERTY(Connected, BOOLEAN)
> -FRONTEND_GET_PROPERTY(ReadOnly, BOOLEAN)
> -FRONTEND_GET_PROPERTY(Discard, BOOLEAN)
> -FRONTEND_GET_PROPERTY(FlushCache, BOOLEAN)
> -FRONTEND_GET_PROPERTY(Barrier, BOOLEAN)
> -FRONTEND_GET_PROPERTY(MaxQueues, ULONG)
> -FRONTEND_GET_PROPERTY(NumQueues, ULONG)
>   
>   #undef FRONTEND_GET_PROPERTY
>   
> diff --git a/src/xenvbd/target.c b/src/xenvbd/target.c
> index a07fc45..7dc18f3 100644
> --- a/src/xenvbd/target.c
> +++ b/src/xenvbd/target.c
> @@ -223,11 +223,11 @@ TargetReadWrite(
>       ULONG                   NumSectors;
>   
>       Srb->SrbStatus = SRB_STATUS_ERROR;
> -    if (!FrontendGetConnected(Frontend))
> +    if (!FrontendGetCaps(Frontend)->Connected)
>           goto fail1;
>   
>       // disallow writes to read-only disks
> -    if (FrontendGetReadOnly(Frontend) &&
> +    if (FrontendGetDiskInfo(Frontend)->DiskInfo & VDISK_READONLY &&
>           Cdb_OperationEx(Srb) == SCSIOP_WRITE)
>           goto fail2;
>   
> @@ -266,15 +266,15 @@ TargetSyncCache(
>       PXENVBD_RING            Ring = FrontendGetRing(Frontend);
>   
>       Srb->SrbStatus = SRB_STATUS_ERROR;
> -    if (!FrontendGetConnected(Frontend))
> +    if (!FrontendGetCaps(Frontend)->Connected)
>           goto fail1;
>   
> -    if (FrontendGetReadOnly(Frontend))
> +    if (FrontendGetDiskInfo(Frontend)->DiskInfo & VDISK_READONLY)
>           goto fail2;
>   
>       // If neither FLUSH or BARRIER is supported, just succceed the SRB
> -    if (!(FrontendGetFlushCache(Frontend) ||
> -          FrontendGetBarrier(Frontend)))
> +    if (!(FrontendGetFeatures(Frontend)->FlushCache ||
> +          FrontendGetFeatures(Frontend)->Barrier))
>           goto succeed;
>   
>       Srb->SrbStatus = SRB_STATUS_PENDING;
> @@ -302,13 +302,13 @@ TargetUnmap(
>       PXENVBD_RING            Ring = FrontendGetRing(Frontend);
>   
>       Srb->SrbStatus = SRB_STATUS_ERROR;
> -    if (!FrontendGetConnected(Frontend))
> +    if (!FrontendGetCaps(Frontend)->Connected)
>           goto fail1;
>   
> -    if (FrontendGetReadOnly(Frontend))
> +    if (FrontendGetDiskInfo(Frontend)->DiskInfo & VDISK_READONLY)
>           goto fail2;
>   
> -    if (!FrontendGetDiscard(Frontend))
> +    if (!FrontendGetFeatures(Frontend)->Discard)
>           goto succeed;
>   
>       Srb->SrbStatus = SRB_STATUS_PENDING;
> @@ -359,7 +359,7 @@ __TargetModeSense(
>           // Fill in CachingParams
>           Caching->PageCode           = MODE_PAGE_CACHING;
>           Caching->PageLength         = sizeof(MODE_CACHING_PAGE);
> -        Caching->WriteCacheEnable   = FrontendGetFlushCache(Target->Frontend) ? 1 : 0;
> +        Caching->WriteCacheEnable   = FrontendGetFeatures(Target->Frontend)->FlushCache ? 1 : 0;
>   
>           *ModeDataLength += sizeof(MODE_CACHING_PAGE);
>           *Size           += sizeof(MODE_CACHING_PAGE);
> @@ -386,12 +386,15 @@ TargetModeSense(
>       IN  PSCSI_REQUEST_BLOCK Srb
>       )
>   {
> +    PXENVBD_FRONTEND        Frontend = Target->Frontend;
> +    PXENVBD_DISKINFO        DiskInfo = FrontendGetDiskInfo(Frontend);
>       PMODE_PARAMETER_HEADER  Data  = Srb->DataBuffer;
>       ULONG                   Length = Srb->DataTransferLength;
>       ULONG                   BlockDescrLength = 0;
>       ULONG                   ModeDataLength = 0;
>       ULONG                   Size;
>   
> +
>       Srb->SrbStatus = SRB_STATUS_ERROR;
>   
>       if (Data == NULL)
> @@ -403,7 +406,7 @@ TargetModeSense(
>   
>       // Header
>       Data->MediumType                = 0;
> -    Data->DeviceSpecificParameter   = FrontendGetReadOnly(Target->Frontend) ?
> +    Data->DeviceSpecificParameter   = (DiskInfo->DiskInfo & VDISK_READONLY) ?
>                                                       MODE_DSP_WRITE_PROTECT : 0;
>       Size = sizeof(MODE_PARAMETER_HEADER);
>   
> @@ -431,6 +434,8 @@ TargetModeSense10(
>       IN  PSCSI_REQUEST_BLOCK     Srb
>       )
>   {
> +    PXENVBD_FRONTEND            Frontend = Target->Frontend;
> +    PXENVBD_DISKINFO            DiskInfo = FrontendGetDiskInfo(Frontend);
>       PMODE_PARAMETER_HEADER10    Data  = Srb->DataBuffer;
>       ULONG                       Length = Srb->DataTransferLength;
>       ULONG                       BlockDescrLength = 0;
> @@ -448,7 +453,7 @@ TargetModeSense10(
>   
>       // Header
>       Data->MediumType                = 0;
> -    Data->DeviceSpecificParameter   = FrontendGetReadOnly(Target->Frontend) ?
> +    Data->DeviceSpecificParameter   = (DiskInfo->DiskInfo & VDISK_READONLY) ?
>                                                       MODE_DSP_WRITE_PROTECT : 0;
>       Size = sizeof(MODE_PARAMETER_HEADER10);
>   



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Wed Mar 04 11:53:27 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Wed, 04 Mar 2026 11:53:27 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1245337.1544702 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxkn8-0002la-OP; Wed, 04 Mar 2026 11:53:26 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1245337.1544702; Wed, 04 Mar 2026 11:53:26 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxkn8-0002lS-Lo; Wed, 04 Mar 2026 11:53:26 +0000
Received: by outflank-mailman (input) for mailman id 1245337;
 Wed, 04 Mar 2026 11:53:25 +0000
Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50]
 helo=se1-gles-flk1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=JLki=BE=bounce.vates.tech=bounce-md_30504962.69a81d31.v1-7136ef9db6934fb8bb93086eb7680465@srs-se1.protection.inumbo.net>)
 id 1vxkn7-0002lI-32
 for win-pv-devel@lists.xenproject.org; Wed, 04 Mar 2026 11:53:25 +0000
Received: from mail177-30.suw61.mandrillapp.com
 (mail177-30.suw61.mandrillapp.com [198.2.177.30])
 by se1-gles-flk1.inumbo.com (Halon) with ESMTPS
 id be689018-17c0-11f1-9ccf-f158ae23cfc8;
 Wed, 04 Mar 2026 12:53:22 +0100 (CET)
Received: from pmta14.mandrill.prod.suw01.rsglab.com (localhost [127.0.0.1])
 by mail177-30.suw61.mandrillapp.com (Mailchimp) with ESMTP id
 4fQrf934cjzP0MKvk
 for <win-pv-devel@lists.xenproject.org>; Wed,  4 Mar 2026 11:53:21 +0000 (GMT)
Received: from [37.26.189.201] by mandrillapp.com id
 7136ef9db6934fb8bb93086eb7680465; Wed, 04 Mar 2026 11:53:21 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: be689018-17c0-11f1-9ccf-f158ae23cfc8
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com;
	s=mte1; t=1772625201; x=1772895201;
	bh=V8aH0A+xZfnrIJ9sS44xEiqMf29CRFc8zCdbSN59Cnc=;
	h=From:Subject:Message-Id:To:Cc:References:In-Reply-To:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=nntDBV4DuzdgXLaDWAQG63srJmlhd42rQ7JzKCZ8xO+Cpku8C4r4OfLVdFPukmkBD
	 b5CFml3Hj4BKWqUZ/vnA6JLiC6T3bCTDkFtJd/QU/8nmRFaWTGNgCI9kEMQCRiyxAA
	 lzw66Re3M7E4seUyjnvwdw3gxKAcp2RL6dM9RYy2//81XFIjsGx6obWJjRp/YJylUw
	 7Jnr9tyIfr1zuD+mCAHLVtSfhTrXJ3T3a5pJ/pWHE18+x0hVya1gTpEbmx9Gsj1snt
	 3kjWBeq+SJ6X1GRqs7VFqrXSha9i9UoWhB7AcsN3fyiHi52gS9q5RncZxFY/YLXqZW
	 vi8vYHZqtj21Q==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1;
	t=1772625201; x=1772885701; i=ngoc-tu.dinh@vates.tech;
	bh=V8aH0A+xZfnrIJ9sS44xEiqMf29CRFc8zCdbSN59Cnc=;
	h=From:Subject:Message-Id:To:Cc:References:In-Reply-To:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=eavrbtULAmbrvqXsRot5gPi3s0uM9wXrpNjWCHxwlmUHLbWnhGop9JojRtjMeg8J6
	 lwXIbrVMJJt0/Gh6sZdnZWB6Bq9OU51Eq//gItUhyPu0C9bFTQofbnGAyjwSw+F6Dn
	 pBdSloPjDOGQ9MG1rsSWVgAKQ89hLpTMzYGuSxahNpr2lEQPLhRbEsS3W8y8vt0AXF
	 rHiOnhErXy55ObLVEAtsKLTRkE5cVMcUIYCL6FlQhkUQxAQuEptYmsS8990QokG/sq
	 FMhrrsvaj51vpc9N/elcThU3XWTg1NVOs6bo1GKFIELe13YdI7Ya1sUQ9j+LbZtsIb
	 mcYz2Pw2NLJOw==
From: "Tu Dinh" <ngoc-tu.dinh@vates.tech>
Subject: =?utf-8?Q?Re:=20[PATCH=201/4=20v2]=20XenDisk:=20Report=20Discard=20support=20by=20issuing=20an=20Inquiry?=
X-Bm-Disclaimer: Yes
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1772625200617
Message-Id: <e9f86c9d-48e5-4bdc-b46d-51f33ad19457@vates.tech>
To: "Owen Smith" <owen.smith@citrix.com>, win-pv-devel@lists.xenproject.org
Cc: "Owen Smith" <owen.smith@cloud.com>
References: <20260303093628.1743-1-owen.smith@citrix.com>
In-Reply-To: <20260303093628.1743-1-owen.smith@citrix.com>
X-Native-Encoded: 1
X-Report-Abuse: =?UTF-8?Q?Please=20forward=20a=20copy=20of=20this=20message,=20including=20all=20headers,=20to=20abuse@mandrill.com.=20You=20can=20also=20report=20abuse=20here:=20https://mandrillapp.com/contact/abuse=3Fid=3D30504962.7136ef9db6934fb8bb93086eb7680465?=
X-Mandrill-User: md_30504962
Feedback-ID: 30504962:30504962.20260304:md
Date: Wed, 04 Mar 2026 11:53:21 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit

On 03/03/2026 10:36, Owen Smith wrote:
> From: Owen Smith <owen.smith@cloud.com>
> 
> When XenDisk starts, issue an inquiry to determine the status of discard
> support in the backend. If the backend exposes discard support, allow
> XenDisk to respond to the appropriate property requests, and forward the
> trim requests to XenVbd.
> 
> Signed-off-by: Owen Smith <owen.smith@citrix.com>

Shouldn't XenDisk report unmaps as being unconditionally supported so 
that unmap requests could be passed to XenVbd for processing (as pointed 
out in "Report VPD 0xB2 Logical Block Provisioning" in the XenDisk 
removal series)?

Otherwise, when booting on a backend that doesn't support discards, 
XenDisk will initially report unmaps as unsupported. This will cause 
Windows to not attempt unmaps even if the VM is later migrated to a 
backend that does support discards.

> ---
>   src/xendisk/pdo.c | 88 ++++++++++++++++++++++++++++++++++++++++++++---
>   1 file changed, 84 insertions(+), 4 deletions(-)
> 
> diff --git a/src/xendisk/pdo.c b/src/xendisk/pdo.c
> index f714efb..5d40a13 100644
> --- a/src/xendisk/pdo.c
> +++ b/src/xendisk/pdo.c
> @@ -63,6 +63,7 @@ struct _XENDISK_PDO {
>       PXENDISK_FDO                Fdo;
>   
>       BOOLEAN                     InterceptTrim;
> +    BOOLEAN                     DiscardSupported;
>       ULONG                       SectorSize;
>       ULONG                       PhysSectorSize;
>   };
> @@ -519,6 +520,72 @@ fail1:
>       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,
> @@ -674,7 +741,7 @@ PdoQueryProperty(
>   
>       switch (Query->PropertyId) {
>       case StorageDeviceTrimProperty:
> -        if (!Pdo->InterceptTrim) {
> +        if (!Pdo->InterceptTrim || !Pdo->DiscardSupported) {
>               status = PdoForwardIrpAndForget(Pdo, Irp);
>               break;
>           }
> @@ -753,7 +820,7 @@ PdoManageDataSetAttributes(
>   
>       switch (Attributes->Action) {
>       case DeviceDsmAction_Trim:
> -        if (!Pdo->InterceptTrim) {
> +        if (!Pdo->InterceptTrim || !Pdo->DiscardSupported) {
>               status = PdoForwardIrpAndForget(Pdo, Irp);
>               break;
>           }
> @@ -830,6 +897,7 @@ PdoStartDevice(
>       ULONG               PhysSectorSize;
>       ULONG64             SectorCount;
>       ULONG64             Size;
> +    BOOLEAN             DiscardSupported;
>       POWER_STATE         PowerState;
>       NTSTATUS            status;
>   
> @@ -848,14 +916,22 @@ PdoStartDevice(
>       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)\n",
> -            __PdoGetName(Pdo), Size, SectorSize);
> +    Verbose("%s: %luMB (%uB sectors)%s%s\n",
> +            __PdoGetName(Pdo), Size, SectorSize,
> +            Pdo->DiscardSupported ? " DISCARD" : "",
> +            Pdo->InterceptTrim ? "" : " (VETOED)");
>   
>       __PdoSetSystemPowerState(Pdo, PowerSystemWorking);
>       __PdoSetDevicePowerState(Pdo, PowerDeviceD0);
> @@ -874,6 +950,9 @@ PdoStartDevice(
>   
>       return STATUS_SUCCESS;
>   
> +fail4:
> +    Error("fail4\n");
> +
>   fail3:
>       Error("fail3\n");
>   
> @@ -1904,6 +1983,7 @@ PdoDestroy(
>       Dx->Pdo = NULL;
>   
>       Pdo->InterceptTrim = FALSE;
> +    Pdo->DiscardSupported = FALSE;
>   
>       RtlZeroMemory(Pdo->Name, sizeof (Pdo->Name));
>   



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Wed Mar 04 14:51:47 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Wed, 04 Mar 2026 14:51:47 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1245534.1544891 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxnZi-0004hE-76; Wed, 04 Mar 2026 14:51:46 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1245534.1544891; Wed, 04 Mar 2026 14:51:46 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxnZi-0004h7-4W; Wed, 04 Mar 2026 14:51:46 +0000
Received: by outflank-mailman (input) for mailman id 1245534;
 Wed, 04 Mar 2026 14:51:44 +0000
Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254]
 helo=se1-gles-sth1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=Dykl=BE=citrix.com=owen.smith@srs-se1.protection.inumbo.net>)
 id 1vxnZg-0004gi-5j
 for win-pv-devel@lists.xenproject.org; Wed, 04 Mar 2026 14:51:44 +0000
Received: from SN4PR0501CU005.outbound.protection.outlook.com
 (mail-southcentralusazlp170110003.outbound.protection.outlook.com
 [2a01:111:f403:c10d::3])
 by se1-gles-sth1.inumbo.com (Halon) with ESMTPS
 id a7440bf3-17d9-11f1-b164-2bf370ae4941;
 Wed, 04 Mar 2026 15:51:41 +0100 (CET)
Received: from SA6PR03MB7760.namprd03.prod.outlook.com (2603:10b6:806:43c::5)
 by LV3PR03MB7432.namprd03.prod.outlook.com (2603:10b6:408:1a5::8)
 with Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9654.22; Wed, 4 Mar
 2026 14:51:37 +0000
Received: from SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38]) by SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38%7]) with mapi id 15.20.9654.022; Wed, 4 Mar 2026
 14:51:37 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: a7440bf3-17d9-11f1-b164-2bf370ae4941
ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;
 b=yXgUDaaHc6S+XFjCctqHRmgKUhGOshwBbJ9kBigtONMlQ1KL/x7CvjFGbhF2rryqpEHrBBJV8ZqYG3eW/EXjm340JvFe5O9WF/1hY7aiZsnQEDT6zatX4x2ZyACG+3C4L69dsTh/R9nG0r/bymeB89vKjPYlh8OPjLDx8H2DFxfjI5D7xUjDr8keBxDJh8W+jUy8qySY19+rDDAG9XJoG9XWHQVPoSH0OFv6KL48ieFpBtFEfdfMo6W7LNAD82l2FVWUb5yQCrm5GVQuyoms+WKb5aQ71dwlOIB1BKw9kHs+pELo+Vj7dZAKqn8+CphCYmElHlFWzd6RMKmNC/UNzQ==
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=ifdf6wbkmfJDGzgppSeKXvfQSfS3GDBmjyz6WhhLNv4=;
 b=a28vO4eH444LR6eW/MTrVFdVS6JM9QVLDQKskcQ7GpYfZt/J6uU6pX77hRxB2dEBguaFszj/IJhJSztVCibf4AJAkV/3nceIDcKOE3HcSIPTXNWcGWOR3bTYuCrWSYZv9iv6PAm9b7pXXOUp1zfrtEmoY3fQHE8+wWHVC3gSgDv1N9yq5mavElUqc2qiafz2+qTOlHMnwXK8zSL+YIJPIncpYVnCeEWRPGnFmPIxXK7/JwpqqTMwAv7Kn2lgR8ScuB6k07jn5zmn5Sr8zNomsuu3So2jo/tfHwmbk27Krrcj+5CBeqlym3JwmJaqSn9oIReVR7JXQhvCSCS5ur9GfQ==
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
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com;
 s=selector1;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=ifdf6wbkmfJDGzgppSeKXvfQSfS3GDBmjyz6WhhLNv4=;
 b=vTcb/Bnl0CygpYlTqvo6mcTZjgyHS3F1FR8PyCho7WzbxSwUm9FNyUDJua2lv67yK9IHyyNawNuFVpz+5EOHNTHyNjMWq1wGWepeZCHyQMF0fOKUH8Yp1pwqoPmmBmyKdWhIIQhA9+7RAnnC39Z+DPi6ECVZiO3sg903QzwmCYU=
From: Owen Smith <owen.smith@citrix.com>
To: Tu Dinh <ngoc-tu.dinh@vates.tech>, "win-pv-devel@lists.xenproject.org"
	<win-pv-devel@lists.xenproject.org>
CC: Owen Smith <owen.smith@cloud.com>
Subject: Re: [PATCH 1/4 v2] XenDisk: Report Discard support by issuing an
 Inquiry
Thread-Topic: [PATCH 1/4 v2] XenDisk: Report Discard support by issuing an
 Inquiry
Thread-Index: AQHcqvE6riH0sHOMCEOc/yFCiUd2IbWeRRyAgAAxYZM=
Date: Wed, 4 Mar 2026 14:51:37 +0000
Message-ID:
 <SA6PR03MB7760C31856A024821CB416F1FE7CA@SA6PR03MB7760.namprd03.prod.outlook.com>
References: <20260303093628.1743-1-owen.smith@citrix.com>
 <e9f86c9d-48e5-4bdc-b46d-51f33ad19457@vates.tech>
In-Reply-To: <e9f86c9d-48e5-4bdc-b46d-51f33ad19457@vates.tech>
Accept-Language: en-GB, en-US
Content-Language: en-GB
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
msip_labels:
authentication-results: dkim=none (message not signed)
 header.d=none;dmarc=none action=none header.from=citrix.com;
x-ms-publictraffictype: Email
x-ms-traffictypediagnostic: SA6PR03MB7760:EE_|LV3PR03MB7432:EE_
x-ms-office365-filtering-correlation-id: 36e49bfa-6000-4009-2738-08de79fd89af
x-ms-exchange-senderadcheck: 1
x-ms-exchange-antispam-relay: 0
x-microsoft-antispam:
 BCL:0;ARA:13230040|376014|366016|1800799024|3613699012|38070700021;
x-microsoft-antispam-message-info:
 6A19k/qsj1fjeWyJarF+kTb8MPLRC9Z58zpRt+Es/1zv2z1O6wTcaTqfTAZ+9ym4M3J1R9d7/8UkZkyfKuDFfeKCTYxeFLwq1OJkRJJziQuVfHCB00LNBzkqPVNckhH3qQveZAypz4yaMgcWQrmyLSXAuzGsexG4Jj1MAUyX/UHJC3Fcz8ai7tZiIN5ihB0JRaqT63eDaVvlMnAa7R48Xlx5yFv97TW3tb7tz8f17XClnRbTW8LftmxK61vtZSSyTFfWO/kWCMgU6V8bH+qbC8Nsos4rH4q+dgGWx/6NU6Kd9C5B9AWHASeSRiT1cKYeVzfYPtPtGLDgrWxTgSXCLQ9xyZiBtNO3N71dyn3YC6UUBzGUunNZ10c1DPycDapJ09XG3Eo7kI0/UMIZWPsZeAfF2myVsguiOc9unqAsF2zXmuM84Iqga2o+FsjwXvj9/nVOS6rYAIPc+InvxqyNGW1ug3jcal9VyLuZisuP7UuoMQe9JNGi672OR4j//fXfmbnsHgKayOWmXwkEyJxYF3AWHsH9oYfwuDpXcO7GJe4hnkUsyaO+nwkQo6ti9CIEzZVLYzZV6uNh9o+uS48d7xVoAa9i76QMOOlJmfUSGScnytZEIfur4dAqLGIfpPlhwR1ZX+qqa8RyRwelsdSpZz+518M/K/pGUoNPW9ZVi8njDazJRYs+e5uUIkfpwCfgnCc6FhYWKnByOCEOHUC6O0hwqDgOW/n89EGPN8pL/nISfJhu0CV5IhpI7/uXqAbtwF+pvesvL6epguiTZE3F6Q==
x-forefront-antispam-report:
 CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SA6PR03MB7760.namprd03.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024)(3613699012)(38070700021);DIR:OUT;SFP:1101;
x-ms-exchange-antispam-messagedata-chunkcount: 1
x-ms-exchange-antispam-messagedata-0:
 =?us-ascii?Q?gbwZ+SXWrYGGqG0uAK9qNWHyddDNRPSqECztiOQuAzC9LAksWwTH5xWi6pkt?=
 =?us-ascii?Q?Lmcz1IomIoK8IVbZ+cmIna34ecrpeEJx1CMtq2XIX4R4d03u9oirrGmo/WZH?=
 =?us-ascii?Q?b3x9ugmv5Fglir8E8mEZ91FbTTOQz3RxhnLx9GdMZK1grkwEsY0j5vPFGpXO?=
 =?us-ascii?Q?ZEJC7ZeU3KwHDkpV3BUeCcrmVz7HwjVXj4ptbGuODg1xJ/vFOpUjNthdvppm?=
 =?us-ascii?Q?YO1Ab8UMFpb4lvmnozjZczcMedVpVUT4gaDu/0v+CDbCwTGdpyY58uQKhWCQ?=
 =?us-ascii?Q?NdgARyVNmvWe9RI3JNvvahEIsWZdkl4MfjGfz0LPxylfFYFyD7nlBdLlzbyc?=
 =?us-ascii?Q?J/C5wN3RvcMIfu0DJB0TSUsj40PHa6v57+Bc8nn1jgEZJqmgdMU8E+IS/PvX?=
 =?us-ascii?Q?DMVmt6Ib1Lcme9mDYbieI0f3i5XTUEP/u4GYgP8m+B9nQpFyRCKfFXQtGsFY?=
 =?us-ascii?Q?oCoxPSbCDcN3TcAMPKd3zQhWiejMGfz38KboMD1s9B6SfX2f9uofVzZpyE0G?=
 =?us-ascii?Q?Uv/2U8dwUTKXvqFZBfl3lIuyHAYP52QR1a+zZhakJmWrLJg02f9N8GA9Pju/?=
 =?us-ascii?Q?auIBRq/MNjLrTASYeB1dX1joGI226WjHkVx91m3e0RJYSp89c9HnPIeE8JnJ?=
 =?us-ascii?Q?L384QGjBOPUAi+LWbROqAsg05q0YX3PIBpArqqtTRXedf+48BEno8ZC0IgZ7?=
 =?us-ascii?Q?T7LuocYcAOZSc0Gb6sA/oxhptvq9hKO7HoAv0sQRikfwTwFo3LxV5KnXfBut?=
 =?us-ascii?Q?S3xf8u9f7WT4tXWBsS3XC/OvOQkkhiBfnAui9Rwj6jk6ho6uy7Dt3JDAid6/?=
 =?us-ascii?Q?t7wpGqjpofzwbDdDr8s2y6Hn1IwHT/pfin3Q5EH6ucy+86NazsJ6NFe3EMl9?=
 =?us-ascii?Q?sQmMsew2UVqVqOyMd1VQT1l58E5QmAQmLfFcP9+QHCDmnqg4sdnkG1zu0nnN?=
 =?us-ascii?Q?NYJibq7sZMjLey4BuJs0fm+PeAoAt4I5aVLwL73vOJOq5UaOxBcee46/LAcr?=
 =?us-ascii?Q?hftC4z25cHngYPPwcICuIgFRm3LQFzh6pU1cuQ3bYBl9BkcQ4MMWaFBGlYkv?=
 =?us-ascii?Q?fn/UZuKD7Om+84j0mTaUXQPP9OZrubM8bre2YpsAkWcTpM2pU8UT97d/8WLf?=
 =?us-ascii?Q?Eoy81vDtPo46aWE5hXPpvQ30Wb+8kOEB6aKjUZmThETsVXVMMAYd1Xmkmg5U?=
 =?us-ascii?Q?6FDDwlG15kz37ahqNeDWvqEVlGwM8ttOq6rxGEK+RPuiELFrnTlyr8QOXqQr?=
 =?us-ascii?Q?/9BL+pbuvnughLe0ADZ32lKWxTLkPl9hoNABedVp+GNwB5Jh3sM73iuHDecR?=
 =?us-ascii?Q?7ZA7sEzpOWvtDMR4Aej6e412JcqcoyGKwqgD+KiDP69tYbwRnUqYUau364Mv?=
 =?us-ascii?Q?Mtve8zphXm3TRySH/B/Nn+YtZgcD2Mup8Hd5Lw41WIFaz3uMfPQeMXqRHmFs?=
 =?us-ascii?Q?m47PKxLuriQlIJ3owpOiC+xTz1vBKZzI56z9pK/RlTneVdqdHI44W4Nhw0UG?=
 =?us-ascii?Q?xQ2eo8TODUKkDoXobJpmLb86cUbT1ReMb0ox1jYRprqfaAZ84dSiH9peuRYy?=
 =?us-ascii?Q?9i9ScyHQ3nuNl9xVCGHgXZiez3uMg+ifmGe5gCjo/CobooCic1sY8BpS8d20?=
 =?us-ascii?Q?ka2R4GYP3fdgVcLhEqTkugGu2GM3Bq/CfyGuYHgx1LpBX2n0oaYgUVJqvRHj?=
 =?us-ascii?Q?zMJ9iI5/pl0axNaOobgKZ36Me5r7wyngFsvtBmLlhVJ+NYRg?=
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
X-OriginatorOrg: citrix.com
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-AuthSource: SA6PR03MB7760.namprd03.prod.outlook.com
X-MS-Exchange-CrossTenant-Network-Message-Id: 36e49bfa-6000-4009-2738-08de79fd89af
X-MS-Exchange-CrossTenant-originalarrivaltime: 04 Mar 2026 14:51:37.6206
 (UTC)
X-MS-Exchange-CrossTenant-fromentityheader: Hosted
X-MS-Exchange-CrossTenant-id: 335836de-42ef-43a2-b145-348c2ee9ca5b
X-MS-Exchange-CrossTenant-mailboxtype: HOSTED
X-MS-Exchange-CrossTenant-userprincipalname: 56D5gLlqKyNQJTQh/QnOXBS4Z+c7FSjLUMCXaUWL+ZzNye/LdoSqSudKHCScpgWKdWrpE6Luwra2M00jKgAQbA==
X-MS-Exchange-Transport-CrossTenantHeadersStamped: LV3PR03MB7432

It does seem a little redundant to patch xendisk, then remove xendisk in yo=
ur series.

I'll drop my series for now, and wait until your fixes to xenvbd / removal =
of xendisk is
applied before reworking some of these patches to tidy up xenvbd

Owen

________________________________________
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
Sent: 04 March 2026 11:53 AM
To: Owen Smith; win-pv-devel@lists.xenproject.org
Cc: Owen Smith
Subject: Re: [PATCH 1/4 v2] XenDisk: Report Discard support by issuing an I=
nquiry

On 03/03/2026 10:36, Owen Smith wrote:
> From: Owen Smith <owen.smith@cloud.com>
>
> When XenDisk starts, issue an inquiry to determine the status of discard
> support in the backend. If the backend exposes discard support, allow
> XenDisk to respond to the appropriate property requests, and forward the
> trim requests to XenVbd.
>
> Signed-off-by: Owen Smith <owen.smith@citrix.com>

Shouldn't XenDisk report unmaps as being unconditionally supported so
that unmap requests could be passed to XenVbd for processing (as pointed
out in "Report VPD 0xB2 Logical Block Provisioning" in the XenDisk
removal series)?

Otherwise, when booting on a backend that doesn't support discards,
XenDisk will initially report unmaps as unsupported. This will cause
Windows to not attempt unmaps even if the VM is later migrated to a
backend that does support discards.

> ---
>   src/xendisk/pdo.c | 88 ++++++++++++++++++++++++++++++++++++++++++++---
>   1 file changed, 84 insertions(+), 4 deletions(-)
>
> diff --git a/src/xendisk/pdo.c b/src/xendisk/pdo.c
> index f714efb..5d40a13 100644
> --- a/src/xendisk/pdo.c
> +++ b/src/xendisk/pdo.c
> @@ -63,6 +63,7 @@ struct _XENDISK_PDO {
>       PXENDISK_FDO                Fdo;
>
>       BOOLEAN                     InterceptTrim;
> +    BOOLEAN                     DiscardSupported;
>       ULONG                       SectorSize;
>       ULONG                       PhysSectorSize;
>   };
> @@ -519,6 +520,72 @@ fail1:
>       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("=3D=3D=3D=3D>\n");
> +
> +    Length =3D sizeof(VPD_BLOCK_LIMITS_PAGE);
> +    *Supported =3D FALSE;
> +
> +    status =3D STATUS_NO_MEMORY;
> +    BlockLimits =3D __PdoAllocate(Length);
> +    if (BlockLimits =3D=3D NULL)
> +        goto fail1;
> +
> +    RtlZeroMemory(&Srb, sizeof(SCSI_REQUEST_BLOCK));
> +    Srb.Length =3D sizeof(SCSI_REQUEST_BLOCK);
> +    Srb.SrbFlags =3D 0;
> +    Srb.Function =3D SRB_FUNCTION_EXECUTE_SCSI;
> +    Srb.DataBuffer =3D BlockLimits;
> +    Srb.DataTransferLength =3D Length;
> +    Srb.TimeOutValue =3D (ULONG)-1;
> +    Srb.CdbLength =3D 6;
> +
> +    Cdb =3D (PCDB)&Srb.Cdb[0];
> +    Cdb->CDB6INQUIRY3.OperationCode =3D SCSIOP_INQUIRY;
> +    Cdb->CDB6INQUIRY3.PageCode =3D 0xB0;
> +    Cdb->CDB6INQUIRY3.EnableVitalProductData =3D 1;
> +    Cdb->CDB6INQUIRY3.AllocationLength =3D (UCHAR)Length;
> +
> +    status =3D PdoSendAwaitSrb(Pdo, &Srb);
> +    if (!NT_SUCCESS(status))
> +        goto fail2;
> +
> +    status =3D STATUS_UNSUCCESSFUL;
> +    if (Srb.DataTransferLength < Length)
> +        goto fail3;
> +
> +    *Supported =3D BlockLimits->UGAValid;
> +
> +    __PdoFree(BlockLimits);
> +
> +    Trace("<=3D=3D=3D=3D\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,
> @@ -674,7 +741,7 @@ PdoQueryProperty(
>
>       switch (Query->PropertyId) {
>       case StorageDeviceTrimProperty:
> -        if (!Pdo->InterceptTrim) {
> +        if (!Pdo->InterceptTrim || !Pdo->DiscardSupported) {
>               status =3D PdoForwardIrpAndForget(Pdo, Irp);
>               break;
>           }
> @@ -753,7 +820,7 @@ PdoManageDataSetAttributes(
>
>       switch (Attributes->Action) {
>       case DeviceDsmAction_Trim:
> -        if (!Pdo->InterceptTrim) {
> +        if (!Pdo->InterceptTrim || !Pdo->DiscardSupported) {
>               status =3D PdoForwardIrpAndForget(Pdo, Irp);
>               break;
>           }
> @@ -830,6 +897,7 @@ PdoStartDevice(
>       ULONG               PhysSectorSize;
>       ULONG64             SectorCount;
>       ULONG64             Size;
> +    BOOLEAN             DiscardSupported;
>       POWER_STATE         PowerState;
>       NTSTATUS            status;
>
> @@ -848,14 +916,22 @@ PdoStartDevice(
>       if (!NT_SUCCESS(status))
>           goto fail3;
>
> +    status =3D PdoSendInquiryB0Synchronous(Pdo,
> +                                         &DiscardSupported);
> +    if (!NT_SUCCESS(status))
> +        goto fail4;
> +
>       Pdo->SectorSize =3D SectorSize;
>       Pdo->PhysSectorSize =3D PhysSectorSize;
> +    Pdo->DiscardSupported =3D DiscardSupported;
>
>       Size =3D SectorSize * SectorCount;
>       Size >>=3D 20; // Scale to megabytes
>
> -    Verbose("%s: %luMB (%uB sectors)\n",
> -            __PdoGetName(Pdo), Size, SectorSize);
> +    Verbose("%s: %luMB (%uB sectors)%s%s\n",
> +            __PdoGetName(Pdo), Size, SectorSize,
> +            Pdo->DiscardSupported ? " DISCARD" : "",
> +            Pdo->InterceptTrim ? "" : " (VETOED)");
>
>       __PdoSetSystemPowerState(Pdo, PowerSystemWorking);
>       __PdoSetDevicePowerState(Pdo, PowerDeviceD0);
> @@ -874,6 +950,9 @@ PdoStartDevice(
>
>       return STATUS_SUCCESS;
>
> +fail4:
> +    Error("fail4\n");
> +
>   fail3:
>       Error("fail3\n");
>
> @@ -1904,6 +1983,7 @@ PdoDestroy(
>       Dx->Pdo =3D NULL;
>
>       Pdo->InterceptTrim =3D FALSE;
> +    Pdo->DiscardSupported =3D FALSE;
>
>       RtlZeroMemory(Pdo->Name, sizeof (Pdo->Name));
>



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Wed Mar 04 15:41:13 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Wed, 04 Mar 2026 15:41:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1245676.1545025 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxoLY-0001Q7-Vv; Wed, 04 Mar 2026 15:41:12 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1245676.1545025; Wed, 04 Mar 2026 15:41:12 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vxoLY-0001Q0-SY; Wed, 04 Mar 2026 15:41:12 +0000
Received: by outflank-mailman (input) for mailman id 1245676;
 Wed, 04 Mar 2026 15:41:11 +0000
Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254]
 helo=se1-gles-sth1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=tIcX=BE=bounce.vates.tech=bounce-md_30504962.69a85292.v1-18a97a3b7f1542e89c67499e8d94b975@srs-se1.protection.inumbo.net>)
 id 1vxoLW-0001Pl-5J
 for win-pv-devel@lists.xenproject.org; Wed, 04 Mar 2026 15:41:11 +0000
Received: from mail177-30.suw61.mandrillapp.com
 (mail177-30.suw61.mandrillapp.com [198.2.177.30])
 by se1-gles-sth1.inumbo.com (Halon) with ESMTPS
 id 8faf5774-17e0-11f1-b164-2bf370ae4941;
 Wed, 04 Mar 2026 16:41:08 +0100 (CET)
Received: from pmta14.mandrill.prod.suw01.rsglab.com (localhost [127.0.0.1])
 by mail177-30.suw61.mandrillapp.com (Mailchimp) with ESMTP id
 4fQxhy5FpYzP0Jn5y
 for <win-pv-devel@lists.xenproject.org>; Wed,  4 Mar 2026 15:41:06 +0000 (GMT)
Received: from [37.26.189.201] by mandrillapp.com id
 18a97a3b7f1542e89c67499e8d94b975; Wed, 04 Mar 2026 15:41:06 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: 8faf5774-17e0-11f1-b164-2bf370ae4941
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com;
	s=mte1; t=1772638866; x=1772908866;
	bh=K0oXT4JMi0IdOlw8MUWYMCJF6zaYhKZ+CU9/xYY8i2E=;
	h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=FVGrIn92URWi39USmcgRosjzwE1DbKFIMoZ/R7V7dWrxj52l8dJBqAR+d2z+2ymyv
	 5qvbt3h/77ePMCzyXN767S5abFHr2XN4ENYm2DP3RDlDbN4diT9wWDv1XtRjUdLc4M
	 funbIWBaJ2nemN297wvT+9hwQxRhrMcRM65GTTopi3wwG8ZOhUaueqokhQsphoK3TP
	 1DemRz2WYm897h1MYrC/ybgOW7IvYDUH+VjPgrKuhi4hApJnnX61Av/BVsnFKvkr3D
	 RLH7R1Pjj6N3CPhG/fkLGjxWitLFvUFGPgbtURRdnojD+Y8zQTXFt9zVwf6nB64zlY
	 nlSog4P3wahCA==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1;
	t=1772638866; x=1772899366; i=ngoc-tu.dinh@vates.tech;
	bh=K0oXT4JMi0IdOlw8MUWYMCJF6zaYhKZ+CU9/xYY8i2E=;
	h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=ZJKxsg6bIH1cB0OYBNTQvAjafDWz5URq7ZcCPDYY5D0vpUIWKIlHvfRMQxMIxEXPk
	 FLXr5ZNa1+YLLUtqKUvcxHXD1BgQl0MElx6xTwQ/Mxc2FgMsRB6N/wcmV08SlP5W1/
	 PEPz9wdl/lJvantdHRI7Ejm0T1Hf7AOSIFi0HZQ6pCmeAMKvzs6T5u64iAkHUJM65n
	 5YJBz/GUhfFqX+/Abblpr4BAjay+MNfwIWmCDFvchVgfmDs7ru0TnwlU2wXVqDneqa
	 BfGgSnMyuq0zWYsILIqMDpvsNNxFDjvIBlvQcqdWiFPFYnlMEs+i3x40jcBEGZAYKo
	 exNlkvILfNsdw==
From: "Tu Dinh" <ngoc-tu.dinh@vates.tech>
Subject: =?utf-8?Q?[PATCH=20v2=206/6]=20Remove=20XenDisk?=
X-Mailer: git-send-email 2.53.0.windows.1
X-Bm-Disclaimer: Yes
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1772638865237
To: win-pv-devel@lists.xenproject.org
Cc: "Owen Smith" <owen.smith@citrix.com>, "Tu Dinh" <ngoc-tu.dinh@vates.tech>
Message-Id: <20260304154051.351-1-ngoc-tu.dinh@vates.tech>
In-Reply-To: <SA6PR03MB7760D5FA973CC19465CCAE00FE7CA@SA6PR03MB7760.namprd03.prod.outlook.com>
References: <SA6PR03MB7760D5FA973CC19465CCAE00FE7CA@SA6PR03MB7760.namprd03.prod.outlook.com>
X-Native-Encoded: 1
X-Report-Abuse: =?UTF-8?Q?Please=20forward=20a=20copy=20of=20this=20message,=20including=20all=20headers,=20to=20abuse@mandrill.com.=20You=20can=20also=20report=20abuse=20here:=20https://mandrillapp.com/contact/abuse=3Fid=3D30504962.18a97a3b7f1542e89c67499e8d94b975?=
X-Mandrill-User: md_30504962
Feedback-ID: 30504962:30504962.20260304:md
Date: Wed, 04 Mar 2026 15:41:06 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit

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@vates.tech>
---
@Owen: I've rebased this on top of "[PATCH 2/4 v2] Refactor Features and
DiskInfo" and "[PATCH 3/4 v2] Consolidate macro'ed access to properties",
without the "XenDisk: Report Discard support by issuing an Inquiry"
patch.
---
 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                   | 1920 ---------------------------
 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                      |   22 -
 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 -
 25 files changed, 1 insertion(+), 6902 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 f714efb..0000000
--- a/src/xendisk/pdo.c
+++ /dev/null
@@ -1,1920 +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;
-    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
-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) {
-            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) {
-            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;
-    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;
-
-    Pdo->SectorSize = SectorSize;
-    Pdo->PhysSectorSize = PhysSectorSize;
-
-    Size = SectorSize * SectorCount;
-    Size >>= 20; // Scale to megabytes
-
-    Verbose("%s: %luMB (%uB sectors)\n",
-            __PdoGetName(Pdo), Size, SectorSize);
-
-    __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;
-
-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;
-
-    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..eb82210 100644
--- a/src/xenvbd.inf
+++ b/src/xenvbd.inf
@@ -48,7 +48,6 @@ DefaultDestDir=12
 [SourceDisksFiles]
 xenvbd.sys=0,,
 xencrsh.sys=0,,
-xendisk.sys=0,,
 
 [Manufacturer] 
 %Vendor%=Inst,NT@INF_ARCH@
@@ -67,29 +66,9 @@ 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] 
 AddService=xenvbd,2,XenVbd_Service,
-AddService=xendisk,,XenDisk_Service,
-
-[XenDisk_Service]
-DisplayName=%XenDiskName%
-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%
@@ -122,7 +101,6 @@ HKLM,%DiskKey%,"TimeOutValue",0x00010001,120
 Vendor = "@VENDOR_NAME@"
 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"
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.53.0.windows.1



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Thu Mar 05 16:02:00 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Thu, 05 Mar 2026 16:02:00 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1246905.1545920 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vyB9C-0007F5-7V; Thu, 05 Mar 2026 16:01:58 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1246905.1545920; Thu, 05 Mar 2026 16:01:58 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vyB9C-0007Ex-3M; Thu, 05 Mar 2026 16:01:58 +0000
Received: by outflank-mailman (input) for mailman id 1246905;
 Thu, 05 Mar 2026 16:01:57 +0000
Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50]
 helo=se1-gles-flk1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=KhWN=BF=bounce.vates.tech=bounce-md_30504962.69a9a8ef.v1-95a8b0432ccb4c0f91807ba2e35d7f1a@srs-se1.protection.inumbo.net>)
 id 1vyB9A-0007Er-Ra
 for win-pv-devel@lists.xenproject.org; Thu, 05 Mar 2026 16:01:57 +0000
Received: from mail132-19.atl131.mandrillapp.com
 (mail132-19.atl131.mandrillapp.com [198.2.132.19])
 by se1-gles-flk1.inumbo.com (Halon) with ESMTPS
 id 9ffc6f76-18ac-11f1-9ccf-f158ae23cfc8;
 Thu, 05 Mar 2026 17:01:53 +0100 (CET)
Received: from pmta09.mandrill.prod.atl01.rsglab.com (localhost [127.0.0.1])
 by mail132-19.atl131.mandrillapp.com (Mailchimp) with ESMTP id 4fRZ6R3chJz4KP
 for <win-pv-devel@lists.xenproject.org>; Thu,  5 Mar 2026 16:01:51 +0000 (GMT)
Received: from [37.26.189.201] by mandrillapp.com id
 95a8b0432ccb4c0f91807ba2e35d7f1a; Thu, 05 Mar 2026 16:01:51 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: 9ffc6f76-18ac-11f1-9ccf-f158ae23cfc8
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com;
	s=mte1; t=1772726511; x=1772996511;
	bh=LnD4y+vsimKzXtg70lpb1qmwKVuuEL9UADYrTYRCvA4=;
	h=From:Subject:To:Cc:Message-Id:Feedback-ID:Date:MIME-Version:
	 Content-Type:Content-Transfer-Encoding:CC:Date:Subject:From;
	b=lCu7BxDhV+jHGyhAeYu6cVfRcNJF+5nN10eNg/6ahR68mgQokHExaYjOGIE6rxEcS
	 vI6sGo6dfWei5TBD9yHB0V/JWANKbRJyELcc5hWds80R/ajPTJtWk2Xvb3MDvufwo3
	 aFNSCJP3jIkLu6qKoLNSDl5WDiesdQBNDKC59lWFWbkiZLOUNSB/4C88FSRRS6/EPl
	 IPdG4sGAqbynrd0yj5akvLnIW4RE7VMyfncWeLLB3IWobSVJ/1vvB4IJGbbyWHw33U
	 ZG7NQntns4DRlQ/iHWRB7e+gxIGuOGQ22bcOfDj9wNbFI5Ws/6F+WJCxgBqrvKLBCk
	 K3dWbI8T8r0KQ==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1;
	t=1772726511; x=1772987011; i=ngoc-tu.dinh@vates.tech;
	bh=LnD4y+vsimKzXtg70lpb1qmwKVuuEL9UADYrTYRCvA4=;
	h=From:Subject:To:Cc:Message-Id:Feedback-ID:Date:MIME-Version:
	 Content-Type:Content-Transfer-Encoding:CC:Date:Subject:From;
	b=RWIcdYM4WmNVnCzbTTxboZFTvaULyqs5YF72pPfF//DJg1MHBLXfqLD1EI1Yc2x+T
	 TdR8AsjmKJo2Jyt/vMU1KW4EGHpTzm9sssKxcWqlxjniU7ZRShqOi7SnE/yhnP9Kpj
	 ovAMGYzrtLHvaq1BfJaenc5DkuxQXZyryNqja8q/gj7aiB6KkSjeEAHv5MySZmBImW
	 hA65ORAjq/STyzNQi6N2RlF874avCyFqwF8jqq0Ds7iqh9eoUR70u37Yw38HtZLwky
	 7HQDX/nJ9LgOGE5rBqqGjvSfla0u7X/ITUKMGO77YdGei9PKSYrhFeUsFIUacfPSS6
	 rTuP92ba2+6+g==
From: "Tu Dinh" <ngoc-tu.dinh@vates.tech>
Subject: =?utf-8?Q?[PATCH]=20Use=20direct=20hypercall=20instead=20of=20hypercall=20page?=
X-Mailer: git-send-email 2.53.0.windows.1
X-Bm-Disclaimer: Yes
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1772726502844
To: win-pv-devel@lists.xenproject.org
Cc: "Owen Smith" <owen.smith@citrix.com>, "Tu Dinh" <ngoc-tu.dinh@vates.tech>
Message-Id: <20260305160136.1704-1-ngoc-tu.dinh@vates.tech>
X-Native-Encoded: 1
X-Report-Abuse: =?UTF-8?Q?Please=20forward=20a=20copy=20of=20this=20message,=20including=20all=20headers,=20to=20abuse@mandrill.com.=20You=20can=20also=20report=20abuse=20here:=20https://mandrillapp.com/contact/abuse=3Fid=3D30504962.95a8b0432ccb4c0f91807ba2e35d7f1a?=
X-Mandrill-User: md_30504962
Feedback-ID: 30504962:30504962.20260305:md
Date: Thu, 05 Mar 2026 16:01:51 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit

XSA-466 "Xen hypercall page unsafe against speculative attacks"
recommends that OSes avoid using the hypercall page, since that breaks
the use of return thunks and CET IBT.

While Windows doesn't support return thunks or CET IBT, the current
hypercall code uses a naked indirect call to call into the hypercall
page. This call is not protected by Windows CFG, and cannot be patched
by Windows's Retpoline implementation.

Convert the hypercall code to detect CPU vendor and use the appropriate
hypercall instructions.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
---
 include/xen.h                     |   8 --
 src/xen/amd64/hypercall_thunk.asm | 101 +++++++++++-----
 src/xen/driver.c                  |  33 +++---
 src/xen/hypercall.c               | 191 +++++++++++++++++-------------
 src/xen/hypercall.h               |   2 +-
 src/xen/i386/hypercall_thunk.asm  |  69 ++++++++---
 src/xenbus/fdo.c                  |   2 -
 src/xenbus/suspend.c              |   2 -
 8 files changed, 254 insertions(+), 154 deletions(-)

diff --git a/include/xen.h b/include/xen.h
index 8691a0f..0c3e8a4 100644
--- a/include/xen.h
+++ b/include/xen.h
@@ -76,14 +76,6 @@ XenTouch(
     _In_ ULONG      BuildNumber
     );
 
-// HYPERCALL
-
-XEN_API
-VOID
-HypercallPopulate(
-    VOID
-    );
-
 // HVM
 
 _Check_return_
diff --git a/src/xen/amd64/hypercall_thunk.asm b/src/xen/amd64/hypercall_thunk.asm
index af045bb..b32ee2e 100644
--- a/src/xen/amd64/hypercall_thunk.asm
+++ b/src/xen/amd64/hypercall_thunk.asm
@@ -3,39 +3,76 @@
 
                         .code
 
-                        extrn   Hypercall:qword
+                        ; uintptr_t __stdcall hypercall2_vmcall(
+                        ;     uint32_t    ord,
+                        ;     uintptr_t   arg1,
+                        ;     uintptr_t   arg2);
+                        public hypercall2_vmcall
+hypercall2_vmcall       proc
+                        push	rdi
+                        push	rsi
+                        mov     eax, ecx                            ; ord
+                        mov		rdi, rdx                            ; arg1
+                        mov		rsi, r8                             ; arg2
+                        vmcall
+                        pop		rsi
+                        pop		rdi
+                        ret
+hypercall2_vmcall       endp
 
-                        ; uintptr_t __stdcall hypercall2(uint32_t ord, uintptr_t arg1, uintptr_t arg2);
-                        public hypercall2
-hypercall2        	proc
-	                push rdi
-	                push rsi
-	                mov rdi, rdx                            ; arg1
-	                mov rax, qword ptr [Hypercall]
-	                shl rcx, 5                              ; ord
-	                add rax, rcx
-	                mov rsi, r8                             ; arg2
-	                call rax
-	                pop rsi
-	                pop rdi
-	                ret
-hypercall2        	endp
+                        ; uintptr_t __stdcall hypercall2_vmmcall(
+                        ;     uint32_t    ord,
+                        ;     uintptr_t   arg1,
+                        ;     uintptr_t   arg2);
+                        public hypercall2_vmmcall
+hypercall2_vmmcall      proc
+                        push	rdi
+                        push	rsi
+                        mov     eax, ecx                            ; ord
+                        mov		rdi, rdx                            ; arg1
+                        mov		rsi, r8                             ; arg2
+                        vmmcall
+                        pop		rsi
+                        pop		rdi
+                        ret
+hypercall2_vmmcall      endp
 
-                        ; uintptr_t __stdcall hypercall3(uint32_t ord, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3);
-                        public hypercall3
-hypercall3 		proc
-	                push rdi
-	                push rsi
-	                mov rdi, rdx                            ; arg1
-	                mov rax, qword ptr [Hypercall]
-	                shl rcx, 5                              ; ord
-	                add rax, rcx
-	                mov rsi, r8                             ; arg2
-	                mov rdx, r9                             ; arg3
-	                call rax
-	                pop rsi
-	                pop rdi
-	                ret
-hypercall3 		endp
+                        ; uintptr_t __stdcall hypercall3_vmcall(
+                        ;     uint32_t    ord,
+                        ;     uintptr_t   arg1,
+                        ;     uintptr_t   arg2,
+                        ;     uintptr_t   arg3);
+                        public hypercall3_vmcall
+hypercall3_vmcall       proc
+                        push    rdi
+                        push    rsi
+                        mov     eax, ecx                            ; ord
+                        mov     rdi, rdx                            ; arg1
+                        mov     rsi, r8                             ; arg2
+                        mov     rdx, r9                             ; arg3
+                        vmcall
+                        pop     rsi
+                        pop     rdi
+                        ret
+hypercall3_vmcall       endp
+
+                        ; uintptr_t __stdcall hypercall3_vmmcall(
+                        ;     uint32_t    ord,
+                        ;     uintptr_t   arg1,
+                        ;     uintptr_t   arg2,
+                        ;     uintptr_t   arg3);
+                        public hypercall3_vmmcall
+hypercall3_vmmcall      proc
+                        push    rdi
+                        push    rsi
+                        mov     eax, ecx                            ; ord
+                        mov     rdi, rdx                            ; arg1
+                        mov     rsi, r8                             ; arg2
+                        mov     rdx, r9                             ; arg3
+                        vmmcall
+                        pop     rsi
+                        pop     rdi
+                        ret
+hypercall3_vmmcall      endp
 
                         end
diff --git a/src/xen/driver.c b/src/xen/driver.c
index 7b2621b..0bed6d1 100644
--- a/src/xen/driver.c
+++ b/src/xen/driver.c
@@ -621,31 +621,33 @@ DllInitialize(
 
     __DriverSetMemoryKey(MemoryKey);
 
-    HypercallInitialize();
+    status = HypercallInitialize();
+    if (!NT_SUCCESS(status))
+        goto fail8;
 
     status = AcpiInitialize();
     if (!NT_SUCCESS(status))
-        goto fail8;
+        goto fail9;
 
     status = SystemInitialize();
     if (!NT_SUCCESS(status))
-        goto fail9;
+        goto fail10;
 
     status = BugCheckInitialize();
     if (!NT_SUCCESS(status))
-        goto fail10;
+        goto fail11;
 
     status = ModuleInitialize();
     if (!NT_SUCCESS(status))
-        goto fail11;
+        goto fail12;
 
     status = ProcessInitialize();
     if (!NT_SUCCESS(status))
-        goto fail12;
+        goto fail13;
 
     status = UnplugInitialize();
     if (!NT_SUCCESS(status))
-        goto fail13;
+        goto fail14;
 
     RegistryCloseKey(ServiceKey);
 
@@ -653,36 +655,39 @@ DllInitialize(
 
     return STATUS_SUCCESS;
 
+fail14:
+    Error("fail14\n");
+
+    ProcessTeardown();
+
 fail13:
     Error("fail13\n");
 
-    ProcessTeardown();
+    ModuleTeardown();
 
 fail12:
     Error("fail12\n");
 
-    ModuleTeardown();
+    BugCheckTeardown();
 
 fail11:
     Error("fail11\n");
 
-    BugCheckTeardown();
+    SystemTeardown();
 
 fail10:
     Error("fail10\n");
 
-    SystemTeardown();
+    AcpiTeardown();
 
 fail9:
     Error("fail9\n");
 
-    AcpiTeardown();
+    HypercallTeardown();
 
 fail8:
     Error("fail8\n");
 
-    HypercallTeardown();
-
     RegistryCloseKey(MemoryKey);
     __DriverSetMemoryKey(NULL);
 
diff --git a/src/xen/hypercall.c b/src/xen/hypercall.c
index 911ae4f..3c68709 100644
--- a/src/xen/hypercall.c
+++ b/src/xen/hypercall.c
@@ -30,9 +30,6 @@
  * SUCH DAMAGE.
  */
 
-#undef  XEN_API
-#define XEN_API __declspec(dllexport)
-
 #include <ntddk.h>
 #include <xen.h>
 #include <intrin.h>
@@ -42,55 +39,63 @@
 #include "assert.h"
 #include "util.h"
 
-#define MAXIMUM_HYPERCALL_PAGE_COUNT 2
-
-#pragma code_seg("hypercall")
-__declspec(allocate("hypercall"))
-static UCHAR        __Section[(MAXIMUM_HYPERCALL_PAGE_COUNT + 1) * PAGE_SIZE];
-
-static ULONG        XenBaseLeaf = 0x40000000;
-
-static PHYSICAL_ADDRESS HypercallPage[MAXIMUM_HYPERCALL_PAGE_COUNT];
-static ULONG            HypercallPageCount;
-static BOOLEAN          HypercallPageInitialized;
-
-typedef UCHAR           HYPERCALL_GATE[32];
-typedef HYPERCALL_GATE  *PHYPERCALL_GATE;
-
-PHYPERCALL_GATE     Hypercall;
-ULONG               HypercallMsr;
-
-XEN_API
-VOID
-HypercallPopulate(
-    VOID
-    )
-{
-    ULONG       Index;
-
-    for (Index = 0; Index < HypercallPageCount; Index++) {
-        LogPrintf(LOG_LEVEL_INFO,
-                  "XEN: HYPERCALL PAGE %d @ %08x.%08x\n",
-                  Index,
-                  HypercallPage[Index].HighPart,
-                  HypercallPage[Index].LowPart);
-
-        __writemsr(HypercallMsr, HypercallPage[Index].QuadPart);
-    }
-
-    HypercallPageInitialized = TRUE;
-}
-
-VOID
+typedef enum _HYPERCALL_INSTRUCTION {
+    HYPERCALL_INSTRUCTION_UNKNOWN,
+    HYPERCALL_INSTRUCTION_VMCALL,
+    HYPERCALL_INSTRUCTION_VMMCALL,
+} HYPERCALL_INSTRUCTION;
+
+typedef struct _CPU_VENDOR_DATA {
+    ULONG                   EBX;
+    ULONG                   ECX;
+    ULONG                   EDX;
+    HYPERCALL_INSTRUCTION   Instruction;
+} CPU_VENDOR_DATA;
+
+static const CPU_VENDOR_DATA    HypercallVendorData[] = {
+    // Note that the vendor data goes EBX-ECX-EDX
+    {
+        // "GenuineIntel"
+        0x756E6547, 0x6C65746E, 0x49656E69,
+        HYPERCALL_INSTRUCTION_VMCALL
+    },
+    {
+        // "AuthenticAMD"
+        0x68747541, 0x444D4163, 0x69746E65,
+        HYPERCALL_INSTRUCTION_VMMCALL
+    },
+    {
+        // "CentaurHauls"
+        0x746E6543, 0x736C7561, 0x48727561,
+        HYPERCALL_INSTRUCTION_VMCALL
+    },
+    {
+        // "  Shanghai  "
+        0x68532020, 0x20206961, 0x68676E61,
+        HYPERCALL_INSTRUCTION_VMCALL
+    },
+    {
+        // "HygonGenuine"
+        0x6F677948, 0x656E6975, 0x6E65476E,
+        HYPERCALL_INSTRUCTION_VMMCALL
+    },
+};
+
+static HYPERCALL_INSTRUCTION    HypercallInstruction
+    = HYPERCALL_INSTRUCTION_UNKNOWN;
+
+NTSTATUS
 HypercallInitialize(
     VOID
     )
 {
-    ULONG       EAX = 'DEAD';
-    ULONG       EBX = 'DEAD';
-    ULONG       ECX = 'DEAD';
-    ULONG       EDX = 'DEAD';
-    ULONG_PTR   Index;
+    ULONG                   XenBaseLeaf = 0x40000000;
+    ULONG                   EAX = 'DEAD';
+    ULONG                   EBX = 'DEAD';
+    ULONG                   ECX = 'DEAD';
+    ULONG                   EDX = 'DEAD';
+    HYPERCALL_INSTRUCTION   Instruction = HYPERCALL_INSTRUCTION_UNKNOWN;
+    ULONG                   Index;
 
     for (;;) {
         CHAR    Signature[13] = {0};
@@ -103,13 +108,13 @@ HypercallInitialize(
         if (strcmp(Signature, "XenVMMXenVMM") == 0 &&
             EAX >= XenBaseLeaf + 2)
             break;
-            
+
         XenBaseLeaf += 0x100;
-        
+
         if (XenBaseLeaf > 0x40000100) {
             LogPrintf(LOG_LEVEL_INFO,
                       "XEN: BASE CPUID LEAF NOT FOUND\n");
-            return;
+            return STATUS_NOT_SUPPORTED;
         }
     }
 
@@ -117,27 +122,46 @@ HypercallInitialize(
               "XEN: BASE CPUID LEAF @ %08x\n",
               XenBaseLeaf);
 
-    if ((ULONG_PTR)__Section & (PAGE_SIZE - 1))
-        Hypercall = (PVOID)(((ULONG_PTR)__Section + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
-    else
-        Hypercall = (PVOID)__Section;
-
-    ASSERT3U(((ULONG_PTR)Hypercall & (PAGE_SIZE - 1)), ==, 0);
+    __CpuId(0, &EAX, &EBX, &ECX, &EDX);
+    for (Index = 0; Index < ARRAYSIZE(HypercallVendorData); Index++) {
+        const CPU_VENDOR_DATA   *CurrentData = &HypercallVendorData[Index];
 
-    for (Index = 0; Index < MAXIMUM_HYPERCALL_PAGE_COUNT; Index++)
-        HypercallPage[Index] = MmGetPhysicalAddress((PUCHAR)Hypercall +
-                                                    (Index << PAGE_SHIFT));
+        if (EBX == CurrentData->EBX &&
+            ECX == CurrentData->ECX &&
+            EDX == CurrentData->EDX) {
+            Instruction = CurrentData->Instruction;
+            break;
+        }
+    }
 
-    __CpuId(XenBaseLeaf + 2, &EAX, &EBX, NULL, NULL);
-    HypercallPageCount = EAX;
-    ASSERT(HypercallPageCount <= MAXIMUM_HYPERCALL_PAGE_COUNT);
-    HypercallMsr = EBX;
+    if (Instruction == HYPERCALL_INSTRUCTION_UNKNOWN) {
+        LogPrintf(LOG_LEVEL_INFO,
+                  "XEN: CANNOT DETECT HYPERCALL INSTRUCTION\n");
+        return STATUS_NOT_SUPPORTED;
+    }
 
-    HypercallPopulate();
+    HypercallInstruction = Instruction;
+    return STATUS_SUCCESS;
 }
 
-extern uintptr_t __stdcall hypercall2(uint32_t ord, uintptr_t arg1, uintptr_t arg2);
-extern uintptr_t __stdcall hypercall3(uint32_t ord, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3);
+extern uintptr_t __stdcall hypercall2_vmcall(
+    uint32_t    ord,
+    uintptr_t   arg1,
+    uintptr_t   arg2);
+extern uintptr_t __stdcall hypercall2_vmmcall(
+    uint32_t    ord,
+    uintptr_t   arg1,
+    uintptr_t   arg2);
+extern uintptr_t __stdcall hypercall3_vmcall(
+    uint32_t    ord,
+    uintptr_t   arg1,
+    uintptr_t   arg2,
+    uintptr_t   arg3);
+extern uintptr_t __stdcall hypercall3_vmmcall(
+    uint32_t    ord,
+    uintptr_t   arg1,
+    uintptr_t   arg2,
+    uintptr_t   arg3);
 
 LONG_PTR
 __Hypercall(
@@ -149,9 +173,6 @@ __Hypercall(
     va_list     Arguments;
     ULONG_PTR   Value;
 
-    if (!HypercallPageInitialized)
-        return -ENOSYS;
-
     va_start(Arguments, Count);
     switch (Count) {
     case 2: {
@@ -159,7 +180,16 @@ __Hypercall(
         uintptr_t  arg1 = va_arg(Arguments, ULONG_PTR);
         uintptr_t  arg2 = va_arg(Arguments, ULONG_PTR);
 
-        Value = hypercall2(ord, arg1, arg2);
+        switch (HypercallInstruction) {
+        case HYPERCALL_INSTRUCTION_VMCALL:
+            Value = hypercall2_vmcall(ord, arg1, arg2);
+            break;
+        case HYPERCALL_INSTRUCTION_VMMCALL:
+            Value = hypercall2_vmmcall(ord, arg1, arg2);
+            break;
+        default:
+            BUG("NO HYPERCALL INSTRUCTION");
+        }
         break;
     }
     case 3: {
@@ -168,7 +198,16 @@ __Hypercall(
         uintptr_t  arg2 = va_arg(Arguments, ULONG_PTR);
         uintptr_t  arg3 = va_arg(Arguments, ULONG_PTR);
 
-        Value = hypercall3(ord, arg1, arg2, arg3);
+        switch (HypercallInstruction) {
+        case HYPERCALL_INSTRUCTION_VMCALL:
+            Value = hypercall3_vmcall(ord, arg1, arg2, arg3);
+            break;
+        case HYPERCALL_INSTRUCTION_VMMCALL:
+            Value = hypercall3_vmmcall(ord, arg1, arg2, arg3);
+            break;
+        default:
+            BUG("NO HYPERCALL INSTRUCTION");
+        }
         break;
     }
     default:
@@ -185,12 +224,4 @@ HypercallTeardown(
     VOID
     )
 {
-    ULONG   Index;
-
-    Hypercall = NULL;
-
-    for (Index = 0; Index < MAXIMUM_HYPERCALL_PAGE_COUNT; Index++)
-        HypercallPage[Index].QuadPart = 0;
-
-    HypercallPageCount = 0;
 }
diff --git a/src/xen/hypercall.h b/src/xen/hypercall.h
index 306d9ab..6f4c7e0 100644
--- a/src/xen/hypercall.h
+++ b/src/xen/hypercall.h
@@ -40,7 +40,7 @@
 
 #include <public/xen.h>
 
-extern VOID
+extern NTSTATUS
 HypercallInitialize(
     VOID
     );
diff --git a/src/xen/i386/hypercall_thunk.asm b/src/xen/i386/hypercall_thunk.asm
index a15ae27..be68db3 100644
--- a/src/xen/i386/hypercall_thunk.asm
+++ b/src/xen/i386/hypercall_thunk.asm
@@ -5,28 +5,69 @@
                         .model  FLAT
                         .code
 
-                        extrn   _Hypercall:dword
+                        ; uintptr_t __stdcall hypercall2_vmcall(
+                        ;     uint32_t    ord,
+                        ;     uintptr_t   arg1,
+                        ;     uintptr_t   arg2);
+                        public _hypercall2_vmcall@12
+_hypercall2_vmcall@12   proc
+                        push    ebp
+                        mov     ebp, esp
+                        push    ebx
+                        mov     eax, [ebp + 08h]                ; ord
+                        mov     ebx, [ebp + 0ch]                ; arg1
+                        mov     ecx, [ebp + 10h]                ; arg2
+                        vmcall
+                        pop     ebx
+                        leave
+                        ret     0Ch
+_hypercall2_vmcall@12   endp
 
-                        ; uintptr_t __stdcall hypercall2(uint32_t ord, uintptr_t arg1, uintptr_t arg2);
-                        public _hypercall2@12
-_hypercall2@12    	proc
+                        ; uintptr_t __stdcall hypercall2_vmmcall(
+                        ;     uint32_t    ord,
+                        ;     uintptr_t   arg1,
+                        ;     uintptr_t   arg2);
+                        public _hypercall2_vmmcall@12
+_hypercall2_vmmcall@12  proc
                         push    ebp
                         mov     ebp, esp
                         push    ebx
                         mov     eax, [ebp + 08h]                ; ord
                         mov     ebx, [ebp + 0ch]                ; arg1
                         mov     ecx, [ebp + 10h]                ; arg2
-                        shl     eax, 5
-                        add     eax, dword ptr [_Hypercall]
-                        call    eax
+                        vmmcall
                         pop     ebx
                         leave
                         ret     0Ch
-_hypercall2@12    	endp
+_hypercall2_vmmcall@12  endp
+
+                        ; uintptr_t __stdcall hypercall3_vmcall(
+                        ;     uint32_t    ord,
+                        ;     uintptr_t   arg1,
+                        ;     uintptr_t   arg2,
+                        ;     uintptr_t   arg3);
+                        public _hypercall3_vmcall@16
+_hypercall3_vmcall@16   proc
+                        push    ebp
+                        mov     ebp, esp
+                        push    ebx
+                        mov     eax, [ebp + 08h]                ; ord
+                        mov     ebx, [ebp + 0ch]                ; arg1
+                        mov     ecx, [ebp + 10h]                ; arg2
+                        mov     edx, [ebp + 14h]                ; arg3
+                        vmcall
+                        pop     ebx
+                        leave
+                        ret     10h
+_hypercall3_vmcall@16   endp
 
-                        ; uintptr_t __stdcall hypercall3(uint32_t ord, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3);
-                        public _hypercall3@16
-_hypercall3@16    	proc
+                        ; uintptr_t __stdcall hypercall3_vmmcall(
+                        ;     uint32_t    ord,
+                        ;     uintptr_t   arg1,
+                        ;     uintptr_t   arg2,
+                        ;     uintptr_t   arg3);
+                        public _hypercall3_vmmcall@16
+_hypercall3_vmmcall@16  proc
                         push    ebp
                         mov     ebp, esp
                         push    ebx
@@ -34,12 +75,10 @@ _hypercall3@16    	proc
                         mov     ebx, [ebp + 0ch]                ; arg1
                         mov     ecx, [ebp + 10h]                ; arg2
                         mov     edx, [ebp + 14h]                ; arg3
-                        shl     eax, 5
-                        add     eax, dword ptr [_Hypercall]
-                        call    eax
+                        vmmcall
                         pop     ebx
                         leave
                         ret     10h
-_hypercall3@16    	endp
+_hypercall3_vmmcall@16  endp
 
                         end
diff --git a/src/xenbus/fdo.c b/src/xenbus/fdo.c
index 8695a56..a5a0ca1 100644
--- a/src/xenbus/fdo.c
+++ b/src/xenbus/fdo.c
@@ -3831,8 +3831,6 @@ FdoS4ToS3(
 
     LogResume();
 
-    HypercallPopulate();
-
     UnplugDevices();
 
 not_active:
diff --git a/src/xenbus/suspend.c b/src/xenbus/suspend.c
index cd292c0..687f86c 100644
--- a/src/xenbus/suspend.c
+++ b/src/xenbus/suspend.c
@@ -205,8 +205,6 @@ SuspendEarly(
     if (Cpu != 0)
         return;
 
-    HypercallPopulate();
-
     UnplugDevices();
 
     for (ListEntry = Context->EarlyList.Flink;
-- 
2.51.2.windows.1



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Fri Mar 06 11:08:25 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Fri, 06 Mar 2026 11:08:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1247619.1546169 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vyT2d-0000vB-Dt; Fri, 06 Mar 2026 11:08:23 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1247619.1546169; Fri, 06 Mar 2026 11:08:23 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vyT2d-0000v4-A5; Fri, 06 Mar 2026 11:08:23 +0000
Received: by outflank-mailman (input) for mailman id 1247619;
 Fri, 06 Mar 2026 11:08:21 +0000
Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254]
 helo=se1-gles-sth1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=kxzm=BG=citrix.com=owen.smith@srs-se1.protection.inumbo.net>)
 id 1vyT2a-0000uy-La
 for win-pv-devel@lists.xenproject.org; Fri, 06 Mar 2026 11:08:21 +0000
Received: from CH1PR05CU001.outbound.protection.outlook.com
 (mail-northcentralusazlp170100001.outbound.protection.outlook.com
 [2a01:111:f403:c105::1])
 by se1-gles-sth1.inumbo.com (Halon) with ESMTPS
 id c6fcd87e-194c-11f1-b164-2bf370ae4941;
 Fri, 06 Mar 2026 12:08:18 +0100 (CET)
Received: from SA6PR03MB7760.namprd03.prod.outlook.com (2603:10b6:806:43c::5)
 by LV3PR03MB7405.namprd03.prod.outlook.com (2603:10b6:408:19c::21)
 with Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9678.19; Fri, 6 Mar
 2026 11:08:10 +0000
Received: from SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38]) by SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38%7]) with mapi id 15.20.9678.017; Fri, 6 Mar 2026
 11:08:10 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: c6fcd87e-194c-11f1-b164-2bf370ae4941
ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;
 b=uW+PigcociUoBVAoMIPuql89W5+xpvUrLwldqh3Tzoy9mSFnnqeJx5pCZPBuJiEN1KStHoHf+76xGAMbsbPEdLSjOGWy34lUo/eq+XITBgd/hiLchQxwMtcvQAqLil2gEuLJK/b1CLXVSNPyyOdCPz27r1cndGPIUn7Ik7DfvCrdmRhTy7p2KAmU9sohdzOIgzcp9iWvcWaH1MqqqeLz7Sdm2ikUllMtRNLUwWAauWAH4tPXZQd61j+fPVNkzZB8ckr3v4q2hQt978siJw9rfDH4unkeojM3HfLnXnaNJsxrbpdGNUs5EHzWB76IXRWHr20DIHauZJz5ZwvLUIV8XQ==
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=h27oX+j62/59UzZhieek7g0UAvDr2f5vlxevLbMxFbs=;
 b=fGhKDKoCuLFM1tYiSXkTIq4JWx2hAzGJgPfSNF2ZphGRmfi2pbfBg2c9rOvYBGLeAFr0u0sXMCC5ZmMrb0dBDVbj1dqlA95NOjIDBl0odhzoFUY+E48rmORfaczKfVRmqE+6DUniSIYO/mggz/rvccEQaPeodUo/bZjGo1sf4hjZxgCQnXJIERTcYgX4HT31CgBA8LV97TaY4+9yx9f2k4KyhttwOuN3knQ0Cs2KbIVEpIDZ9uLfptBefQHnjaniziqxuz0jSaLgmd6dTuX3v26dP5Bue37AflHDoUPsMcRwhyb4LheJGrVRZRc8ecPOtQ7pMhnv+wxh2MEONtSRaA==
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
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com;
 s=selector1;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=h27oX+j62/59UzZhieek7g0UAvDr2f5vlxevLbMxFbs=;
 b=FLNV3KRk2M6LN6DMC6eGzFa14vw4kHyQpuVttepvwUT0k18jL/2EWWCbQsDnfe+aXbfk2dnej2xHkhjM6p3WDrGwMDSNk/jUBLHXBwfh5aR7iDdx5W0Nf4V1PXKmSsMalJX1zAq7/FIn79NVksNY/57NSG62ooX5LUWA+W479Ag=
From: Owen Smith <owen.smith@citrix.com>
To: Tu Dinh <ngoc-tu.dinh@vates.tech>, "win-pv-devel@lists.xenproject.org"
	<win-pv-devel@lists.xenproject.org>
Subject: Re: [PATCH v2 6/6] Remove XenDisk
Thread-Topic: [PATCH v2 6/6] Remove XenDisk
Thread-Index: AQHcq+1UFilX07E1zk60YxLDaWPHdrWhWP74
Date: Fri, 6 Mar 2026 11:08:10 +0000
Message-ID:
 <SA6PR03MB77604B7AB1918B8C02E15AB7FE7AA@SA6PR03MB7760.namprd03.prod.outlook.com>
References:
 <SA6PR03MB7760D5FA973CC19465CCAE00FE7CA@SA6PR03MB7760.namprd03.prod.outlook.com>
 <20260304154051.351-1-ngoc-tu.dinh@vates.tech>
In-Reply-To: <20260304154051.351-1-ngoc-tu.dinh@vates.tech>
Accept-Language: en-GB, en-US
Content-Language: en-GB
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
msip_labels:
authentication-results: dkim=none (message not signed)
 header.d=none;dmarc=none action=none header.from=citrix.com;
x-ms-publictraffictype: Email
x-ms-traffictypediagnostic: SA6PR03MB7760:EE_|LV3PR03MB7405:EE_
x-ms-office365-filtering-correlation-id: 9f9d1877-ac50-49f8-a064-08de7b70a704
x-ms-exchange-senderadcheck: 1
x-ms-exchange-antispam-relay: 0
x-microsoft-antispam:
 BCL:0;ARA:13230040|376014|366016|1800799024|13003099007|38070700021;
x-microsoft-antispam-message-info:
 VTx4OooG7ww3Ct22MCKKPHWWu0JEFtC5phdtBsz01CdAI83sJLKSpGP6YoClMkC+WNesac3KzSt7QS1jYs13yX+qfMWDFVA5AgYPg5o5WmWSAk5eJxZyb/ybWYEyNsjrbDW3zGmISPXHkTdP2j+9pGI7/sEzjGi/H8LAsB2ir61sIzrvsa0d6NSNXjSUm+WzBUdlNrkVuPMtobk1gjUZUBJOb73LoB9ZpVM1fHEErDG3HEgG5IkxY57+E0+Q2+CaaNBiDPhaubaqMXKFQW5lROuRy8+qLpNMvX8QyU3lgIS0k5IK5rYxPSU1RTGzhwZtF1YQLUIKY2TiCnQqifnsBibf9sFxG6NNrUlS/0zSXjHdyAHm1scg9n7miR0F8XVNWfz+gV81qawXlPYbxPqeEXt4epMTVNjt46SyDxp2a0rSUjgQp1zZKwci2f+tTBm0HIuADe+nrHFbkwrtzegowk62eimOngTCtqEkuCoJYX3+VZsGskzLSDORPXQZI0GJ/Ul7dj7X/a76HmNldZXybZ5ZaR6HAhjVqFDrwEAbis21z5oGRb6Fr/ISp7boZNd4hhagX4+p6WkNa4tL00Xbnt8WOXBWVuw6onsaGvUW6uI379f2QGbeRlVUx+3C+VGFs+ginqmgZgCrPUdy1vYBq0FrdiIcoMuxWb8vpx9bxzZxeuyVO1Tl6cBP39sl65+v8k7T8D5pnfcx1Jemp9J65ovhvhA2EPkl5Rvj0HO5JMY=
x-forefront-antispam-report:
 CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SA6PR03MB7760.namprd03.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024)(13003099007)(38070700021);DIR:OUT;SFP:1101;
x-ms-exchange-antispam-messagedata-chunkcount: 1
x-ms-exchange-antispam-messagedata-0:
 =?us-ascii?Q?doGWIhDVU834oiJZWP1nTkwCBoKlDgHA69soJN6XRxvoO/TC9UEsEwfpwgra?=
 =?us-ascii?Q?KoOIay1ZJ8H8OITZjFAlMliQpRnH1AuyNgMkrKect7Zfyf0QvBm5OGk9Hnya?=
 =?us-ascii?Q?2WpOLb4zu48yufb43suRXOuBwnrpiyDUlewwLxONAYTlzWS1LXxl0lVGbUJn?=
 =?us-ascii?Q?ouw/1CY6GYXVGTFIj2+6z+M9Iy8/68IXZZCk5M2Se22qvPsbl5t38NICH4Gd?=
 =?us-ascii?Q?hdYiGTZTh5xbq2x8/1Pp0sQgUCcnbGbVGH9yvm3CkWXEJgD3JU9jvtkfOoY+?=
 =?us-ascii?Q?VumcpeZoVSlzm0N6AKJONgjAmRKvnoC10pwUTYp7dxlZVoMdPfP/23bf8FZB?=
 =?us-ascii?Q?N54GKIRHUNWG/lFiqtPrVR/kx4rO9+GPhIYBbI5/kGvKsRzzel9yvexulP6y?=
 =?us-ascii?Q?5bpinLUQIgUdBy+iuiwDu+FFoAJRZ+bM9YClFTsVORoq29ehRhYDNfKqCMWa?=
 =?us-ascii?Q?9aBIvzm66x4xL5zMWhIEiK71B8QF/cf5JTAgHnh6FA0zPnobdT9zC6+LVmF3?=
 =?us-ascii?Q?cOlye5Byox+l59lD2cYFuY5C9m0UEE1KOJa85RDrzdoyPxSxBWFbZCjbvgAH?=
 =?us-ascii?Q?AuqC5C5iF7K3g1myYVeJkvwu2DwRJYWxSlceuLHhFBMM/jxY42CaRFRYrj6y?=
 =?us-ascii?Q?ceuvgT/qkr5bAbA5uYY13ZDalBlArZSbI7QOqq2qE6tn59kw9dqVvyLuMMLi?=
 =?us-ascii?Q?1ujftCmX4k3vaRSahC/TCDUse47hAA/8wx+X9cgFvvAStLT63MMQMBrL9ytQ?=
 =?us-ascii?Q?VQHoN5xaisRrUr6lNGk0uhE6ZZwG5WpRnKUfh4pAVDdRJi9XfLicm4MU8EA8?=
 =?us-ascii?Q?98+Z6pRo3j0tTLIbTGcTvHr9QxgrHYT3Sxw8SJQ87Bb2jN2v+E+pSD4aTkGW?=
 =?us-ascii?Q?zGkAicAelWl/SqCQGdRlgXHuR7mQ7G7HDcirCl6Px5fkIVOSdTU4/ArEvUdZ?=
 =?us-ascii?Q?OVCSc7zBaeH8fCx+TzPZs9CQlkerX/9s1VQLbFtQkAutcY0wHhfjnPLc8pbH?=
 =?us-ascii?Q?oXfrZWb9rIuKL5LIjFggGpdYKvMn38RC5rKvI1UR4eqr4ZAfTjcAu2DOqWVA?=
 =?us-ascii?Q?ZnuZTVFDyRrGLT5JRC30v5l5o71gfAXy6tsYJZ1GxXidDZYq5Y8rDvLBuwsy?=
 =?us-ascii?Q?KaLfGBTKTud/7nR8XbVGcOrcXolreI+B4dhLzhqh3iYGZUGKYglhh4y0Erzm?=
 =?us-ascii?Q?TSKdor0aX8/Pe8+Q8FzKgTdLGuQFz1EgnqWDCxcXnh69yGKZ8moNvzu4k90U?=
 =?us-ascii?Q?mIxp2LXq5M78HUoTY3taHg7NRPcKIrqw7JQwZGY5yS30fNjaSMW4aA0f9RlC?=
 =?us-ascii?Q?fs+A6Avf5AyIwfXZpyEm5qmGtzKRHlrhtSxuv8qQbPpAGG0P8n92pDQxqDQZ?=
 =?us-ascii?Q?ut2kL6lkIF1PFnMn0DyozpuEA19Tnw44dvEnu3L1xMJ4PjZIAXWjXhQ4CsgP?=
 =?us-ascii?Q?yS7x0ujaqVvBj2W0ExQKPzK3hJ3sxECnXO5Khlf8ZEt++5Scuj35ceiPjoWA?=
 =?us-ascii?Q?d63JFr6CUWUIbiXTfu5LQS+gabQMWT/L6rOMi7+7FeoQ5Dcqb3w/VyIynUAC?=
 =?us-ascii?Q?lF+HlbNFATwfR+4MmKFdAN5UONuwdvgmMImWZ7JjeVVtFc5BapVAjXuiUhDk?=
 =?us-ascii?Q?MIKlfDFQZxEWEzTXzxzKlU6MQIWT+g82JLpIC/MRLD0gL3tIEc/6ftVu790y?=
 =?us-ascii?Q?m7Goy8stgsBql7qDhcsxPhK1P7xb1VdNUuRf3W7gaFpoIdbL?=
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
X-OriginatorOrg: citrix.com
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-AuthSource: SA6PR03MB7760.namprd03.prod.outlook.com
X-MS-Exchange-CrossTenant-Network-Message-Id: 9f9d1877-ac50-49f8-a064-08de7b70a704
X-MS-Exchange-CrossTenant-originalarrivaltime: 06 Mar 2026 11:08:10.1777
 (UTC)
X-MS-Exchange-CrossTenant-fromentityheader: Hosted
X-MS-Exchange-CrossTenant-id: 335836de-42ef-43a2-b145-348c2ee9ca5b
X-MS-Exchange-CrossTenant-mailboxtype: HOSTED
X-MS-Exchange-CrossTenant-userprincipalname: E9KZwlXaz3bspVXQCQjIfO8fHa24k3Tn4jvamlf0mhJh7KXAQWw1ssBCbh9T+FZKFpAm/qdyg53WWOaMgo960g==
X-MS-Exchange-Transport-CrossTenantHeadersStamped: LV3PR03MB7405

This patch on top of your others in this series, and the 3 from mine look g=
ood.

(applied my patches)
"v2 Refactor Features and DiskInfo",
"v2 Consolidate macro'ed access..."
"v2 Use NT Safe String printf..." (unrelated to later changes)

(applied your patches)
"Stop inlining the VPD page list..."
"Stop inlining the VPD page codes"
"Report max unmap LBA and..."
"Report VPD 0xB2 Logical Block..."
"Check Service Action when..."
"v2 Remove XenDisk"

This combination look to function well. We may want to consider overrides
or tuning for the "always report unmap support" and "max unmap blocks",
but this can be looked at later, if needed.

Reviewed-by: Owen Smith <owen.smith@citrix.com>


________________________________________
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
Sent: 04 March 2026 3:41 PM
To: win-pv-devel@lists.xenproject.org
Cc: Owen Smith; Tu Dinh
Subject: [PATCH v2 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@vates.tech>
---
@Owen: I've rebased this on top of "[PATCH 2/4 v2] Refactor Features and
DiskInfo" and "[PATCH 3/4 v2] Consolidate macro'ed access to properties",
without the "XenDisk: Report Discard support by issuing an Inquiry"
patch.
---
 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                   | 1920 ---------------------------
 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                      |   22 -
 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 -
 25 files changed, 1 insertion(+), 6902 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 =3D "xenvbd.sln"
 $ArchivePath =3D "xenvbd"
-$ProjectList =3D @( "xencrsh", "xendisk", "xenvbd" )
+$ProjectList =3D @( "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 =3D (_TEXT);                       \
-            const CHAR  *_File =3D __FILE__;                      \
-            ULONG       _Line =3D __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 =3D (_TEXT1);                     \
-            const CHAR  *_Text2 =3D (_TEXT2);                     \
-            const CHAR  *_File =3D __FILE__;                      \
-            ULONG       _Line =3D __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 =3D (ULONGLONG)(_X);    \
-            ULONGLONG   _Rval =3D (ULONGLONG)(_Y);    \
-            if (!(_Lval _OP _Rval)) {               \
-                Error("%s =3D %llu\n", #_X, _Lval);   \
-                Error("%s =3D %llu\n", #_Y, _Rval);   \
-                ASSERT(_X _OP _Y);                  \
-            }                                       \
-        } while (FALSE)
-
-#define ASSERT3S(_X, _OP, _Y)                       \
-        do {                                        \
-            LONGLONG    _Lval =3D (LONGLONG)(_X);     \
-            LONGLONG    _Rval =3D (LONGLONG)(_Y);     \
-            if (!(_Lval _OP _Rval)) {               \
-                Error("%s =3D %lld\n", #_X, _Lval);   \
-                Error("%s =3D %lld\n", #_Y, _Rval);   \
-                ASSERT(_X _OP _Y);                  \
-            }                                       \
-        } while (FALSE)
-
-#define ASSERT3P(_X, _OP, _Y)                       \
-        do {                                        \
-            PVOID   _Lval =3D (PVOID)(_X);            \
-            PVOID   _Rval =3D (PVOID)(_Y);            \
-            if (!(_Lval _OP _Rval)) {               \
-                Error("%s =3D %p\n", #_X, _Lval);     \
-                Error("%s =3D %p\n", #_Y, _Rval);     \
-                ASSERT(_X _OP _Y);                  \
-            }                                       \
-        } while (FALSE)
-
-#define ASSERTREFCOUNT(_X, _OP, _Y, _Z)             \
-        do {                                        \
-            LONG    _L =3D (LONG)(_X);                \
-            LONG    _R =3D (LONG)(_Y);                \
-            if (!(_L _OP _R)) {                     \
-                Error("%s:%s =3D %d\n", (_Z), #_X, _L); \
-                Error("%s:%s =3D %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 =3D 0;
-    while (Offset < Length) {
-        if (*((PUCHAR)Buffer + Offset) !=3D 0) {
-            Error("%s: non-zero byte in %s (0x%p+0x%x)\n", Caller, Name, B=
uffer, 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 =3D 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 =3D 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, =3D=3D, __DriverGetDriverObject());
-
-    Trace("=3D=3D=3D=3D>\n");
-
-    ParametersKey =3D __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("<=3D=3D=3D=3D\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, =3D=3D, __DriverGetDriverObject());
-
-    status =3D 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 =3D (PXENDISK_DX)DeviceObject->DeviceExtension;
-    ASSERT3P(Dx->DeviceObject, =3D=3D, DeviceObject);
-
-    if (Dx->DevicePnpState =3D=3D Deleted) {
-        PIO_STACK_LOCATION  StackLocation =3D IoGetCurrentIrpStackLocation=
(Irp);
-        UCHAR               MajorFunction =3D StackLocation->MajorFunction=
;
-        UCHAR               MinorFunction =3D StackLocation->MinorFunction=
;
-
-        status =3D STATUS_NO_SUCH_DEVICE;
-
-        if (MajorFunction =3D=3D IRP_MJ_PNP) {
-            /* FDO and PDO deletions can block after being marked deleted,=
 but before IoDeleteDevice */
-            if (MinorFunction =3D=3D IRP_MN_SURPRISE_REMOVAL || MinorFunct=
ion =3D=3D IRP_MN_REMOVE_DEVICE)
-                status =3D STATUS_SUCCESS;
-
-            ASSERT((MinorFunction !=3D IRP_MN_CANCEL_REMOVE_DEVICE) && (Mi=
norFunction !=3D IRP_MN_CANCEL_STOP_DEVICE));
-        }
-
-        Irp->IoStatus.Status =3D status;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
-        goto done;
-    }
-
-    status =3D STATUS_NOT_SUPPORTED;
-    switch (Dx->Type) {
-    case PHYSICAL_DEVICE_OBJECT: {
-        PXENDISK_PDO    Pdo =3D Dx->Pdo;
-
-        status =3D PdoDispatch(Pdo, Irp);
-        break;
-    }
-    case FUNCTION_DEVICE_OBJECT: {
-        PXENDISK_FDO    Fdo =3D Dx->Fdo;
-
-        status =3D 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(), =3D=3D, NULL);
-    UNREFERENCED_PARAMETER(RegistryPath);
-
-    ExInitializeDriverRuntime(DrvRtPoolNxOptIn);
-
-    Trace("=3D=3D=3D=3D>\n");
-
-    __DriverSetDriverObject(DriverObject);
-
-    DriverObject->DriverUnload =3D DriverUnload;
-
-    Verbose("XENDISK %d.%d.%d (%d) (%02d.%02d.%04d)\n",
-            MAJOR_VERSION,
-            MINOR_VERSION,
-            MICRO_VERSION,
-            BUILD_NUMBER,
-            DAY,
-            MONTH,
-            YEAR);
-
-    status =3D RegistryInitialize(DriverObject, RegistryPath);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status =3D RegistryOpenParametersKey(KEY_READ, &ParametersKey);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    __DriverSetParametersKey(ParametersKey);
-
-    DriverObject->DriverExtension->AddDevice =3D AddDevice;
-
-    for (Index =3D 0; Index <=3D IRP_MJ_MAXIMUM_FUNCTION; Index++) {
-#pragma prefast(suppress:28169) // No __drv_dispatchType annotation
-#pragma prefast(suppress:28168) // No matching __drv_dispatchType annotati=
on for IRP_MJ_CREATE
-        DriverObject->MajorFunction[Index] =3D Dispatch;
-    }
-
-    Trace("<=3D=3D=3D=3D\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 str=
uct/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 =3D Fdo->Dx;
-
-    // We can never transition out of the deleted state
-    ASSERT(Dx->DevicePnpState !=3D Deleted || State =3D=3D Deleted);
-
-    Dx->PreviousDevicePnpState =3D Dx->DevicePnpState;
-    Dx->DevicePnpState =3D State;
-}
-
-static FORCEINLINE VOID
-__FdoRestoreDevicePnpState(
-    IN  PXENDISK_FDO        Fdo,
-    IN  DEVICE_PNP_STATE    State
-    )
-{
-    PXENDISK_DX             Dx =3D Fdo->Dx;
-
-    if (Dx->DevicePnpState =3D=3D State)
-        Dx->DevicePnpState =3D Dx->PreviousDevicePnpState;
-}
-
-static FORCEINLINE DEVICE_PNP_STATE
-__FdoGetDevicePnpState(
-    IN  PXENDISK_FDO    Fdo
-    )
-{
-    PXENDISK_DX         Dx =3D Fdo->Dx;
-
-    return Dx->DevicePnpState;
-}
-
-static FORCEINLINE VOID
-__FdoSetDevicePowerState(
-    IN  PXENDISK_FDO        Fdo,
-    IN  DEVICE_POWER_STATE  State
-    )
-{
-    PXENDISK_DX             Dx =3D Fdo->Dx;
-
-    Dx->DevicePowerState =3D State;
-}
-
-static FORCEINLINE DEVICE_POWER_STATE
-__FdoGetDevicePowerState(
-    IN  PXENDISK_FDO    Fdo
-    )
-{
-    PXENDISK_DX         Dx =3D Fdo->Dx;
-
-    return Dx->DevicePowerState;
-}
-
-static FORCEINLINE VOID
-__FdoSetSystemPowerState(
-    IN  PXENDISK_FDO        Fdo,
-    IN  SYSTEM_POWER_STATE  State
-    )
-{
-    PXENDISK_DX              Dx =3D Fdo->Dx;
-
-    Dx->SystemPowerState =3D State;
-}
-
-static FORCEINLINE SYSTEM_POWER_STATE
-__FdoGetSystemPowerState(
-    IN  PXENDISK_FDO    Fdo
-    )
-{
-    PXENDISK_DX         Dx =3D 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 =3D (PXENDISK_DX)DeviceObject->DeviceExtension;
-    ASSERT3U(Dx->Type, =3D=3D, PHYSICAL_DEVICE_OBJECT);
-
-    InsertTailList(&Fdo->Dx->ListEntry, &Dx->ListEntry);
-    ASSERT3U(Fdo->References, !=3D, 0);
-    Fdo->References++;
-}
-
-VOID
-FdoRemovePhysicalDeviceObject(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PDEVICE_OBJECT  DeviceObject
-    )
-{
-    PXENDISK_DX         Dx;
-
-    Dx =3D (PXENDISK_DX)DeviceObject->DeviceExtension;
-    ASSERT3U(Dx->Type, =3D=3D, PHYSICAL_DEVICE_OBJECT);
-
-    RemoveEntryList(&Dx->ListEntry);
-    ASSERT3U(Fdo->References, !=3D, 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 =3D=3D 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 =3D 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(), =3D=3D, PASSIVE_LEVEL);
-
-    Irp =3D IoAllocateIrp(DeviceObject->StackSize, FALSE);
-
-    status =3D STATUS_INSUFFICIENT_RESOURCES;
-    if (Irp =3D=3D NULL)
-        goto fail1;
-
-    StackLocation =3D IoGetNextIrpStackLocation(Irp);
-
-    StackLocation->MajorFunction =3D IRP_MJ_PNP;
-    StackLocation->MinorFunction =3D IRP_MN_QUERY_ID;
-    StackLocation->Flags =3D 0;
-    StackLocation->Parameters.QueryId.IdType =3D Type;
-    StackLocation->DeviceObject =3D DeviceObject;
-    StackLocation->FileObject =3D NULL;
-
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
-    IoSetCompletionRoutine(Irp,
-                           FdoQueryIdCompletion,
-                           &Event,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    // Default completion status
-    Irp->IoStatus.Status =3D STATUS_NOT_SUPPORTED;
-
-    status =3D IoCallDriver(DeviceObject, Irp);
-    if (status =3D=3D STATUS_PENDING) {
-        (VOID) KeWaitForSingleObject(&Event,
-                                     Executive,
-                                     KernelMode,
-                                     FALSE,
-                                     NULL);
-        status =3D Irp->IoStatus.Status;
-    } else {
-        ASSERT3U(status, =3D=3D, Irp->IoStatus.Status);
-    }
-
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status =3D 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 =3D FdoQueryId(Fdo,
-                        PhysicalDeviceObject,
-                        BusQueryDeviceID,
-                        DeviceID);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status =3D FdoQueryId(Fdo,
-                        PhysicalDeviceObject,
-                        BusQueryInstanceID,
-                        InstanceID);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status =3D 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 =3D Relations->Count;
-    ASSERT(Count !=3D 0);
-
-    PhysicalDeviceObject =3D __FdoAllocate(sizeof (PDEVICE_OBJECT) * Count=
);
-
-    status =3D STATUS_NO_MEMORY;
-    if (PhysicalDeviceObject =3D=3D NULL)
-        goto fail1;
-
-    RtlCopyMemory(PhysicalDeviceObject,
-                  Relations->Objects,
-                  sizeof (PDEVICE_OBJECT) * Count);
-
-    // Remove any PDOs that do not appear in the device list
-    ListEntry =3D Fdo->Dx->ListEntry.Flink;
-    while (ListEntry !=3D &Fdo->Dx->ListEntry) {
-        PLIST_ENTRY     Next =3D ListEntry->Flink;
-        PXENDISK_DX     Dx =3D CONTAINING_RECORD(ListEntry, XENDISK_DX, Li=
stEntry);
-        PXENDISK_PDO    Pdo =3D Dx->Pdo;
-
-        for (Index =3D 0; Index < Count; Index++) {
-            if (PdoGetPhysicalDeviceObject(Pdo) =3D=3D PhysicalDeviceObjec=
t[Index]) {
-#pragma prefast(suppress:6387)  // PhysicalDeviceObject[Index] could be NU=
LL
-                PhysicalDeviceObject[Index] =3D NULL; // avoid duplication
-                break;
-            }
-        }
-
-        ListEntry =3D Next;
-    }
-
-    // Walk the list and create PDO filters for any new devices
-    for (Index =3D 0; Index < Count; Index++) {
-#pragma warning(suppress:6385)  // Reading invalid data from 'PhysicalDevi=
ceObject'
-        if (PhysicalDeviceObject[Index] !=3D 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 =3D 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(), =3D=3D, PASSIVE_LEVEL);
-
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoForwardIrpSynchronously,
-                           &Event,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-    if (status =3D=3D STATUS_PENDING) {
-        (VOID) KeWaitForSingleObject(&Event,
-                                     Executive,
-                                     KernelMode,
-                                     FALSE,
-                                     NULL);
-        status =3D Irp->IoStatus.Status;
-    } else {
-        ASSERT3U(status, =3D=3D, Irp->IoStatus.Status);
-    }
-
-    return status;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-FdoStartDevice(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    POWER_STATE         PowerState;
-    NTSTATUS            status;
-
-    status =3D IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status =3D FdoForwardIrpSynchronously(Fdo, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    __FdoSetSystemPowerState(Fdo, PowerSystemWorking);
-    __FdoSetDevicePowerState(Fdo, PowerDeviceD0);
-
-    PowerState.DeviceState =3D 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 =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    __FdoSetDevicePnpState(Fdo, StopPending);
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoQueryStopDevice,
-                           Fdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-
-    __FdoRestoreDevicePnpState(Fdo, StopPending);
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoCancelStopDevice,
-                           Fdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    if (__FdoGetDevicePowerState(Fdo) !=3D PowerDeviceD0)
-        goto done;
-
-    PowerState.DeviceState =3D PowerDeviceD3;
-    PoSetPowerState(Fdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
-
-    __FdoSetDevicePowerState(Fdo, PowerDeviceD3);
-    __FdoSetSystemPowerState(Fdo, PowerSystemShutdown);
-
-done:
-    __FdoSetDevicePnpState(Fdo, Stopped);
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoStopDevice,
-                           Fdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    __FdoSetDevicePnpState(Fdo, RemovePending);
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoQueryRemoveDevice,
-                           Fdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    __FdoRestoreDevicePnpState(Fdo, RemovePending);
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoCancelRemoveDevice,
-                           Fdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    __FdoSetDevicePnpState(Fdo, SurpriseRemovePending);
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoSurpriseRemoval,
-                           Fdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    if (__FdoGetDevicePowerState(Fdo) !=3D PowerDeviceD0)
-        goto done;
-
-    PowerState.DeviceState =3D PowerDeviceD3;
-    PoSetPowerState(Fdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
-
-    __FdoSetDevicePowerState(Fdo, PowerDeviceD3);
-    __FdoSetSystemPowerState(Fdo, PowerSystemShutdown);
-
-done:
-    __FdoSetDevicePnpState(Fdo, Deleted);
-
-    IoReleaseRemoveLockAndWait(&Fdo->Dx->RemoveLock, Irp);
-
-    status =3D FdoForwardIrpSynchronously(Fdo, Irp);
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    __FdoAcquireMutex(Fdo);
-    ASSERT3U(Fdo->References, !=3D, 0);
-    --Fdo->References;
-    __FdoReleaseMutex(Fdo);
-
-    if (Fdo->References =3D=3D 0)
-        FdoDestroy(Fdo);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D 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 =3D 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 =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-    if (status =3D=3D STATUS_PENDING) {
-        (VOID) KeWaitForSingleObject(&Event,
-                                     Executive,
-                                     KernelMode,
-                                     FALSE,
-                                     NULL);
-        status =3D Irp->IoStatus.Status;
-    } else {
-        ASSERT3U(status, =3D=3D, Irp->IoStatus.Status);
-    }
-
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    StackLocation =3D IoGetCurrentIrpStackLocation(Irp);
-    if (StackLocation->Parameters.QueryDeviceRelations.Type !=3D BusRelati=
ons)
-        goto done;
-
-    Relations =3D (PDEVICE_RELATIONS)Irp->IoStatus.Information;
-
-    __FdoAcquireMutex(Fdo);
-
-    if (Relations->Count !=3D 0)
-        __FdoEnumerate(Fdo, Relations);
-
-    for (ListEntry =3D Fdo->Dx->ListEntry.Flink;
-         ListEntry !=3D &Fdo->Dx->ListEntry;
-         ListEntry =3D ListEntry->Flink) {
-        PXENDISK_DX     Dx =3D CONTAINING_RECORD(ListEntry, XENDISK_DX, Li=
stEntry);
-        PXENDISK_PDO    Pdo =3D Dx->Pdo;
-
-        ASSERT3U(Dx->Type, =3D=3D, PHYSICAL_DEVICE_OBJECT);
-
-        if (PdoGetDevicePnpState(Pdo) =3D=3D Present)
-            PdoSetDevicePnpState(Pdo, Enumerated);
-    }
-
-    __FdoReleaseMutex(Fdo);
-
-    Trace("%d PDO(s)\n", Relations->Count);
-
-    status =3D STATUS_SUCCESS;
-
-done:
-    IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-
-    Irp->IoStatus.Status =3D status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-
-fail2:
-    IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-    MinorFunction =3D StackLocation->MinorFunction;
-
-    switch (StackLocation->MinorFunction) {
-    case IRP_MN_START_DEVICE:
-        status =3D FdoStartDevice(Fdo, Irp);
-        break;
-
-    case IRP_MN_QUERY_STOP_DEVICE:
-        status =3D FdoQueryStopDevice(Fdo, Irp);
-        break;
-
-    case IRP_MN_CANCEL_STOP_DEVICE:
-        status =3D FdoCancelStopDevice(Fdo, Irp);
-        break;
-
-    case IRP_MN_STOP_DEVICE:
-        status =3D FdoStopDevice(Fdo, Irp);
-        break;
-
-    case IRP_MN_QUERY_REMOVE_DEVICE:
-        status =3D FdoQueryRemoveDevice(Fdo, Irp);
-        break;
-
-    case IRP_MN_SURPRISE_REMOVAL:
-        status =3D FdoSurpriseRemoval(Fdo, Irp);
-        break;
-
-    case IRP_MN_REMOVE_DEVICE:
-        status =3D FdoRemoveDevice(Fdo, Irp);
-        break;
-
-    case IRP_MN_CANCEL_REMOVE_DEVICE:
-        status =3D FdoCancelRemoveDevice(Fdo, Irp);
-        break;
-
-    case IRP_MN_QUERY_DEVICE_RELATIONS:
-        status =3D FdoQueryDeviceRelations(Fdo, Irp);
-        break;
-
-    default:
-        status =3D IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-        if (!NT_SUCCESS(status))
-            goto fail1;
-
-        IoCopyCurrentIrpStackLocationToNext(Irp);
-        IoSetCompletionRoutine(Irp,
-                               __FdoDispatchPnp,
-                               Fdo,
-                               TRUE,
-                               TRUE,
-                               TRUE);
-
-        status =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-        break;
-    }
-
-    return status;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    Irp->IoStatus.Status =3D 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 =3D (PXENDISK_FDO) Context;
-    PIO_STACK_LOCATION  StackLocation;
-    POWER_STATE         PowerState;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    StackLocation =3D IoGetCurrentIrpStackLocation(Irp);
-    PowerState =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-    PowerState =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-    DeviceState =3D StackLocation->Parameters.Power.State.DeviceState;
-    PowerAction =3D StackLocation->Parameters.Power.ShutdownType;
-
-    Trace("=3D=3D=3D=3D> (%s:%s)\n",
-          PowerDeviceStateName(DeviceState),
-          PowerActionName(PowerAction));
-
-    if (DeviceState =3D=3D __FdoGetDevicePowerState(Fdo)) {
-        IoSkipCurrentIrpStackLocation(Irp);
-        status =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-        goto done;
-    }
-
-    status =3D (DeviceState < __FdoGetDevicePowerState(Fdo)) ?
-             __FdoSetDevicePowerUp(Fdo, Irp) :
-             __FdoSetDevicePowerDown(Fdo, Irp);
-
-done:
-    Trace("<=3D=3D=3D=3D (%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 =3D (PXENDISK_FDO) Context;
-    PIO_STACK_LOCATION  StackLocation;
-    SYSTEM_POWER_STATE  SystemState;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    StackLocation =3D IoGetCurrentIrpStackLocation(Irp);
-    SystemState =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-    SystemState =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-    SystemState =3D StackLocation->Parameters.Power.State.SystemState;
-    PowerAction =3D StackLocation->Parameters.Power.ShutdownType;
-
-    Trace("=3D=3D=3D=3D> (%s:%s)\n",
-          PowerSystemStateName(SystemState),
-          PowerActionName(PowerAction));
-
-    if (SystemState =3D=3D __FdoGetSystemPowerState(Fdo)) {
-        IoSkipCurrentIrpStackLocation(Irp);
-        status =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-        goto done;
-    }
-
-    status =3D (SystemState < __FdoGetSystemPowerState(Fdo)) ?
-             __FdoSetSystemPowerUp(Fdo, Irp) :
-             __FdoSetSystemPowerDown(Fdo, Irp);
-
-done:
-    Trace("<=3D=3D=3D=3D (%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 =3D IoGetCurrentIrpStackLocation(Irp);
-
-    switch (StackLocation->MinorFunction) {
-    case IRP_MN_SET_POWER:
-        status =3D __FdoSetDevicePower(Fdo, Irp);
-        break;
-
-    default:
-        IoSkipCurrentIrpStackLocation(Irp);
-        status =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-        break;
-    }
-
-    return status;
-}
-
-static NTSTATUS
-FdoSystemPower(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    NTSTATUS            status;
-
-    StackLocation =3D IoGetCurrentIrpStackLocation(Irp);
-
-    switch (StackLocation->MinorFunction) {
-    case IRP_MN_SET_POWER:
-        status =3D __FdoSetSystemPower(Fdo, Irp);
-        break;
-
-    default:
-        IoSkipCurrentIrpStackLocation(Irp);
-        status =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-    PowerType =3D StackLocation->Parameters.Power.Type;
-
-    switch (PowerType) {
-    case DevicePowerState:
-        status =3D FdoDevicePower(Fdo, Irp);
-        break;
-
-    case SystemPowerState:
-        status =3D FdoSystemPower(Fdo, Irp);
-        break;
-
-    default:
-        IoSkipCurrentIrpStackLocation(Irp);
-        status =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __FdoDispatchDefault,
-                           Fdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    Irp->IoStatus.Status =3D status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-NTSTATUS
-FdoDispatch(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    NTSTATUS            status;
-
-    StackLocation =3D IoGetCurrentIrpStackLocation(Irp);
-
-    switch (StackLocation->MajorFunction) {
-    case IRP_MJ_PNP:
-        status =3D FdoDispatchPnp(Fdo, Irp);
-        break;
-
-    case IRP_MJ_POWER:
-        status =3D FdoDispatchPower(Fdo, Irp);
-        break;
-
-    default:
-        status =3D 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 =3D IoGetAttachedDeviceReference(PhysicalDeviceObjec=
t);
-    DeviceType =3D LowerDeviceObject->DeviceType;
-    ObDereferenceObject(LowerDeviceObject);
-
-#pragma prefast(suppress:28197) // Possibly leaking memory 'FilterDeviceOb=
ject'
-    status =3D IoCreateDevice(DriverGetDriverObject(),
-                            sizeof (XENDISK_DX),
-                            NULL,
-                            DeviceType,
-                            FILE_DEVICE_SECURE_OPEN,
-                            FALSE,
-                            &FilterDeviceObject);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    Dx =3D (PXENDISK_DX)FilterDeviceObject->DeviceExtension;
-    RtlZeroMemory(Dx, sizeof (XENDISK_DX));
-
-    Dx->Type =3D FUNCTION_DEVICE_OBJECT;
-    Dx->DeviceObject =3D FilterDeviceObject;
-    Dx->DevicePnpState =3D Added;
-    Dx->SystemPowerState =3D PowerSystemShutdown;
-    Dx->DevicePowerState =3D PowerDeviceD3;
-
-    IoInitializeRemoveLock(&Dx->RemoveLock, FDO_TAG, 0, 0);
-
-    Fdo =3D __FdoAllocate(sizeof (XENDISK_FDO));
-
-    status =3D STATUS_NO_MEMORY;
-    if (Fdo =3D=3D NULL)
-        goto fail2;
-
-    LowerDeviceObject =3D IoAttachDeviceToDeviceStack(FilterDeviceObject,
-                                                    PhysicalDeviceObject);
-
-    status =3D STATUS_UNSUCCESSFUL;
-    if (LowerDeviceObject =3D=3D NULL)
-        goto fail3;
-
-    Fdo->Dx =3D Dx;
-    Fdo->PhysicalDeviceObject =3D PhysicalDeviceObject;
-    Fdo->LowerDeviceObject =3D LowerDeviceObject;
-
-    InitializeMutex(&Fdo->Mutex);
-    InitializeListHead(&Dx->ListEntry);
-    Fdo->References =3D 1;
-
-    Verbose("%p\n", FilterDeviceObject);
-
-    Dx->Fdo =3D Fdo;
-
-#pragma prefast(suppress:28182)  // Dereferencing NULL pointer
-    FilterDeviceObject->DeviceType =3D LowerDeviceObject->DeviceType;
-    FilterDeviceObject->Characteristics =3D LowerDeviceObject->Characteris=
tics;
-
-    FilterDeviceObject->Flags |=3D LowerDeviceObject->Flags;
-    FilterDeviceObject->Flags &=3D ~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 =3D Fdo->LowerDeviceObject;
-    PXENDISK_DX         Dx =3D Fdo->Dx;
-    PDEVICE_OBJECT      FilterDeviceObject =3D Dx->DeviceObject;
-
-    ASSERT(IsListEmpty(&Dx->ListEntry));
-    ASSERT3U(Fdo->References, =3D=3D, 0);
-    ASSERT3U(__FdoGetDevicePnpState(Fdo), =3D=3D, Deleted);
-
-    Dx->Fdo =3D NULL;
-
-    RtlZeroMemory(&Fdo->Mutex, sizeof (MUTEX));
-
-    Fdo->LowerDeviceObject =3D NULL;
-    Fdo->PhysicalDeviceObject =3D NULL;
-    Fdo->Dx =3D 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 =3D 0;
-
-    status =3D KeWaitForSingleObject(&Mutex->Event,
-                                   Executive,
-                                   KernelMode,
-                                   FALSE,
-                                   &Timeout);
-    if (status =3D=3D STATUS_TIMEOUT)
-        return FALSE;
-
-    ASSERT(NT_SUCCESS(status));
-
-    ASSERT3P(Mutex->Owner, =3D=3D, NULL);
-    Mutex->Owner =3D KeGetCurrentThread();
-
-    return TRUE;
-}
-
-static FORCEINLINE VOID
-__drv_maxIRQL(PASSIVE_LEVEL)
-AcquireMutex(
-    IN  PMUTEX  Mutex
-    )
-{
-    NTSTATUS    status;
-
-    status =3D KeWaitForSingleObject(&Mutex->Event,
-                                   Executive,
-                                   KernelMode,
-                                   FALSE,
-                                   NULL);
-
-    ASSERT(NT_SUCCESS(status));
-
-    ASSERT3P(Mutex->Owner, =3D=3D, NULL);
-    Mutex->Owner =3D KeGetCurrentThread();
-}
-
-static FORCEINLINE VOID
-__drv_maxIRQL(PASSIVE_LEVEL)
-ReleaseMutex(
-    IN  PMUTEX  Mutex
-    )
-{
-    ASSERT3P(Mutex->Owner, =3D=3D, KeGetCurrentThread());
-    Mutex->Owner =3D 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 f714efb..0000000
--- a/src/xendisk/pdo.c
+++ /dev/null
@@ -1,1920 +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;
-    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 =3D Pdo->Dx;
-
-    // We can never transition out of the deleted state
-    ASSERT(Dx->DevicePnpState !=3D Deleted || State =3D=3D Deleted);
-
-    Dx->PreviousDevicePnpState =3D Dx->DevicePnpState;
-    Dx->DevicePnpState =3D 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 =3D Pdo->Dx;
-
-    if (Dx->DevicePnpState =3D=3D State)
-        Dx->DevicePnpState =3D Dx->PreviousDevicePnpState;
-}
-
-static FORCEINLINE DEVICE_PNP_STATE
-__PdoGetDevicePnpState(
-    IN  PXENDISK_PDO    Pdo
-    )
-{
-    PXENDISK_DX         Dx =3D 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 =3D Pdo->Dx;
-
-    Dx->DevicePowerState =3D State;
-}
-
-static FORCEINLINE DEVICE_POWER_STATE
-__PdoGetDevicePowerState(
-    IN  PXENDISK_PDO    Pdo
-    )
-{
-    PXENDISK_DX         Dx =3D Pdo->Dx;
-
-    return Dx->DevicePowerState;
-}
-
-static FORCEINLINE VOID
-__PdoSetSystemPowerState(
-    IN  PXENDISK_PDO        Pdo,
-    IN  SYSTEM_POWER_STATE  State
-    )
-{
-    PXENDISK_DX             Dx =3D Pdo->Dx;
-
-    Dx->SystemPowerState =3D State;
-}
-
-static FORCEINLINE SYSTEM_POWER_STATE
-__PdoGetSystemPowerState(
-    IN  PXENDISK_PDO    Pdo
-    )
-{
-    PXENDISK_DX         Dx =3D 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 =3D Fdo;
-    FdoAddPhysicalDeviceObject(Fdo, Pdo->Dx->DeviceObject);
-}
-
-static FORCEINLINE VOID
-__PdoUnlink(
-    IN  PXENDISK_PDO    Pdo
-    )
-{
-    PXENDISK_FDO        Fdo =3D Pdo->Fdo;
-
-    ASSERT(Fdo !=3D NULL);
-
-    FdoRemovePhysicalDeviceObject(Fdo, Pdo->Dx->DeviceObject);
-
-    Pdo->Fdo =3D 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 =3D 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 =3D 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(), =3D=3D, PASSIVE_LEVEL);
-
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __PdoForwardIrpSynchronously,
-                           &Event,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-    if (status =3D=3D STATUS_PENDING) {
-        (VOID) KeWaitForSingleObject(&Event,
-                                     Executive,
-                                     KernelMode,
-                                     FALSE,
-                                     NULL);
-        status =3D Irp->IoStatus.Status;
-    } else {
-        ASSERT3U(status, =3D=3D, 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 =3D 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 =3D 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) =3D 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 =3D STATUS_NO_MEMORY;
-    Irp =3D IoAllocateIrp((CCHAR)(Pdo->LowerDeviceObject->StackSize + 1), =
FALSE);
-    if (Irp =3D=3D NULL)
-        goto fail1;
-
-    Stack =3D IoGetNextIrpStackLocation(Irp);
-    Stack->MajorFunction =3D IRP_MJ_SCSI;
-    Stack->Parameters.Scsi.Srb =3D Srb;
-
-    IoSetCompletionRoutine(Irp,
-                            __PdoSendAwaitSrb,
-                            Srb,
-                            TRUE,
-                            TRUE,
-                            TRUE);
-    Irp->UserIosb =3D &IoStatus;
-    Irp->UserEvent =3D &Event;
-
-    Irp->MdlAddress =3D IoAllocateMdl(Srb->DataBuffer,
-                                    Srb->DataTransferLength,
-                                    FALSE,
-                                    FALSE,
-                                    Irp);
-    if (Irp->MdlAddress =3D=3D NULL)
-        goto fail2;
-
-#pragma warning(disable:6320)
-    try {
-        MmProbeAndLockPages(Irp->MdlAddress, KernelMode, IoWriteAccess);
-    } except (EXCEPTION_EXECUTE_HANDLER) {
-        status =3D GetExceptionCode();
-
-        goto fail3;
-    }
-#pragma warning(default:6320)
-
-    Srb->OriginalRequest =3D Irp;
-
-    status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-    if (status =3D=3D STATUS_PENDING) {
-        (VOID) KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE,=
 NULL);
-        status =3D 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("=3D=3D=3D=3D>\n");
-
-    Length =3D sizeof(READ_CAPACITY16_DATA);
-
-    status =3D STATUS_NO_MEMORY;
-    Capacity =3D __PdoAllocate(Length);
-    if (Capacity =3D=3D NULL)
-        goto fail1;
-
-    RtlZeroMemory(&Srb, sizeof(SCSI_REQUEST_BLOCK));
-    Srb.Length =3D sizeof(SCSI_REQUEST_BLOCK);
-    Srb.SrbFlags =3D 0;
-    Srb.Function =3D SRB_FUNCTION_EXECUTE_SCSI;
-    Srb.DataBuffer =3D Capacity;
-    Srb.DataTransferLength =3D Length;
-    Srb.TimeOutValue =3D (ULONG)-1;
-    Srb.CdbLength =3D 16;
-
-    Cdb =3D (PCDB)&Srb.Cdb[0];
-    Cdb->READ_CAPACITY16.OperationCode =3D SCSIOP_READ_CAPACITY16;
-    Cdb->READ_CAPACITY16.ServiceAction =3D SERVICE_ACTION_READ_CAPACITY16;
-    *(PULONG)Cdb->READ_CAPACITY16.AllocationLength =3D _byteswap_ulong(Len=
gth);
-
-    status =3D PdoSendAwaitSrb(Pdo, &Srb);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status =3D STATUS_UNSUCCESSFUL;
-    if (Srb.DataTransferLength < Length)
-        goto fail3;
-
-    *SectorSize =3D _byteswap_ulong(Capacity->BytesPerBlock);
-    *PhysSectorSize =3D *SectorSize << Capacity->LogicalPerPhysicalExponen=
t;
-    *SectorCount =3D _byteswap_uint64(Capacity->LogicalBlockAddress.QuadPa=
rt) + 1;
-
-    __PdoFree(Capacity);
-
-    Trace("<=3D=3D=3D=3D\n");
-    return STATUS_SUCCESS;
-
-fail3:
-    Error("fail3\n");
-
-fail2:
-    Error("fail2\n");
-
-    __PdoFree(Capacity);
-
-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 =3D sizeof(UNMAP_LIST_HEADER) +
-             (Count * sizeof(UNMAP_BLOCK_DESCRIPTOR));
-
-    status =3D STATUS_NO_MEMORY;
-    Unmap =3D __PdoAllocate(Length);
-    if (Unmap =3D=3D NULL)
-        goto fail1;
-
-    RtlZeroMemory(&Srb, sizeof(SCSI_REQUEST_BLOCK));
-    Srb.Length =3D sizeof(SCSI_REQUEST_BLOCK);
-    Srb.SrbFlags =3D 0;
-    Srb.Function =3D SRB_FUNCTION_EXECUTE_SCSI;
-    Srb.DataBuffer =3D Unmap;
-    Srb.DataTransferLength =3D Length;
-    Srb.TimeOutValue =3D (ULONG)-1;
-    Srb.CdbLength =3D 10;
-
-    Cdb =3D (PCDB)&Srb.Cdb[0];
-    Cdb->UNMAP.OperationCode =3D SCSIOP_UNMAP;
-    *(PUSHORT)Cdb->UNMAP.AllocationLength =3D _byteswap_ushort((USHORT)Len=
gth);
-
-    *(PUSHORT)Unmap->DataLength =3D _byteswap_ushort((USHORT)(Length - FIE=
LD_OFFSET(UNMAP_LIST_HEADER, BlockDescrDataLength)));
-    *(PUSHORT)Unmap->BlockDescrDataLength =3D _byteswap_ushort((USHORT)(Le=
ngth - FIELD_OFFSET(UNMAP_LIST_HEADER, Descriptors[0])));
-
-    for (Index =3D 0; Index < Count; ++Index) {
-        PUNMAP_BLOCK_DESCRIPTOR Block =3D &Unmap->Descriptors[Index];
-        PDEVICE_DATA_SET_RANGE  Range =3D &Ranges[Index];
-
-        ULONG   LengthInSectors =3D (ULONG)(Range->LengthInBytes / Pdo->Se=
ctorSize);
-        ULONG64 OffsetInSectors =3D (ULONG64)(Range->StartingOffset / Pdo-=
>SectorSize);
-
-        *(PULONG64)Block->StartingLba =3D _byteswap_uint64(OffsetInSectors=
);
-        *(PULONG)Block->LbaCount =3D _byteswap_ulong(LengthInSectors);
-    }
-
-    status =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-
-    if (StackLocation->Parameters.DeviceIoControl.InputBufferLength <
-        sizeof (STORAGE_PROPERTY_QUERY))
-        return PdoCompleteIrp(Pdo, Irp, STATUS_INFO_LENGTH_MISMATCH);
-
-    Query =3D Irp->AssociatedIrp.SystemBuffer;
-
-    Trace("%s %s\n", PropertyIdName(Query->PropertyId), QueryTypeName(Quer=
y->QueryType));
-
-    switch (Query->PropertyId) {
-    case StorageDeviceTrimProperty:
-        if (!Pdo->InterceptTrim) {
-            status =3D PdoForwardIrpAndForget(Pdo, Irp);
-            break;
-        }
-
-        if (Query->QueryType =3D=3D PropertyStandardQuery) {
-            PDEVICE_TRIM_DESCRIPTOR Trim;
-
-            if (StackLocation->Parameters.DeviceIoControl.OutputBufferLeng=
th <
-                sizeof (DEVICE_TRIM_DESCRIPTOR))
-                return PdoCompleteIrp(Pdo, Irp, STATUS_BUFFER_OVERFLOW);
-
-            Trim =3D Irp->AssociatedIrp.SystemBuffer;
-
-            RtlZeroMemory(Trim, sizeof(DEVICE_TRIM_DESCRIPTOR));
-
-            Trim->Version =3D sizeof(DEVICE_TRIM_DESCRIPTOR);
-            Trim->Size =3D sizeof(DEVICE_TRIM_DESCRIPTOR);
-            Trim->TrimEnabled =3D TRUE;
-
-            Irp->IoStatus.Information =3D sizeof(DEVICE_TRIM_DESCRIPTOR);
-        } else {
-            Irp->IoStatus.Information =3D 0;
-        }
-
-        status =3D PdoCompleteIrp(Pdo, Irp, STATUS_SUCCESS);
-        break;
-
-    case StorageAccessAlignmentProperty: {
-        if (Query->QueryType =3D=3D PropertyStandardQuery) {
-            PSTORAGE_ACCESS_ALIGNMENT_DESCRIPTOR AccessAlignment;
-
-            if (StackLocation->Parameters.DeviceIoControl.OutputBufferLeng=
th <
-                sizeof (STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR))
-                return PdoCompleteIrp(Pdo, Irp, STATUS_BUFFER_OVERFLOW);
-
-            AccessAlignment =3D Irp->AssociatedIrp.SystemBuffer;
-
-            RtlZeroMemory(AccessAlignment, sizeof(STORAGE_ACCESS_ALIGNMENT=
_DESCRIPTOR));
-
-            AccessAlignment->Version =3D sizeof(STORAGE_ACCESS_ALIGNMENT_D=
ESCRIPTOR);
-            AccessAlignment->Size =3D sizeof(STORAGE_ACCESS_ALIGNMENT_DESC=
RIPTOR);
-            AccessAlignment->BytesPerCacheLine =3D 0;
-            AccessAlignment->BytesOffsetForCacheAlignment =3D 0;
-            AccessAlignment->BytesPerLogicalSector =3D Pdo->SectorSize;
-            AccessAlignment->BytesPerPhysicalSector =3D Pdo->PhysSectorSiz=
e;
-            AccessAlignment->BytesOffsetForSectorAlignment =3D 0;
-
-            Irp->IoStatus.Information =3D sizeof(STORAGE_ACCESS_ALIGNMENT_=
DESCRIPTOR);
-        } else {
-            Irp->IoStatus.Information =3D 0;
-        }
-
-        status =3D PdoCompleteIrp(Pdo, Irp, STATUS_SUCCESS);
-        break;
-    }
-    default:
-        status =3D 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 =3D Irp->AssociatedIrp.SystemBuffer;
-
-    switch (Attributes->Action) {
-    case DeviceDsmAction_Trim:
-        if (!Pdo->InterceptTrim) {
-            status =3D PdoForwardIrpAndForget(Pdo, Irp);
-            break;
-        }
-
-        Ranges =3D (PDEVICE_DATA_SET_RANGE)((PUCHAR)Attributes + Attribute=
s->DataSetRangesOffset);
-        NumRanges =3D Attributes->DataSetRangesLength / sizeof(DEVICE_DATA=
_SET_RANGE);
-
-        status =3D PdoSendTrimSynchronous(Pdo, Ranges, NumRanges);
-
-        status =3D PdoCompleteIrp(Pdo, Irp, status);
-        break;
-
-    default:
-        status =3D 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 =3D IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    StackLocation =3D IoGetCurrentIrpStackLocation(Irp);
-    ControlCode =3D StackLocation->Parameters.DeviceIoControl.IoControlCod=
e;
-    Method =3D METHOD_FROM_CTL_CODE(ControlCode);
-
-    switch (ControlCode) {
-    case IOCTL_STORAGE_QUERY_PROPERTY:
-        ASSERT(Method =3D=3D METHOD_BUFFERED);
-        status =3D PdoQueryProperty(Pdo, Irp);
-        break;
-
-    case IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES:
-        ASSERT(Method =3D=3D METHOD_BUFFERED);
-        status =3D PdoManageDataSetAttributes(Pdo, Irp);
-        break;
-
-    default:
-        status =3D PdoForwardIrpAndForget(Pdo, Irp);
-        break;
-    }
-
-    return status;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    Irp->IoStatus.Status =3D 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;
-    POWER_STATE         PowerState;
-    NTSTATUS            status;
-
-    status =3D IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status =3D PdoForwardIrpSynchronously(Pdo, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status =3D PdoSendReadCapacity16Synchronous(Pdo,
-                                              &SectorSize,
-                                              &PhysSectorSize,
-                                              &SectorCount);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    Pdo->SectorSize =3D SectorSize;
-    Pdo->PhysSectorSize =3D PhysSectorSize;
-
-    Size =3D SectorSize * SectorCount;
-    Size >>=3D 20; // Scale to megabytes
-
-    Verbose("%s: %luMB (%uB sectors)\n",
-            __PdoGetName(Pdo), Size, SectorSize);
-
-    __PdoSetSystemPowerState(Pdo, PowerSystemWorking);
-    __PdoSetDevicePowerState(Pdo, PowerDeviceD0);
-
-    PowerState.DeviceState =3D PowerDeviceD0;
-    PoSetPowerState(Pdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
-
-    __PdoSetDevicePnpState(Pdo, Started);
-
-    IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return STATUS_SUCCESS;
-
-fail3:
-    Error("fail3\n");
-
-fail2:
-    Error("fail2\n");
-
-    IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    Irp->IoStatus.Status =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    __PdoSetDevicePnpState(Pdo, StopPending);
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __PdoQueryStopDevice,
-                           Pdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-
-    __PdoRestoreDevicePnpState(Pdo, StopPending);
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __PdoCancelStopDevice,
-                           Pdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D Context;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-
-    Pdo->PhysSectorSize =3D 0;
-    Pdo->SectorSize =3D 0;
-
-    return STATUS_SUCCESS;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-PdoStopDevice(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    POWER_STATE         PowerState;
-    NTSTATUS            status;
-
-    status =3D IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    if (__PdoGetDevicePowerState(Pdo) !=3D PowerDeviceD0)
-        goto done;
-
-    __PdoSetDevicePowerState(Pdo, PowerDeviceD3);
-    __PdoSetSystemPowerState(Pdo, PowerSystemShutdown);
-
-    PowerState.DeviceState =3D PowerDeviceD3;
-    PoSetPowerState(Pdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
-
-done:
-    __PdoSetDevicePnpState(Pdo, Stopped);
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __PdoStopDevice,
-                           Pdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    __PdoSetDevicePnpState(Pdo, RemovePending);
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __PdoQueryRemoveDevice,
-                           Pdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    __PdoRestoreDevicePnpState(Pdo, RemovePending);
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __PdoCancelRemoveDevice,
-                           Pdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    __PdoSetDevicePnpState(Pdo, SurpriseRemovePending);
-    Irp->IoStatus.Status =3D STATUS_SUCCESS;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __PdoSurpriseRemoval,
-                           Pdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-PdoRemoveDevice(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    PXENDISK_FDO        Fdo =3D __PdoGetFdo(Pdo);
-    POWER_STATE         PowerState;
-    NTSTATUS            status;
-
-    status =3D IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    if (__PdoGetDevicePowerState(Pdo) !=3D PowerDeviceD0)
-        goto done;
-
-    __PdoSetDevicePowerState(Pdo, PowerDeviceD3);
-    __PdoSetSystemPowerState(Pdo, PowerSystemShutdown);
-
-    PowerState.DeviceState =3D PowerDeviceD3;
-    PoSetPowerState(Pdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
-
-done:
-    FdoAcquireMutex(Fdo);
-    __PdoSetDevicePnpState(Pdo, Deleted);
-    FdoReleaseMutex(Fdo);
-
-    IoReleaseRemoveLockAndWait(&Pdo->Dx->RemoveLock, Irp);
-
-    status =3D PdoForwardIrpSynchronously(Pdo, Irp);
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    Pdo->PhysSectorSize =3D 0;
-    Pdo->SectorSize =3D 0;
-
-    FdoAcquireMutex(Fdo);
-    PdoDestroy(Pdo);
-    FdoReleaseMutex(Fdo);
-
-    IoInvalidateDeviceRelations(FdoGetPhysicalDeviceObject(Fdo),
-                                BusRelations);
-
-    return status;
-
-fail1:
-    Irp->IoStatus.Status =3D status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-static DECLSPEC_NOINLINE NTSTATUS
-PdoEject(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    PXENDISK_FDO        Fdo =3D __PdoGetFdo(Pdo);
-    NTSTATUS            status;
-
-    __PdoSetDevicePnpState(Pdo, Deleted);
-
-    status =3D 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 =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-    MinorFunction =3D StackLocation->MinorFunction;
-
-    switch (StackLocation->MinorFunction) {
-    case IRP_MN_START_DEVICE:
-        status =3D PdoStartDevice(Pdo, Irp);
-        break;
-
-    case IRP_MN_QUERY_STOP_DEVICE:
-        status =3D PdoQueryStopDevice(Pdo, Irp);
-        break;
-
-    case IRP_MN_CANCEL_STOP_DEVICE:
-        status =3D PdoCancelStopDevice(Pdo, Irp);
-        break;
-
-    case IRP_MN_STOP_DEVICE:
-        status =3D PdoStopDevice(Pdo, Irp);
-        break;
-
-    case IRP_MN_QUERY_REMOVE_DEVICE:
-        status =3D PdoQueryRemoveDevice(Pdo, Irp);
-        break;
-
-    case IRP_MN_SURPRISE_REMOVAL:
-        status =3D PdoSurpriseRemoval(Pdo, Irp);
-        break;
-
-    case IRP_MN_REMOVE_DEVICE:
-        status =3D PdoRemoveDevice(Pdo, Irp);
-        break;
-
-    case IRP_MN_CANCEL_REMOVE_DEVICE:
-        status =3D PdoCancelRemoveDevice(Pdo, Irp);
-        break;
-
-    case IRP_MN_EJECT:
-        status =3D PdoEject(Pdo, Irp);
-        break;
-
-    default:
-        status =3D IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-        if (!NT_SUCCESS(status))
-            goto fail1;
-
-        IoCopyCurrentIrpStackLocationToNext(Irp);
-        IoSetCompletionRoutine(Irp,
-                               __PdoDispatchPnp,
-                               Pdo,
-                               TRUE,
-                               TRUE,
-                               TRUE);
-
-        status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-        break;
-    }
-
-    return status;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    Irp->IoStatus.Status =3D 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 =3D (PXENDISK_PDO) Context;
-    PIO_STACK_LOCATION  StackLocation;
-    POWER_STATE         PowerState;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    StackLocation =3D IoGetCurrentIrpStackLocation(Irp);
-    PowerState =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-    PowerState =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-    DeviceState =3D StackLocation->Parameters.Power.State.DeviceState;
-    PowerAction =3D StackLocation->Parameters.Power.ShutdownType;
-
-    Trace("=3D=3D=3D=3D> (%s:%s)\n",
-          PowerDeviceStateName(DeviceState),
-          PowerActionName(PowerAction));
-
-    if (DeviceState =3D=3D __PdoGetDevicePowerState(Pdo)) {
-        IoSkipCurrentIrpStackLocation(Irp);
-        status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-        goto done;
-    }
-
-    status =3D DeviceState < __PdoGetDevicePowerState(Pdo) ?
-             __PdoSetDevicePowerUp(Pdo, Irp) :
-             __PdoSetDevicePowerDown(Pdo, Irp);
-
-done:
-    Trace("<=3D=3D=3D=3D (%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 =3D (PXENDISK_PDO) Context;
-    PIO_STACK_LOCATION  StackLocation;
-    SYSTEM_POWER_STATE  SystemState;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    StackLocation =3D IoGetCurrentIrpStackLocation(Irp);
-    SystemState =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-    SystemState =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-    SystemState =3D StackLocation->Parameters.Power.State.SystemState;
-    PowerAction =3D StackLocation->Parameters.Power.ShutdownType;
-
-    Trace("=3D=3D=3D=3D> (%s:%s)\n",
-          PowerSystemStateName(SystemState),
-          PowerActionName(PowerAction));
-
-    if (SystemState =3D=3D __PdoGetSystemPowerState(Pdo)) {
-        IoSkipCurrentIrpStackLocation(Irp);
-        status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-        goto done;
-    }
-
-    status =3D SystemState < __PdoGetSystemPowerState(Pdo) ?
-             __PdoSetSystemPowerUp(Pdo, Irp) :
-             __PdoSetSystemPowerDown(Pdo, Irp);
-
-done:
-    Trace("<=3D=3D=3D=3D (%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 =3D IoGetCurrentIrpStackLocation(Irp);
-
-    switch (StackLocation->MinorFunction) {
-    case IRP_MN_SET_POWER:
-        status =3D __PdoSetDevicePower(Pdo, Irp);
-        break;
-
-    default:
-        IoSkipCurrentIrpStackLocation(Irp);
-        status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-        break;
-    }
-
-    return status;
-}
-
-static NTSTATUS
-PdoSystemPower(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    NTSTATUS            status;
-    PIO_STACK_LOCATION  StackLocation;
-
-    StackLocation =3D IoGetCurrentIrpStackLocation(Irp);
-
-    switch (StackLocation->MinorFunction) {
-    case IRP_MN_SET_POWER:
-        status =3D __PdoSetSystemPower(Pdo, Irp);
-        break;
-
-    default:
-        IoSkipCurrentIrpStackLocation(Irp);
-        status =3D 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 =3D IoGetCurrentIrpStackLocation(Irp);
-    PowerType =3D StackLocation->Parameters.Power.Type;
-
-    switch (PowerType) {
-    case DevicePowerState:
-        status =3D PdoDevicePower(Pdo, Irp);
-        break;
-
-    case SystemPowerState:
-        status =3D PdoSystemPower(Pdo, Irp);
-        break;
-
-    default:
-        IoSkipCurrentIrpStackLocation(Irp);
-        status =3D 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 =3D 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 =3D IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-    IoSetCompletionRoutine(Irp,
-                           __PdoDispatchDefault,
-                           Pdo,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    status =3D IoCallDriver(Pdo->LowerDeviceObject, Irp);
-
-    return status;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    Irp->IoStatus.Status =3D status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-NTSTATUS
-PdoDispatch(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    NTSTATUS            status;
-
-    StackLocation =3D IoGetCurrentIrpStackLocation(Irp);
-
-    switch (StackLocation->MajorFunction) {
-    case IRP_MJ_DEVICE_CONTROL:
-        status =3D PdoDispatchControl(Pdo, Irp);
-        break;
-
-    case IRP_MJ_PNP:
-        status =3D PdoDispatchPnp(Pdo, Irp);
-        break;
-
-    case IRP_MJ_POWER:
-        status =3D PdoDispatchPower(Pdo, Irp);
-        break;
-
-    default:
-        status =3D 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 =3D IoGetAttachedDeviceReference(PhysicalDeviceObjec=
t);
-    DeviceType =3D LowerDeviceObject->DeviceType;
-    ObDereferenceObject(LowerDeviceObject);
-
-#pragma prefast(suppress:28197) // Possibly leaking memory 'PhysicalDevice=
Object'
-    status =3D IoCreateDevice(DriverGetDriverObject(),
-                            sizeof(XENDISK_DX),
-                            NULL,
-                            DeviceType,
-                            FILE_DEVICE_SECURE_OPEN,
-                            FALSE,
-                            &FilterDeviceObject);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    Dx =3D (PXENDISK_DX)FilterDeviceObject->DeviceExtension;
-    RtlZeroMemory(Dx, sizeof (XENDISK_DX));
-
-    Dx->Type =3D PHYSICAL_DEVICE_OBJECT;
-    Dx->DeviceObject =3D FilterDeviceObject;
-    Dx->DevicePnpState =3D Present;
-    Dx->SystemPowerState =3D PowerSystemShutdown;
-    Dx->DevicePowerState =3D PowerDeviceD3;
-
-    IoInitializeRemoveLock(&Dx->RemoveLock, PDO_TAG, 0, 0);
-
-    Pdo =3D __PdoAllocate(sizeof (XENDISK_PDO));
-
-    status =3D STATUS_NO_MEMORY;
-    if (Pdo =3D=3D NULL)
-        goto fail2;
-
-    LowerDeviceObject =3D IoAttachDeviceToDeviceStack(FilterDeviceObject,
-                                                    PhysicalDeviceObject);
-
-    status =3D STATUS_UNSUCCESSFUL;
-    if (LowerDeviceObject =3D=3D NULL)
-        goto fail3;
-
-    Pdo->Dx =3D Dx;
-    Pdo->PhysicalDeviceObject =3D PhysicalDeviceObject;
-    Pdo->LowerDeviceObject =3D LowerDeviceObject;
-
-    __PdoSetName(Pdo, DeviceID, InstanceID);
-
-    ParametersKey =3D DriverGetParametersKey();
-
-    Pdo->InterceptTrim =3D TRUE;
-
-    status =3D RegistryQueryDwordValue(ParametersKey,
-                                     "InterceptTrim",
-                                     &InterceptTrim);
-    if (NT_SUCCESS(status))
-        Pdo->InterceptTrim =3D (InterceptTrim !=3D 0) ? TRUE : FALSE;
-
-    Verbose("%p (%s)\n", FilterDeviceObject, __PdoGetName(Pdo));
-
-    Dx->Pdo =3D Pdo;
-
-#pragma prefast(suppress:28182) // Dereferencing NULL pointer
-    FilterDeviceObject->DeviceType =3D LowerDeviceObject->DeviceType;
-    FilterDeviceObject->Characteristics =3D LowerDeviceObject->Characteris=
tics;
-
-    FilterDeviceObject->Flags |=3D LowerDeviceObject->Flags;
-    FilterDeviceObject->Flags &=3D ~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 =3D Pdo->LowerDeviceObject;
-    PXENDISK_DX         Dx =3D Pdo->Dx;
-    PDEVICE_OBJECT      FilterDeviceObject =3D Dx->DeviceObject;
-
-    ASSERT3U(__PdoGetDevicePnpState(Pdo), =3D=3D, Deleted);
-
-    __PdoUnlink(Pdo);
-
-    Verbose("%s\n", __PdoGetName(Pdo));
-
-    Dx->Pdo =3D NULL;
-
-    Pdo->InterceptTrim =3D FALSE;
-
-    RtlZeroMemory(Pdo->Name, sizeof (Pdo->Name));
-
-    Pdo->PhysicalDeviceObject =3D NULL;
-    Pdo->LowerDeviceObject =3D NULL;
-    Pdo->Dx =3D 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_T=
YPE, 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, =3D=3D, NULL);
-
-    status =3D RtlUpcaseUnicodeString(&RegistryPath, Path, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    ASSERT3P(RegistryDriverObject, =3D=3D, NULL);
-    RegistryDriverObject =3D DriverObject;
-
-    ASSERT3P(__IoOpenDriverRegistryKey, =3D=3D, NULL);
-    RtlInitUnicodeString(&Unicode, L"IoOpenDriverRegistryKey");
-
-    Func =3D MmGetSystemRoutineAddress(&Unicode);
-    if (Func !=3D NULL)
-        __IoOpenDriverRegistryKey =3D (IOOPENDRIVERREGISTRYKEY)Func;
-
-    return STATUS_SUCCESS;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
-}
-
-VOID
-RegistryTeardown(
-    VOID
-    )
-{
-    __IoOpenDriverRegistryKey =3D NULL;
-
-    RegistryDriverObject =3D NULL;
-
-    RtlFreeUnicodeString(&RegistryPath);
-    RegistryPath.Buffer =3D NULL;
-    RegistryPath.MaximumLength =3D RegistryPath.Length =3D 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 =3D 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[] =3D L"\\Registry\\Machine\\";
-    ULONG               Length;
-    UNICODE_STRING      Unicode;
-    NTSTATUS            status;
-
-    Length =3D (ULONG)wcslen(Prefix);
-
-    status =3D STATUS_INVALID_PARAMETER;
-    if (_wcsnicmp(Path, Prefix, Length) !=3D 0)
-        goto fail1;
-
-    RtlInitUnicodeString(&Unicode, Prefix);
-
-    status =3D RegistryOpenKey(NULL, &Unicode, KEY_ALL_ACCESS, Parent);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    *ChildPath =3D 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 =3D __RegistryAllocate(Path->MaximumLength + sizeof (WCHAR));
-
-    status =3D STATUS_NO_MEMORY;
-    if (Buffer =3D=3D NULL)
-        goto fail1;
-
-    RtlCopyMemory(Buffer, Path->Buffer, Path->Length);
-
-    Root =3D Parent;
-
-    if (Parent !=3D NULL) {
-        ChildPath =3D Buffer;
-    } else {
-        status =3D RegistryOpenRoot(Buffer, &Parent, &ChildPath);
-        if (!NT_SUCCESS(status))
-            goto fail2;
-    }
-
-    ChildName =3D __wcstok_r(ChildPath, L"\\", &Context);
-
-    status =3D STATUS_INVALID_PARAMETER;
-    if (ChildName =3D=3D NULL)
-        goto fail3;
-
-    Child =3D NULL;
-
-    while (ChildName !=3D NULL) {
-        UNICODE_STRING      Unicode;
-        OBJECT_ATTRIBUTES   Attributes;
-
-        RtlInitUnicodeString(&Unicode, ChildName);
-
-        InitializeObjectAttributes(&Attributes,
-                                   &Unicode,
-                                   OBJ_CASE_INSENSITIVE |
-                                   OBJ_KERNEL_HANDLE |
-                                   OBJ_OPENIF,
-                                   Parent,
-                                   NULL);
-
-        status =3D ZwCreateKey(&Child,
-                             KEY_ALL_ACCESS,
-                             &Attributes,
-                             0,
-                             NULL,
-                             Options,
-                             NULL
-                             );
-        if (!NT_SUCCESS(status))
-            goto fail4;
-
-        ChildName =3D __wcstok_r(NULL, L"\\", &Context);
-
-        if (Parent !=3D Root)
-            ZwClose(Parent);
-
-        Parent =3D Child;
-    }
-
-    ASSERT(Child !=3D NULL);
-
-    *Key =3D Child;
-
-    __RegistryFree(Buffer);
-
-    return STATUS_SUCCESS;
-
-fail4:
-fail3:
-    if (Parent !=3D 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 !=3D NULL) {
-        status =3D __IoOpenDriverRegistryKey(RegistryDriverObject,
-                                           DriverRegKeyParameters,
-                                           DesiredAccess,
-                                           0,
-                                           Key);
-        if (!NT_SUCCESS(status))
-            goto fail1;
-
-        goto done;
-    }
-
-    status =3D RegistryOpenKey(NULL, &RegistryPath, DesiredAccess, &Servic=
eKey);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status =3D 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 =3D 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 =3D IoOpenDeviceRegistryKey(DeviceObject,
-                                     PLUGPLAY_REGKEY_DEVICE,
-                                     KEY_READ,
-                                     &SubKey);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    Length =3D 0;
-    status =3D ZwQueryKey(SubKey,
-                        KeyNameInformation,
-                        NULL,
-                        0,
-                        &Length);
-    if (status !=3D STATUS_BUFFER_OVERFLOW &&
-        status !=3D STATUS_BUFFER_TOO_SMALL)
-        goto fail2;
-
-#pragma prefast(suppress:6102)
-    Info =3D __RegistryAllocate(Length + sizeof (WCHAR));
-
-    status =3D STATUS_NO_MEMORY;
-    if (Info =3D=3D NULL)
-        goto fail3;
-
-    status =3D ZwQueryKey(SubKey,
-                        KeyNameInformation,
-                        Info,
-                        Length,
-                        &Length);
-    if (!NT_SUCCESS(status))
-        goto fail4;
-
-    Info->Name[Info->NameLength / sizeof (WCHAR)] =3D '\0';
-
-    Cursor =3D wcsrchr(Info->Name, L'\\');
-    ASSERT(Cursor !=3D NULL);
-
-    *Cursor =3D L'\0';
-
-    RtlInitUnicodeString(&Unicode, Info->Name);
-
-    status =3D 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 =3D RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status =3D 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 =3D RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status =3D 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 =3D RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status =3D RegistryOpenKey(Key, &Unicode, KEY_ALL_ACCESS, &SubKey);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status =3D 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 =3D ZwQueryKey(Key,
-                        KeyFullInformation,
-                        NULL,
-                        0,
-                        &Size);
-    if (status !=3D STATUS_BUFFER_OVERFLOW &&
-        status !=3D STATUS_BUFFER_TOO_SMALL)
-        goto fail1;
-
-#pragma prefast(suppress:6102)
-    Full =3D __RegistryAllocate(Size);
-
-    status =3D STATUS_NO_MEMORY;
-    if (Full =3D=3D NULL)
-        goto fail2;
-
-    status =3D ZwQueryKey(Key,
-                        KeyFullInformation,
-                        Full,
-                        Size,
-                        &Size);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    Size =3D FIELD_OFFSET(KEY_BASIC_INFORMATION, Name) +
-           Full->MaxNameLen;
-
-    Basic =3D __RegistryAllocate(Size);
-    status =3D STATUS_NO_MEMORY;
-    if (Basic =3D=3D NULL)
-        goto fail4;
-
-    for (Index =3D 0; Index < Full->SubKeys; Index++) {
-        ULONG           Ignore;
-        UNICODE_STRING  Unicode;
-        ANSI_STRING     Ansi;
-
-        status =3D ZwEnumerateKey(Key,
-                                Index,
-                                KeyBasicInformation,
-                                Basic,
-                                Size,
-                                &Ignore);
-        if (!NT_SUCCESS(status))
-            goto fail5;
-
-        Unicode.MaximumLength =3D (USHORT)Basic->NameLength;
-        Unicode.Buffer =3D Basic->Name;
-        Unicode.Length =3D (USHORT)Basic->NameLength;
-
-        Ansi.MaximumLength =3D (USHORT)((Basic->NameLength / sizeof (WCHAR=
)) + sizeof (CHAR));
-        Ansi.Buffer =3D __RegistryAllocate(Ansi.MaximumLength);
-
-        status =3D STATUS_NO_MEMORY;
-        if (Ansi.Buffer =3D=3D NULL)
-            goto fail6;
-
-        status =3D RtlUnicodeStringToAnsiString(&Ansi, &Unicode, FALSE);
-        ASSERT(NT_SUCCESS(status));
-
-        Ansi.Length =3D (USHORT)(strlen(Ansi.Buffer) * sizeof (CHAR));
-
-        status =3D Callback(Context, Key, &Ansi);
-
-        __RegistryFree(Ansi.Buffer);
-        Ansi.Buffer =3D 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_STRIN=
G, ULONG),
-    IN  PVOID                       Context
-    )
-{
-    ULONG                           Size;
-    NTSTATUS                        status;
-    PKEY_FULL_INFORMATION           Full;
-    PKEY_VALUE_BASIC_INFORMATION    Basic;
-    ULONG                           Index;
-
-    status =3D ZwQueryKey(Key,
-                        KeyFullInformation,
-                        NULL,
-                        0,
-                        &Size);
-    if (status !=3D STATUS_BUFFER_OVERFLOW &&
-        status !=3D STATUS_BUFFER_TOO_SMALL)
-        goto fail1;
-
-#pragma prefast(suppress:6102)
-    Full =3D __RegistryAllocate(Size);
-
-    status =3D STATUS_NO_MEMORY;
-    if (Full =3D=3D NULL)
-        goto fail2;
-
-    status =3D ZwQueryKey(Key,
-                        KeyFullInformation,
-                        Full,
-                        Size,
-                        &Size);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    Size =3D FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name) +
-           Full->MaxValueNameLen;
-
-    Basic =3D __RegistryAllocate(Size);
-    status =3D STATUS_NO_MEMORY;
-    if (Basic =3D=3D NULL)
-        goto fail4;
-
-    for (Index =3D 0; Index < Full->Values; Index++) {
-        ULONG           Ignore;
-        UNICODE_STRING  Unicode;
-        ANSI_STRING     Ansi;
-
-        status =3D ZwEnumerateValueKey(Key,
-                                     Index,
-                                     KeyValueBasicInformation,
-                                     Basic,
-                                     Size,
-                                     &Ignore);
-        if (!NT_SUCCESS(status))
-            goto fail5;
-
-        Unicode.MaximumLength =3D (USHORT)Basic->NameLength;
-        Unicode.Buffer =3D Basic->Name;
-        Unicode.Length =3D (USHORT)Basic->NameLength;
-
-        Ansi.MaximumLength =3D (USHORT)((Basic->NameLength / sizeof (WCHAR=
)) + sizeof (CHAR));
-        Ansi.Buffer =3D __RegistryAllocate(Ansi.MaximumLength);
-
-        status =3D RtlUnicodeStringToAnsiString(&Ansi, &Unicode, FALSE);
-        ASSERT(NT_SUCCESS(status));
-
-        Ansi.Length =3D (USHORT)(strlen(Ansi.Buffer) * sizeof (CHAR));
-
-        status =3D 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 =3D RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status =3D 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 =3D RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status =3D ZwQueryValueKey(Key,
-                             &Unicode,
-                             KeyValuePartialInformation,
-                             NULL,
-                             0,
-                             &Size);
-    if (status !=3D STATUS_BUFFER_OVERFLOW &&
-        status !=3D STATUS_BUFFER_TOO_SMALL)
-        goto fail2;
-
-#pragma prefast(suppress:6102)
-    Partial =3D __RegistryAllocate(Size);
-
-    status =3D STATUS_NO_MEMORY;
-    if (Partial =3D=3D NULL)
-        goto fail3;
-
-    status =3D ZwQueryValueKey(Key,
-                             &Unicode,
-                             KeyValuePartialInformation,
-                             Partial,
-                             Size,
-                             &Size);
-    if (!NT_SUCCESS(status))
-        goto fail4;
-
-    status =3D STATUS_INVALID_PARAMETER;
-    if (Partial->Type !=3D REG_DWORD ||
-        Partial->DataLength !=3D sizeof (ULONG))
-        goto fail5;
-
-    *Value =3D *(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 =3D RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    Partial =3D __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMAT=
ION, Data) +
-                                 sizeof (ULONG));
-
-    status =3D STATUS_NO_MEMORY;
-    if (Partial =3D=3D NULL)
-        goto fail2;
-
-    Partial->TitleIndex =3D 0;
-    Partial->Type =3D REG_DWORD;
-    Partial->DataLength =3D sizeof (ULONG);
-    *(PULONG)Partial->Data =3D Value;
-
-    status =3D 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 =3D __RegistryAllocate(sizeof (ANSI_STRING) * 2);
-
-    status =3D STATUS_NO_MEMORY;
-    if (Ansi =3D=3D NULL)
-        goto fail1;
-
-    Length =3D (ULONG)wcslen(Buffer);
-    Ansi[0].MaximumLength =3D (USHORT)(Length + 1) * sizeof (CHAR);
-    Ansi[0].Buffer =3D __RegistryAllocate(Ansi[0].MaximumLength);
-
-    status =3D STATUS_NO_MEMORY;
-    if (Ansi[0].Buffer =3D=3D NULL)
-        goto fail2;
-
-    RtlInitUnicodeString(&Unicode, Buffer);
-    status =3D RtlUnicodeStringToAnsiString(&Ansi[0], &Unicode, FALSE);
-    ASSERT(NT_SUCCESS(status));
-
-    Ansi[0].Length =3D (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 =3D 0;
-    Count =3D 0;
-    for (;;) {
-        ULONG   Length;
-
-        Length =3D (ULONG)wcslen(&Buffer[Index]);
-        if (Length =3D=3D 0)
-            break;
-
-        Index +=3D Length + 1;
-        Count++;
-    }
-
-    Ansi =3D __RegistryAllocate(sizeof (ANSI_STRING) * (Count + 1));
-
-    status =3D STATUS_NO_MEMORY;
-    if (Ansi =3D=3D NULL)
-        goto fail1;
-
-    for (Index =3D 0; Index < Count; Index++) {
-        ULONG           Length;
-        UNICODE_STRING  Unicode;
-
-        Length =3D (ULONG)wcslen(Buffer);
-        Ansi[Index].MaximumLength =3D (USHORT)(Length + 1) * sizeof (CHAR)=
;
-        Ansi[Index].Buffer =3D __RegistryAllocate(Ansi[Index].MaximumLengt=
h);
-
-        status =3D STATUS_NO_MEMORY;
-        if (Ansi[Index].Buffer =3D=3D NULL)
-            goto fail2;
-
-        RtlInitUnicodeString(&Unicode, Buffer);
-
-        status =3D RtlUnicodeStringToAnsiString(&Ansi[Index], &Unicode, FA=
LSE);
-        ASSERT(NT_SUCCESS(status));
-
-        Ansi[Index].Length =3D (USHORT)Length * sizeof (CHAR);
-        Buffer +=3D Length + 1;
-    }
-
-    return Ansi;
-
-fail2:
-    while (--Index >=3D 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 =3D RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status =3D ZwQueryValueKey(Key,
-                             &Unicode,
-                             KeyValuePartialInformation,
-                             NULL,
-                             0,
-                             &Size);
-    if (status !=3D STATUS_BUFFER_OVERFLOW &&
-        status !=3D STATUS_BUFFER_TOO_SMALL)
-        goto fail2;
-
-#pragma prefast(suppress:6102)
-    Value =3D __RegistryAllocate(Size);
-
-    status =3D STATUS_NO_MEMORY;
-    if (Value =3D=3D NULL)
-        goto fail3;
-
-    status =3D ZwQueryValueKey(Key,
-                             &Unicode,
-                             KeyValuePartialInformation,
-                             Value,
-                             Size,
-                             &Size);
-    if (!NT_SUCCESS(status))
-        goto fail4;
-
-    switch (Value->Type) {
-    case REG_SZ:
-        status =3D STATUS_NO_MEMORY;
-        *Array =3D RegistrySzToAnsi((PWCHAR)Value->Data);
-        break;
-
-    case REG_MULTI_SZ:
-        status =3D STATUS_NO_MEMORY;
-        *Array =3D RegistryMultiSzToAnsi((PWCHAR)Value->Data);
-        break;
-
-    default:
-        status =3D STATUS_INVALID_PARAMETER;
-        *Array =3D NULL;
-        break;
-    }
-
-    if (*Array =3D=3D NULL)
-        goto fail5;
-
-    if (Type !=3D NULL)
-        *Type =3D 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 =3D RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status =3D ZwQueryValueKey(Key,
-                             &Unicode,
-                             KeyValuePartialInformation,
-                             NULL,
-                             0,
-                             &Size);
-    if (status !=3D STATUS_BUFFER_OVERFLOW &&
-        status !=3D STATUS_BUFFER_TOO_SMALL)
-        goto fail2;
-
-#pragma prefast(suppress:6102)
-    Partial =3D __RegistryAllocate(Size);
-
-    status =3D STATUS_NO_MEMORY;
-    if (Partial =3D=3D NULL)
-        goto fail3;
-
-    status =3D ZwQueryValueKey(Key,
-                             &Unicode,
-                             KeyValuePartialInformation,
-                             Partial,
-                             Size,
-                             &Size);
-    if (!NT_SUCCESS(status))
-        goto fail4;
-
-    switch (Partial->Type) {
-    case REG_BINARY:
-        *Buffer =3D __RegistryAllocate(Partial->DataLength);
-
-        status =3D STATUS_NO_MEMORY;
-        if (*Buffer =3D=3D NULL)
-            break;
-
-        *Length =3D Partial->DataLength;
-        RtlCopyMemory(*Buffer, Partial->Data, Partial->DataLength);
-        break;
-
-    default:
-        status =3D STATUS_INVALID_PARAMETER;
-        *Buffer =3D NULL;
-        break;
-    }
-
-    if (*Buffer =3D=3D 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 =3D RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    Partial =3D __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMAT=
ION, Data) +
-                                 Length);
-
-    status =3D STATUS_NO_MEMORY;
-    if (Partial =3D=3D NULL)
-        goto fail2;
-
-    Partial->TitleIndex =3D 0;
-    Partial->Type =3D REG_BINARY;
-    Partial->DataLength =3D Length;
-    RtlCopyMemory(Partial->Data, Buffer, Partial->DataLength);
-
-    status =3D 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 =3D ZwQueryKey(Key,
-                        KeyNameInformation,
-                        NULL,
-                        0,
-                        &Size);
-    if (status !=3D STATUS_BUFFER_OVERFLOW &&
-        status !=3D STATUS_BUFFER_TOO_SMALL)
-        goto fail1;
-
-    // Name information is not intrinsically NULL terminated
-#pragma prefast(suppress:6102)
-    Value =3D __RegistryAllocate(Size + sizeof (WCHAR));
-
-    status =3D STATUS_NO_MEMORY;
-    if (Value =3D=3D NULL)
-        goto fail2;
-
-    status =3D ZwQueryKey(Key,
-                        KeyNameInformation,
-                        Value,
-                        Size,
-                        &Size);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    Value->Name[Value->NameLength / sizeof (WCHAR)] =3D L'\0';
-    *Array =3D RegistrySzToAnsi((PWCHAR)Value->Name);
-
-    status =3D STATUS_NO_MEMORY;
-    if (*Array =3D=3D 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\\CurrentC=
ontrolSet\\Control");
-
-    status =3D RegistryOpenKey(NULL, &Unicode, KEY_READ, &Key);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status =3D 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 =3D (ULONG)strlen(Prefix);
-
-    Option =3D __strtok_r(Ansi[0].Buffer, " ", &Context);
-    while (Option !=3D NULL) {
-        if (strncmp(Prefix, Option, Length) =3D=3D 0)
-            goto found;
-
-        Option =3D __strtok_r(NULL, " ", &Context);
-    }
-
-    status =3D STATUS_OBJECT_NAME_NOT_FOUND;
-    goto fail3;
-
-found:
-    *Value =3D __RegistryAllocate(sizeof (ANSI_STRING) * 2);
-
-    status =3D STATUS_NO_MEMORY;
-    if (*Value =3D=3D NULL)
-        goto fail4;
-
-    Length =3D (ULONG)strlen(Option);
-    (*Value)[0].MaximumLength =3D (USHORT)(Length + 1) * sizeof (CHAR);
-    (*Value)[0].Buffer =3D __RegistryAllocate((*Value)[0].MaximumLength);
-
-    status =3D STATUS_NO_MEMORY;
-    if ((*Value)[0].Buffer =3D=3D NULL)
-        goto fail5;
-
-    RtlCopyMemory((*Value)[0].Buffer, Option, Length * sizeof (CHAR));
-
-    (*Value)[0].Length =3D (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 =3D Ansi->Length + 1;
-    Partial =3D __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMAT=
ION, Data) +
-                                 Length * sizeof (WCHAR));
-
-    status =3D STATUS_NO_MEMORY;
-    if (Partial =3D=3D NULL)
-        goto fail1;
-
-    Partial->TitleIndex =3D 0;
-    Partial->Type =3D REG_SZ;
-    Partial->DataLength =3D Length * sizeof (WCHAR);
-
-    Unicode.MaximumLength =3D (UCHAR)Partial->DataLength;
-    Unicode.Buffer =3D (PWCHAR)Partial->Data;
-    Unicode.Length =3D 0;
-
-    status =3D 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 =3D 1;
-    for (Index =3D 0; Ansi[Index].Buffer !=3D NULL; Index++)
-        Length +=3D Ansi[Index].Length + 1;
-
-    Partial =3D __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMAT=
ION, Data) +
-                               Length * sizeof (WCHAR));
-
-    status =3D STATUS_NO_MEMORY;
-    if (Partial =3D=3D NULL)
-        goto fail1;
-
-    Partial->TitleIndex =3D 0;
-    Partial->Type =3D REG_MULTI_SZ;
-    Partial->DataLength =3D Length * sizeof (WCHAR);
-
-    Unicode.MaximumLength =3D (USHORT)Partial->DataLength;
-    Unicode.Buffer =3D (PWCHAR)Partial->Data;
-    Unicode.Length =3D 0;
-
-    for (Index =3D 0; Ansi[Index].Buffer !=3D NULL; Index++) {
-        status =3D RtlAnsiStringToUnicodeString(&Unicode, &Ansi[Index], FA=
LSE);
-        if (!NT_SUCCESS(status))
-            goto fail2;
-
-        Length =3D Unicode.Length / sizeof (WCHAR);
-
-        ASSERT3U(Unicode.MaximumLength, >=3D, (Length + 1) * sizeof (WCHAR=
));
-        Unicode.MaximumLength -=3D (USHORT)((Length + 1) * sizeof (WCHAR))=
;
-        Unicode.Buffer +=3D Length + 1;
-        Unicode.Length =3D 0;
-    }
-    *Unicode.Buffer =3D 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 =3D RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    switch (Type) {
-    case REG_SZ:
-        status =3D STATUS_NO_MEMORY;
-        Partial =3D RegistryAnsiToSz(Array);
-        break;
-
-    case REG_MULTI_SZ:
-        status =3D STATUS_NO_MEMORY;
-        Partial =3D RegistryAnsiToMultiSz(Array);
-        break;
-
-    default:
-        status =3D STATUS_INVALID_PARAMETER;
-        Partial =3D NULL;
-        break;
-    }
-
-    if (Partial =3D=3D NULL)
-        goto fail2;
-
-    status =3D 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 =3D=3D NULL)
-        return;
-
-    for (Index =3D 0; Array[Index].Buffer !=3D 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 =3D TRUE;
-    __ThreadWake(Thread);
-}
-
-VOID
-ThreadAlert(
-    IN  PXENDISK_THREAD Thread
-    )
-{
-    __ThreadAlert(Thread);
-}
-
-KSTART_ROUTINE  ThreadFunction;
-
-VOID
-ThreadFunction(
-    IN  PVOID       Argument
-    )
-{
-    PXENDISK_THREAD Self =3D Argument;
-    NTSTATUS        status;
-
-    status =3D Self->Function(Self, Self->Context);
-
-    if (InterlockedDecrement(&Self->References) =3D=3D 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(), =3D=3D, PASSIVE_LEVEL);
-
-    (*Thread) =3D __ThreadAllocate(sizeof (XENDISK_THREAD));
-
-    status =3D STATUS_NO_MEMORY;
-    if (*Thread =3D=3D NULL)
-        goto fail1;
-
-    (*Thread)->Function =3D Function;
-    (*Thread)->Context =3D Context;
-    (*Thread)->Alerted =3D FALSE;
-    (*Thread)->References =3D 2; // One for us, one for the thread functio=
n
-
-    KeInitializeEvent(&(*Thread)->Event, NotificationEvent, FALSE);
-
-    status =3D PsCreateSystemThread(&Handle,
-                                  STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_AL=
L,
-                                  NULL,
-                                  NULL,
-                                  NULL,
-                                  ThreadFunction,
-                                  *Thread);
-    if (!NT_SUCCESS(status)) {
-        --(*Thread)->References;    // Fake thread function termination
-        goto fail2;
-    }
-
-    status =3D 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) =3D=3D 0)
-        __ThreadFree(*Thread);
-
-    *Thread =3D 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(), =3D=3D, PASSIVE_LEVEL);
-    ASSERT3P(KeGetCurrentThread(), !=3D, Thread->Thread);
-
-    (VOID) KeWaitForSingleObject(Thread->Thread,
-                                 Executive,
-                                 KernelMode,
-                                 FALSE,
-                                 NULL);
-
-    References =3D InterlockedDecrement(&Thread->References);
-    ASSERT3U(References, =3D=3D, 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 =3D 'ODP',
-    FUNCTION_DEVICE_OBJECT =3D 'ODF'
-} DEVICE_OBJECT_TYPE, *PDEVICE_OBJECT_TYPE;
-
-typedef enum _DEVICE_PNP_STATE {
-    Invalid =3D 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_VERS=
ION,BUILD_NUMBER
-#define VER_PRODUCTVERSION_STR      MAJOR_VERSION_STR "." MINOR_VERSION_ST=
R "." 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..eb82210 100644
--- a/src/xenvbd.inf
+++ b/src/xenvbd.inf
@@ -48,7 +48,6 @@ DefaultDestDir=3D12
 [SourceDisksFiles]
 xenvbd.sys=3D0,,
 xencrsh.sys=3D0,,
-xendisk.sys=3D0,,

 [Manufacturer]
 %Vendor%=3DInst,NT@INF_ARCH@
@@ -67,29 +66,9 @@ FeatureScore=3D0xFE
 [XenVbd_Copyfiles]
 xenvbd.sys
 xencrsh.sys
-xendisk.sys
-
-[XenVbd_Inst.HW]
-AddReg=3DXenVbd_AddReg
-
-[XenVbd_AddReg]
-HKR,,"UpperFilters",0x00010000,"xendisk"

 [XenVbd_Inst.Services]
 AddService=3Dxenvbd,2,XenVbd_Service,
-AddService=3Dxendisk,,XenDisk_Service,
-
-[XenDisk_Service]
-DisplayName=3D%XenDiskName%
-ServiceType=3D%SERVICE_KERNEL_DRIVER%
-StartType=3D%SERVICE_BOOT_START%
-ErrorControl=3D%SERVICE_ERROR_NORMAL%
-ServiceBinary=3D%12%\xendisk.sys
-LoadOrderGroup=3D"Scsi Miniport"
-AddReg=3DXenDisk_Parameters
-
-[XenDisk_Parameters]
-HKR,"Parameters",,0x00000010

 [XenVbd_Service]
 DisplayName=3D%XenVbdName%
@@ -122,7 +101,6 @@ HKLM,%DiskKey%,"TimeOutValue",0x00010001,120
 Vendor =3D "@VENDOR_NAME@"
 DiskDesc =3D "@PRODUCT_NAME@ PV Storage Host Adapter Package"
 XenVbdName=3D "@PRODUCT_NAME@ PV Storage Host Adapter"
-XenDiskName=3D "@PRODUCT_NAME@ PV Storage Filter"
 UnplugKey=3D"SYSTEM\CurrentControlSet\Services\XEN\Unplug"
 ForceUnplugKey=3D"SYSTEM\CurrentControlSet\Services\XEN\ForceUnplug"
 PnpKey=3D"SYSTEM\CurrentControlSet\Control\Pnp"
diff --git a/vs2019/package/package.vcxproj b/vs2019/package/package.vcxpro=
j
index 764cfef..1a553d7 100644
--- a/vs2019/package/package.vcxproj
+++ b/vs2019/package/package.vcxproj
@@ -50,9 +50,6 @@
     <ProjectReference Include=3D"..\xenvbd\xenvbd.vcxproj">
       <Project>{ef236371-3145-41b1-99c9-82b33e353f17}</Project>
     </ProjectReference>
-    <ProjectReference Include=3D"..\xendisk\xendisk.vcxproj">
-      <Project>{d7411b2c-2c43-434d-9f56-e10a3d2f5bad}</Project>
-    </ProjectReference>
     <FilesToPackage Include=3D"..\xenvbd.inf" />
   </ItemGroup>
   <ItemGroup Condition=3D"Exists('$(DPINST_REDIST)')">
diff --git a/vs2019/xendisk/xendisk.vcxproj b/vs2019/xendisk/xendisk.vcxpro=
j
deleted file mode 100644
index 25b195f..0000000
--- a/vs2019/xendisk/xendisk.vcxproj
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version=3D"1.0" encoding=3D"utf-8"?>
-<Project DefaultTargets=3D"Build" ToolsVersion=3D"15.0" xmlns=3D"http://sc=
hemas.microsoft.com/developer/msbuild/2003">
-  <Import Project=3D"..\configs.props" />
-  <PropertyGroup Label=3D"PropertySheets">
-    <DriverType>WDM</DriverType>
-    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
-    <ConfigurationType>Driver</ConfigurationType>
-  </PropertyGroup>
-  <Import Project=3D"$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Label=3D"Globals">
-    <ProjectGuid>{D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}</ProjectGuid>
-  </PropertyGroup>
-  <Import Project=3D"..\targets.props" />
-  <Import Project=3D"$(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)</AdditionalOptio=
ns>
-      <AdditionalIncludeDirectories>..\..\include;..\..\src\common;%(Addit=
ionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>PROJECT=3D$(ProjectName);POOL_NX_OPTIN=3D1;=
%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <WarningLevel>EnableAllWarnings</WarningLevel>
-      <DisableSpecificWarnings>4061;4464;4548;4770;4711;4820;4668;4255;504=
5;6001;6054;26451;28196;30030;30029;%(DisableSpecificWarnings)</DisableSpec=
ificWarnings>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-    </ClCompile>
-    <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\src\common;%(Addit=
ionalIncludeDirectories)</AdditionalIncludeDirectories>
-    </ResourceCompile>
-    <Link>
-      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDepende=
ncies>
-      <AdditionalOptions>/INTEGRITYCHECK %(AdditionalOptions)</AdditionalO=
ptions>
-      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGener=
ation>
-      <CETCompat>true</CETCompat>
-      <GenerateMapFile>true</GenerateMapFile>
-      <MapExports>true</MapExports>
-    </Link>
-    <DriverSign>
-      <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
-    </DriverSign>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition=3D"'$(Platform)'=3D=3D'Win32'">
-    <ClCompile>
-      <PreprocessorDefinitions>__i386__;%(PreprocessorDefinitions)</Prepro=
cessorDefinitions>
-    </ClCompile>
-    <Link>
-      <ImageHasSafeExceptionHandlers>true</ImageHasSafeExceptionHandlers>
-    </Link>  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition=3D"'$(Platform)'=3D=3D'x64'">
-    <ClCompile>
-      <PreprocessorDefinitions>__x86_64__;%(PreprocessorDefinitions)</Prep=
rocessorDefinitions>
-    </ClCompile>
-    <Link>
-      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition=3D"'$(Configuration)'=3D=3D'Windows 10 Re=
lease'">
-    <ClCompile>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <WholeProgramOptimization>true</WholeProgramOptimization>
-      <AdditionalOptions>/Qspectre %(AdditionalOptions)</AdditionalOptions=
>
-    </ClCompile>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <FilesToPackage Include=3D"$(TargetPath)" />
-    <FilesToPackage Include=3D"$(OutDir)$(TargetName).pdb" />
-    <FilesToPackage Include=3D"$(OutDir)$(TargetName).map" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include=3D"../../src/xendisk/driver.c" />
-    <ClCompile Include=3D"../../src/xendisk/fdo.c" />
-    <ClCompile Include=3D"../../src/xendisk/pdo.c" />
-    <ClCompile Include=3D"../../src/xendisk/registry.c" />
-    <ClCompile Include=3D"../../src/xendisk/thread.c" />
-  </ItemGroup>
-  <ItemGroup>
-    <ResourceCompile Include=3D"..\..\src\xendisk\xendisk.rc" />
-  </ItemGroup>
-  <Import Project=3D"$(VCTargetsPath)\Microsoft.Cpp.targets" />
-</Project>
diff --git a/vs2019/xendisk/xendisk.vcxproj.user b/vs2019/xendisk/xendisk.v=
cxproj.user
deleted file mode 100644
index e1315db..0000000
--- a/vs2019/xendisk/xendisk.vcxproj.user
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version=3D"1.0" encoding=3D"utf-8"?>
-<Project ToolsVersion=3D"15.0" xmlns=3D"http://schemas.microsoft.com/devel=
oper/msbuild/2003">
-  <PropertyGroup>
-    <SignMode>TestSign</SignMode>
-    <TestCertificate>..\..\src\xenvbd.pfx</TestCertificate>
-    <TimeStampServer>http://timestamp.verisign.com/scripts/timstamp.dll</T=
imeStampServer>
-  </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}") =3D "=
xencrsh", "xencrsh\xencrsh.
                {65FA97EA-A569-4FC1-BFE7-D68E109143F7} =3D {65FA97EA-A569-4=
FC1-BFE7-D68E109143F7}
        EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") =3D "xendisk", "xendisk\=
xendisk.vcxproj", "{D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}"
-       ProjectSection(ProjectDependencies) =3D postProject
-               {65FA97EA-A569-4FC1-BFE7-D68E109143F7} =3D {65FA97EA-A569-4=
FC1-BFE7-D68E109143F7}
-       EndProjectSection
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") =3D "package", "package\=
package.vcxproj", "{AB8DAED3-9D70-4907-99A3-C643F1FC1972}"
        ProjectSection(ProjectDependencies) =3D postProject
                {65FA97EA-A569-4FC1-BFE7-D68E109143F7} =3D {65FA97EA-A569-4=
FC1-BFE7-D68E109143F7}
                {58F5BC43-B92E-4A2B-975D-0066EAB29092} =3D {58F5BC43-B92E-4=
A2B-975D-0066EAB29092}
                {EF236371-3145-41B1-99C9-82B33E353F17} =3D {EF236371-3145-4=
1B1-99C9-82B33E353F17}
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD} =3D {D7411B2C-2C43-4=
34D-9F56-E10A3D2F5BAD}
        EndProjectSection
 EndProject
 Global
@@ -44,14 +38,6 @@ Global
                {65FA97EA-A569-4FC1-BFE7-D68E109143F7}.Windows 10 Release|W=
in32.Build.0 =3D Windows 10 Release|Win32
                {65FA97EA-A569-4FC1-BFE7-D68E109143F7}.Windows 10 Release|x=
64.ActiveCfg =3D Windows 10 Release|x64
                {65FA97EA-A569-4FC1-BFE7-D68E109143F7}.Windows 10 Release|x=
64.Build.0 =3D Windows 10 Release|x64
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}.Windows 10 Debug|Win=
32.ActiveCfg =3D Windows 10 Debug|Win32
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}.Windows 10 Debug|Win=
32.Build.0 =3D Windows 10 Debug|Win32
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}.Windows 10 Debug|x64=
.ActiveCfg =3D Windows 10 Debug|x64
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}.Windows 10 Debug|x64=
.Build.0 =3D Windows 10 Debug|x64
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}.Windows 10 Release|W=
in32.ActiveCfg =3D Windows 10 Release|Win32
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}.Windows 10 Release|W=
in32.Build.0 =3D Windows 10 Release|Win32
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}.Windows 10 Release|x=
64.ActiveCfg =3D Windows 10 Release|x64
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}.Windows 10 Release|x=
64.Build.0 =3D Windows 10 Release|x64
                {EF236371-3145-41B1-99C9-82B33E353F17}.Windows 10 Debug|Win=
32.ActiveCfg =3D Windows 10 Debug|Win32
                {EF236371-3145-41B1-99C9-82B33E353F17}.Windows 10 Debug|Win=
32.Build.0 =3D Windows 10 Debug|Win32
                {EF236371-3145-41B1-99C9-82B33E353F17}.Windows 10 Debug|x64=
.ActiveCfg =3D Windows 10 Debug|x64
diff --git a/vs2022/package/package.vcxproj b/vs2022/package/package.vcxpro=
j
index 2a7d9f2..9c7c813 100644
--- a/vs2022/package/package.vcxproj
+++ b/vs2022/package/package.vcxproj
@@ -49,9 +49,6 @@
     <ProjectReference Include=3D"..\xenvbd\xenvbd.vcxproj">
       <Project>{ef236371-3145-41b1-99c9-82b33e353f17}</Project>
     </ProjectReference>
-    <ProjectReference Include=3D"..\xendisk\xendisk.vcxproj">
-      <Project>{d7411b2c-2c43-434d-9f56-e10a3d2f5bad}</Project>
-    </ProjectReference>
     <FilesToPackage Include=3D"..\xenvbd.inf" />
   </ItemGroup>
   <ItemGroup Condition=3D"Exists('$(DPINST_REDIST)')">
diff --git a/vs2022/xendisk/xendisk.vcxproj b/vs2022/xendisk/xendisk.vcxpro=
j
deleted file mode 100644
index d7df663..0000000
--- a/vs2022/xendisk/xendisk.vcxproj
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version=3D"1.0" encoding=3D"utf-8"?>
-<Project DefaultTargets=3D"Build" ToolsVersion=3D"15.0" xmlns=3D"http://sc=
hemas.microsoft.com/developer/msbuild/2003">
-  <Import Project=3D"..\configs.props" />
-  <PropertyGroup Label=3D"PropertySheets">
-    <DriverType>WDM</DriverType>
-    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
-    <ConfigurationType>Driver</ConfigurationType>
-  </PropertyGroup>
-  <Import Project=3D"$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Label=3D"Globals">
-    <ProjectGuid>{D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}</ProjectGuid>
-  </PropertyGroup>
-  <Import Project=3D"..\targets.props" />
-  <Import Project=3D"$(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)</AdditionalOptio=
ns>
-      <AdditionalIncludeDirectories>..\..\include;..\..\src\common;%(Addit=
ionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>PROJECT=3D$(ProjectName);POOL_NX_OPTIN=3D1;=
%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <WarningLevel>EnableAllWarnings</WarningLevel>
-      <DisableSpecificWarnings>4061;4464;4548;4770;4711;4820;4668;4255;504=
5;6001;6054;26451;28196;30030;30029;%(DisableSpecificWarnings)</DisableSpec=
ificWarnings>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-    </ClCompile>
-    <ResourceCompile>
-      <AdditionalIncludeDirectories>..\..\include;..\..\src\common;%(Addit=
ionalIncludeDirectories)</AdditionalIncludeDirectories>
-    </ResourceCompile>
-    <Link>
-      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDepende=
ncies>
-      <AdditionalOptions>/INTEGRITYCHECK %(AdditionalOptions)</AdditionalO=
ptions>
-      <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGener=
ation>
-      <CETCompat>true</CETCompat>
-      <GenerateMapFile>true</GenerateMapFile>
-      <MapExports>true</MapExports>
-    </Link>
-    <DriverSign>
-      <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
-    </DriverSign>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition=3D"'$(Platform)'=3D=3D'x64'">
-    <ClCompile>
-      <PreprocessorDefinitions>__x86_64__;%(PreprocessorDefinitions)</Prep=
rocessorDefinitions>
-    </ClCompile>
-    <Link>
-      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition=3D"'$(Configuration)'=3D=3D'Windows 10 Re=
lease'">
-    <ClCompile>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <WholeProgramOptimization>true</WholeProgramOptimization>
-      <AdditionalOptions>/Qspectre %(AdditionalOptions)</AdditionalOptions=
>
-    </ClCompile>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <FilesToPackage Include=3D"$(TargetPath)" />
-    <FilesToPackage Include=3D"$(OutDir)$(TargetName).pdb" />
-    <FilesToPackage Include=3D"$(OutDir)$(TargetName).map" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include=3D"../../src/xendisk/driver.c" />
-    <ClCompile Include=3D"../../src/xendisk/fdo.c" />
-    <ClCompile Include=3D"../../src/xendisk/pdo.c" />
-    <ClCompile Include=3D"../../src/xendisk/registry.c" />
-    <ClCompile Include=3D"../../src/xendisk/thread.c" />
-  </ItemGroup>
-  <ItemGroup>
-    <ResourceCompile Include=3D"..\..\src\xendisk\xendisk.rc" />
-  </ItemGroup>
-  <Import Project=3D"$(VCTargetsPath)\Microsoft.Cpp.targets" />
-</Project>
diff --git a/vs2022/xendisk/xendisk.vcxproj.user b/vs2022/xendisk/xendisk.v=
cxproj.user
deleted file mode 100644
index e1315db..0000000
--- a/vs2022/xendisk/xendisk.vcxproj.user
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version=3D"1.0" encoding=3D"utf-8"?>
-<Project ToolsVersion=3D"15.0" xmlns=3D"http://schemas.microsoft.com/devel=
oper/msbuild/2003">
-  <PropertyGroup>
-    <SignMode>TestSign</SignMode>
-    <TestCertificate>..\..\src\xenvbd.pfx</TestCertificate>
-    <TimeStampServer>http://timestamp.verisign.com/scripts/timstamp.dll</T=
imeStampServer>
-  </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}") =3D "=
xencrsh", "xencrsh\xencrsh.
                {65FA97EA-A569-4FC1-BFE7-D68E109143F7} =3D {65FA97EA-A569-4=
FC1-BFE7-D68E109143F7}
        EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") =3D "xendisk", "xendisk\=
xendisk.vcxproj", "{D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}"
-       ProjectSection(ProjectDependencies) =3D postProject
-               {65FA97EA-A569-4FC1-BFE7-D68E109143F7} =3D {65FA97EA-A569-4=
FC1-BFE7-D68E109143F7}
-       EndProjectSection
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") =3D "package", "package\=
package.vcxproj", "{AB8DAED3-9D70-4907-99A3-C643F1FC1972}"
        ProjectSection(ProjectDependencies) =3D postProject
                {65FA97EA-A569-4FC1-BFE7-D68E109143F7} =3D {65FA97EA-A569-4=
FC1-BFE7-D68E109143F7}
                {58F5BC43-B92E-4A2B-975D-0066EAB29092} =3D {58F5BC43-B92E-4=
A2B-975D-0066EAB29092}
                {EF236371-3145-41B1-99C9-82B33E353F17} =3D {EF236371-3145-4=
1B1-99C9-82B33E353F17}
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD} =3D {D7411B2C-2C43-4=
34D-9F56-E10A3D2F5BAD}
        EndProjectSection
 EndProject
 Global
@@ -38,10 +32,6 @@ Global
                {65FA97EA-A569-4FC1-BFE7-D68E109143F7}.Windows 10 Debug|x64=
.Build.0 =3D Windows 10 Debug|x64
                {65FA97EA-A569-4FC1-BFE7-D68E109143F7}.Windows 10 Release|x=
64.ActiveCfg =3D Windows 10 Release|x64
                {65FA97EA-A569-4FC1-BFE7-D68E109143F7}.Windows 10 Release|x=
64.Build.0 =3D Windows 10 Release|x64
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}.Windows 10 Debug|x64=
.ActiveCfg =3D Windows 10 Debug|x64
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}.Windows 10 Debug|x64=
.Build.0 =3D Windows 10 Debug|x64
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}.Windows 10 Release|x=
64.ActiveCfg =3D Windows 10 Release|x64
-               {D7411B2C-2C43-434D-9F56-E10A3D2F5BAD}.Windows 10 Release|x=
64.Build.0 =3D Windows 10 Release|x64
                {EF236371-3145-41B1-99C9-82B33E353F17}.Windows 10 Debug|x64=
.ActiveCfg =3D Windows 10 Debug|x64
                {EF236371-3145-41B1-99C9-82B33E353F17}.Windows 10 Debug|x64=
.Build.0 =3D Windows 10 Debug|x64
                {EF236371-3145-41B1-99C9-82B33E353F17}.Windows 10 Release|x=
64.ActiveCfg =3D Windows 10 Release|x64
--
2.53.0.windows.1



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Fri Mar 06 11:34:57 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Fri, 06 Mar 2026 11:34:57 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1247648.1546173 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vyTSK-0004Rp-9d; Fri, 06 Mar 2026 11:34:56 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1247648.1546173; Fri, 06 Mar 2026 11:34:56 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vyTSK-0004Ri-6d; Fri, 06 Mar 2026 11:34:56 +0000
Received: by outflank-mailman (input) for mailman id 1247648;
 Fri, 06 Mar 2026 11:34:55 +0000
Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254]
 helo=se1-gles-sth1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=kxzm=BG=citrix.com=owen.smith@srs-se1.protection.inumbo.net>)
 id 1vyTSJ-0004Rc-6b
 for win-pv-devel@lists.xenproject.org; Fri, 06 Mar 2026 11:34:55 +0000
Received: from DM5PR21CU001.outbound.protection.outlook.com
 (mail-centralusazlp170110009.outbound.protection.outlook.com
 [2a01:111:f403:c111::9])
 by se1-gles-sth1.inumbo.com (Halon) with ESMTPS
 id 7dc92a5c-1950-11f1-b164-2bf370ae4941;
 Fri, 06 Mar 2026 12:34:53 +0100 (CET)
Received: from SA6PR03MB7760.namprd03.prod.outlook.com (2603:10b6:806:43c::5)
 by DSWPR03MB989129.namprd03.prod.outlook.com (2603:10b6:8:35e::9)
 with Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9654.22; Fri, 6 Mar
 2026 11:34:49 +0000
Received: from SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38]) by SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38%7]) with mapi id 15.20.9678.017; Fri, 6 Mar 2026
 11:34:49 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: 7dc92a5c-1950-11f1-b164-2bf370ae4941
ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;
 b=wHAZNJdEyyKFRqw+wpN8VmJXNC40z3N3BIHdtiSRhOh34AFva/bGS8QzdVYs5PNYbyZon99mVaQoUdDkrFgZPKwf98fLfMtGPCaDF+AAw59+kTLoQ1UkeABpq0aBbPYO+quhxJ46HCXjAymVfRDCfY6tEWCKTbI4unKb50c1ORGiZT+8C76fcl0fh2e2Zc657ACZkOHY1x1M/X+dcd0Nu7O4tT2/TuMKY39yU/RlhYAXNj/mXg2glX2UpVSKO6+yi720ln0QuASVP4VLoTI5ez/Y2UzPExzQGIXGx4gmSG5gEM62CGpNUYL0JWJzECpR0Dg3rE0hsWKqnTY64A1jHg==
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=sXXuzVJ9Y1ZDCUTmITeFsUpuVDwpztWdpHmtJu7dvgQ=;
 b=Kpwca93FE+34SvKrZd/VpCW6AKPdkJxIVFd6ykgGi31lkdHQuY26HY3AcFgNhrqaGj3la5ISsmaNvx60FlnXMJhi3U8jnsZ8Dic3NQCvjT59tXgeFLaRlMTFx3XruPhEc8ifkiVbTYJ81YEAepr2Hb1nT3pFMIbpUqRR9DleWyl+wKz4LxcgxC8ztRUVFf2ynZBJfLMk/g1B4VneJhLhCarDiZxk/3tpwFJoud6gqXI6+F0k5WfWLKwhpeFVMctJE793qKqis19BzIf4baQD6Hh8ilGGInZ4YudElMp2vx2vRQaiT/TSgpuJ1QxvWpV75b1TGEXEnp3Rap59Eh2CtQ==
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
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com;
 s=selector1;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=sXXuzVJ9Y1ZDCUTmITeFsUpuVDwpztWdpHmtJu7dvgQ=;
 b=PrZzCmpnRDrColUeChPt5csvRse/d/CZg6W+x4vNP9NGUZLSNbTRJZofJt10kcVU8PHHUkyksK9SOSVvcnfv487pPnQmTCa/tBdhHfhbCMNsjAi0U55yYupRG++jNafrTixnBYG+o9cLX3gLJp3ZHHA+UzA2i0qYg2TNO+k0bqE=
From: Owen Smith <owen.smith@citrix.com>
To: Tu Dinh <ngoc-tu.dinh@vates.tech>, "win-pv-devel@lists.xenproject.org"
	<win-pv-devel@lists.xenproject.org>
Subject: Re: [PATCH] Use direct hypercall instead of hypercall page
Thread-Topic: [PATCH] Use direct hypercall instead of hypercall page
Thread-Index: AQHcrLlmSrnEliHBT06Hvz9uApFt27WhXoBQ
Date: Fri, 6 Mar 2026 11:34:49 +0000
Message-ID:
 <SA6PR03MB77601B24ED277E02AAC4E94DFE7AA@SA6PR03MB7760.namprd03.prod.outlook.com>
References: <20260305160136.1704-1-ngoc-tu.dinh@vates.tech>
In-Reply-To: <20260305160136.1704-1-ngoc-tu.dinh@vates.tech>
Accept-Language: en-GB, en-US
Content-Language: en-GB
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
msip_labels:
authentication-results: dkim=none (message not signed)
 header.d=none;dmarc=none action=none header.from=citrix.com;
x-ms-publictraffictype: Email
x-ms-traffictypediagnostic: SA6PR03MB7760:EE_|DSWPR03MB989129:EE_
x-ms-office365-filtering-correlation-id: 91ac3c0d-cd88-48d4-a519-08de7b746061
x-ms-exchange-senderadcheck: 1
x-ms-exchange-antispam-relay: 0
x-microsoft-antispam: BCL:0;ARA:13230040|366016|376014|1800799024|38070700021;
x-microsoft-antispam-message-info:
 jg3vuKAWFJvBHcpf29t1ugsGnK4Gim4Q+IO1AO8c0iBV/0heYlN/JroGTfJBm+8YiWGbHbYk8pVzCbYL5cZ/F+ST7/P0/Dwz3YmonFnOuOh9aXcFbru9JfjW7Ktr9H2GF7wrKG1+1qoiBjOqZEJ3Q/8PbH0lVQvnGNazrOjtGSA66RCw29qbUotg808jVuDOVk/XctR05zDoLuzkh/qN9PRiBkHEOiwDaKUsk2pXIDeYnAedFH6DdmMcu1uFgseBibtyHk3kyJjCT89IRApKBuwSZ0gN0E1PReiQsZ7l1kFDyRoKFm031WGlJXS/HnpmMBelvOWerlQUGURu2H4GTVzNvMHQe1K1q53jj5NhuVnduGB9Xt5LdmXFZ6opZhghyT8tTdVSAyoddG8eoetTi9aM4hMIV2BN/aspVGYKfq4owWuo2ZR9Jl5nHa1NT4WhNxg7A0zRmkivlfsETxLdbShEdJjBXdd1qwJ/fYDIAxprUAgjhwgiWf03u6fYiFq/0gM89lDc91sVUd4xshl9qt4ojgQn9UzFar+D8LPpFJoBIYAGxarWvqAp/+PMOJs5UJY2dRWyAjOOyaAxx035UsJj36O9EL9mKLXLdHpSobfTzhjVX/WuEL7YLAi1/f7yOp4x7SDYKmdo+SfFbAEcVgt0O2sOV6CvkDVSRsQ8S5l2NutnXt88vfaJ1FZzNf9UM9ZeApGwGhxOhPBtFqsM/+mLOhmn+UGwkGVIHxw7nCs=
x-forefront-antispam-report:
 CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SA6PR03MB7760.namprd03.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(366016)(376014)(1800799024)(38070700021);DIR:OUT;SFP:1101;
x-ms-exchange-antispam-messagedata-chunkcount: 1
x-ms-exchange-antispam-messagedata-0:
 =?us-ascii?Q?ur5YLv3TmFL/cEXzAMuKPoFHwyIfI3Smc9NOPFj3s1qA/emxWcZ59CJw3CGL?=
 =?us-ascii?Q?b+ipjtANeHSZKY0ireJYJKzfHB5hz4pXcbKn3QSfcRxOYeulWtYBwzozfhXz?=
 =?us-ascii?Q?KXm/JS3WsvexZaN1r2fFcUYyn5+GKBlKSWdD7/cHnJjy6LPuh7qFG0gRQeFE?=
 =?us-ascii?Q?4H3tJlJ7UYjdxx8dLSVxvoGyNqx/VMayCKk9jOoBc4bxKK8HyoX07JFXM57R?=
 =?us-ascii?Q?1Ju7pCnyR5A52AdQq4EMtavykZLFSCSS4uH6qpb/JL8Pg+NaBYUxuWCQ/OOQ?=
 =?us-ascii?Q?IJYdw8tgGLx/BP9a5UTfkcPiC9OzN/eIuss3M0r8QeKJAPYT2fiXlatqRuJz?=
 =?us-ascii?Q?sb/CNAeSewkubGSuqE3lPZ0eGKI6ApSupPH2prKttW4Rm8sMOUjlwi1oLpaG?=
 =?us-ascii?Q?9guwWVrNtRxgNJsrHTr/OB3bn6Raz3+6NHbg1qeskFlThK4D6l1g2PMV4uio?=
 =?us-ascii?Q?f0JXg4uyURTSfMDsj16FYNbAyzK862RQvwBSLwx3NrbXJz/s1pN7QSCkUjXp?=
 =?us-ascii?Q?xUVN8sLG3ycHYaSRMzafqVhnXyay2jQ2D4ewmPwqGDc8em4RWlv12HTuIltl?=
 =?us-ascii?Q?sJrzUfGMj9lkUX9PftZDfJSBrKRHkp1ls4C2+NREbQJYK/PpYFXN2JtDWX/o?=
 =?us-ascii?Q?RFeZ9GLRinFckCS4kZlnHSPWD3P2myyHkOSes1sN+mRjUci7rgYj1MWve/ip?=
 =?us-ascii?Q?GqELXvGTPWQYuzvAc9tZeauX8dpbX6wdUF/iAJMcUR7SGlcsDZdZ3BaU1t+x?=
 =?us-ascii?Q?w6CRdsPRGNlGB+mLZZauhgX9IMNnf1NiPFiK0xZchw+OYPwMZfq8nML4snQM?=
 =?us-ascii?Q?hQQvdvCOKsRGIO2RC32wLRXypX7GLLYB10/XKQqGknhikbKrfY6qAlwBNfMx?=
 =?us-ascii?Q?CDGEUFOpWiVuUN7PqfqzNocvJMtLnFD0C09VleSzdWQCLZ4anaIpyDbx0dgR?=
 =?us-ascii?Q?H/tLjdwoZQ9EujgYB6jrXyluk+sh/486wjc9M1AASEzjLhTk1CJdComJvSob?=
 =?us-ascii?Q?CVELQQ0qS6fK51RPg3cCYssVWjeLq3JBOhe5FpTv2CXgBM6XvTWLmfW5rVPf?=
 =?us-ascii?Q?RSHBj6rzniGIPVDo+VH4dR3AwwZrzY41od7nY1LDbQQBoRUjEu5Xg2Bn0TLE?=
 =?us-ascii?Q?RnCj5Rn/gxFGO3Ow1ouxUpm5v30QVdGe/kA+HKpIzoFHOUQGwJ9c+iW7Gi6j?=
 =?us-ascii?Q?Lw7b4rF6ncYXHcLOtpMv4kNTwjtWLl8TJX2IveY+w3BCZMzBHX73IY+PoASp?=
 =?us-ascii?Q?JbLyWivx9USY3WsYKzz1pwKb2teHv8JXqibUBJmF1K3i9eML16MVC+4sg30k?=
 =?us-ascii?Q?7OUu46eORgB8I0os2MXn09caG2sKAqkXMTIxqulelKArGx8Hmwk6caIi2K7y?=
 =?us-ascii?Q?ZIu7aSKFEnFuOb6M2qleB+apf0hKSHPJkhy0Q3x7fV7oMvgoYKEbOreSJt66?=
 =?us-ascii?Q?aXBGIwgCksfRWsJdgLRcj0x77Z/EYu4ASZok2GB6Xw07PhlFy7p7wWQdQ3Lp?=
 =?us-ascii?Q?U889e/2wv8e92Ox+YtqwJawXYTH5dw5Ouy9MxTOo95Msvl+B67L9/dDPDEQa?=
 =?us-ascii?Q?nQcxpI+oj0TgL0+PJogQToCx9Z1sit7Lp2WZD5/pTvYLg1KzrYwXvNDDdURf?=
 =?us-ascii?Q?0TkYsEQTPvnhJRc3LUHQ+AYssNOOA3Wo3qAqNvKZN4JV/X6J0pNo2tVagJFq?=
 =?us-ascii?Q?8Or0YC+exVBpdYrIsmlRxoloOXBhAVGdhLrUL6IpSZCZqxLlCobhzYXZ95za?=
 =?us-ascii?Q?zGwoZe05og=3D=3D?=
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
X-OriginatorOrg: citrix.com
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-AuthSource: SA6PR03MB7760.namprd03.prod.outlook.com
X-MS-Exchange-CrossTenant-Network-Message-Id: 91ac3c0d-cd88-48d4-a519-08de7b746061
X-MS-Exchange-CrossTenant-originalarrivaltime: 06 Mar 2026 11:34:49.6023
 (UTC)
X-MS-Exchange-CrossTenant-fromentityheader: Hosted
X-MS-Exchange-CrossTenant-id: 335836de-42ef-43a2-b145-348c2ee9ca5b
X-MS-Exchange-CrossTenant-mailboxtype: HOSTED
X-MS-Exchange-CrossTenant-userprincipalname: X+BwA6zdiccmpVRYRBryfoLs7UNMM5pbbJ7FtjIVCzzZOd1+3khObPKeja+ncJcl5G6vIWm4+u4DSqm3BMY4BQ==
X-MS-Exchange-Transport-CrossTenantHeadersStamped: DSWPR03MB989129

There are a few whitespace issues in the amd64 asm, which I can correct
before applying.

Reviewed-by: Owen Smith <owen.smith@citrix.com>

________________________________________
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
Sent: 05 March 2026 4:01 PM
To: win-pv-devel@lists.xenproject.org
Cc: Owen Smith; Tu Dinh
Subject: [PATCH] Use direct hypercall instead of hypercall page

XSA-466 "Xen hypercall page unsafe against speculative attacks"
recommends that OSes avoid using the hypercall page, since that breaks
the use of return thunks and CET IBT.

While Windows doesn't support return thunks or CET IBT, the current
hypercall code uses a naked indirect call to call into the hypercall
page. This call is not protected by Windows CFG, and cannot be patched
by Windows's Retpoline implementation.

Convert the hypercall code to detect CPU vendor and use the appropriate
hypercall instructions.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
---
 include/xen.h                     |   8 --
 src/xen/amd64/hypercall_thunk.asm | 101 +++++++++++-----
 src/xen/driver.c                  |  33 +++---
 src/xen/hypercall.c               | 191 +++++++++++++++++-------------
 src/xen/hypercall.h               |   2 +-
 src/xen/i386/hypercall_thunk.asm  |  69 ++++++++---
 src/xenbus/fdo.c                  |   2 -
 src/xenbus/suspend.c              |   2 -
 8 files changed, 254 insertions(+), 154 deletions(-)

diff --git a/include/xen.h b/include/xen.h
index 8691a0f..0c3e8a4 100644
--- a/include/xen.h
+++ b/include/xen.h
@@ -76,14 +76,6 @@ XenTouch(
     _In_ ULONG      BuildNumber
     );

-// HYPERCALL
-
-XEN_API
-VOID
-HypercallPopulate(
-    VOID
-    );
-
 // HVM

 _Check_return_
diff --git a/src/xen/amd64/hypercall_thunk.asm b/src/xen/amd64/hypercall_th=
unk.asm
index af045bb..b32ee2e 100644
--- a/src/xen/amd64/hypercall_thunk.asm
+++ b/src/xen/amd64/hypercall_thunk.asm
@@ -3,39 +3,76 @@

                         .code

-                        extrn   Hypercall:qword
+                        ; uintptr_t __stdcall hypercall2_vmcall(
+                        ;     uint32_t    ord,
+                        ;     uintptr_t   arg1,
+                        ;     uintptr_t   arg2);
+                        public hypercall2_vmcall
+hypercall2_vmcall       proc
+                        push   rdi
+                        push   rsi
+                        mov     eax, ecx                            ; ord
+                        mov            rdi, rdx                           =
 ; arg1
+                        mov            rsi, r8                            =
 ; arg2
+                        vmcall
+                        pop            rsi
+                        pop            rdi
+                        ret
+hypercall2_vmcall       endp

-                        ; uintptr_t __stdcall hypercall2(uint32_t ord, uin=
tptr_t arg1, uintptr_t arg2);
-                        public hypercall2
-hypercall2             proc
-                       push rdi
-                       push rsi
-                       mov rdi, rdx                            ; arg1
-                       mov rax, qword ptr [Hypercall]
-                       shl rcx, 5                              ; ord
-                       add rax, rcx
-                       mov rsi, r8                             ; arg2
-                       call rax
-                       pop rsi
-                       pop rdi
-                       ret
-hypercall2             endp
+                        ; uintptr_t __stdcall hypercall2_vmmcall(
+                        ;     uint32_t    ord,
+                        ;     uintptr_t   arg1,
+                        ;     uintptr_t   arg2);
+                        public hypercall2_vmmcall
+hypercall2_vmmcall      proc
+                        push   rdi
+                        push   rsi
+                        mov     eax, ecx                            ; ord
+                        mov            rdi, rdx                           =
 ; arg1
+                        mov            rsi, r8                            =
 ; arg2
+                        vmmcall
+                        pop            rsi
+                        pop            rdi
+                        ret
+hypercall2_vmmcall      endp

-                        ; uintptr_t __stdcall hypercall3(uint32_t ord, uin=
tptr_t arg1, uintptr_t arg2, uintptr_t arg3);
-                        public hypercall3
-hypercall3             proc
-                       push rdi
-                       push rsi
-                       mov rdi, rdx                            ; arg1
-                       mov rax, qword ptr [Hypercall]
-                       shl rcx, 5                              ; ord
-                       add rax, rcx
-                       mov rsi, r8                             ; arg2
-                       mov rdx, r9                             ; arg3
-                       call rax
-                       pop rsi
-                       pop rdi
-                       ret
-hypercall3             endp
+                        ; uintptr_t __stdcall hypercall3_vmcall(
+                        ;     uint32_t    ord,
+                        ;     uintptr_t   arg1,
+                        ;     uintptr_t   arg2,
+                        ;     uintptr_t   arg3);
+                        public hypercall3_vmcall
+hypercall3_vmcall       proc
+                        push    rdi
+                        push    rsi
+                        mov     eax, ecx                            ; ord
+                        mov     rdi, rdx                            ; arg1
+                        mov     rsi, r8                             ; arg2
+                        mov     rdx, r9                             ; arg3
+                        vmcall
+                        pop     rsi
+                        pop     rdi
+                        ret
+hypercall3_vmcall       endp
+
+                        ; uintptr_t __stdcall hypercall3_vmmcall(
+                        ;     uint32_t    ord,
+                        ;     uintptr_t   arg1,
+                        ;     uintptr_t   arg2,
+                        ;     uintptr_t   arg3);
+                        public hypercall3_vmmcall
+hypercall3_vmmcall      proc
+                        push    rdi
+                        push    rsi
+                        mov     eax, ecx                            ; ord
+                        mov     rdi, rdx                            ; arg1
+                        mov     rsi, r8                             ; arg2
+                        mov     rdx, r9                             ; arg3
+                        vmmcall
+                        pop     rsi
+                        pop     rdi
+                        ret
+hypercall3_vmmcall      endp

                         end
diff --git a/src/xen/driver.c b/src/xen/driver.c
index 7b2621b..0bed6d1 100644
--- a/src/xen/driver.c
+++ b/src/xen/driver.c
@@ -621,31 +621,33 @@ DllInitialize(

     __DriverSetMemoryKey(MemoryKey);

-    HypercallInitialize();
+    status =3D HypercallInitialize();
+    if (!NT_SUCCESS(status))
+        goto fail8;

     status =3D AcpiInitialize();
     if (!NT_SUCCESS(status))
-        goto fail8;
+        goto fail9;

     status =3D SystemInitialize();
     if (!NT_SUCCESS(status))
-        goto fail9;
+        goto fail10;

     status =3D BugCheckInitialize();
     if (!NT_SUCCESS(status))
-        goto fail10;
+        goto fail11;

     status =3D ModuleInitialize();
     if (!NT_SUCCESS(status))
-        goto fail11;
+        goto fail12;

     status =3D ProcessInitialize();
     if (!NT_SUCCESS(status))
-        goto fail12;
+        goto fail13;

     status =3D UnplugInitialize();
     if (!NT_SUCCESS(status))
-        goto fail13;
+        goto fail14;

     RegistryCloseKey(ServiceKey);

@@ -653,36 +655,39 @@ DllInitialize(

     return STATUS_SUCCESS;

+fail14:
+    Error("fail14\n");
+
+    ProcessTeardown();
+
 fail13:
     Error("fail13\n");

-    ProcessTeardown();
+    ModuleTeardown();

 fail12:
     Error("fail12\n");

-    ModuleTeardown();
+    BugCheckTeardown();

 fail11:
     Error("fail11\n");

-    BugCheckTeardown();
+    SystemTeardown();

 fail10:
     Error("fail10\n");

-    SystemTeardown();
+    AcpiTeardown();

 fail9:
     Error("fail9\n");

-    AcpiTeardown();
+    HypercallTeardown();

 fail8:
     Error("fail8\n");

-    HypercallTeardown();
-
     RegistryCloseKey(MemoryKey);
     __DriverSetMemoryKey(NULL);

diff --git a/src/xen/hypercall.c b/src/xen/hypercall.c
index 911ae4f..3c68709 100644
--- a/src/xen/hypercall.c
+++ b/src/xen/hypercall.c
@@ -30,9 +30,6 @@
  * SUCH DAMAGE.
  */

-#undef  XEN_API
-#define XEN_API __declspec(dllexport)
-
 #include <ntddk.h>
 #include <xen.h>
 #include <intrin.h>
@@ -42,55 +39,63 @@
 #include "assert.h"
 #include "util.h"

-#define MAXIMUM_HYPERCALL_PAGE_COUNT 2
-
-#pragma code_seg("hypercall")
-__declspec(allocate("hypercall"))
-static UCHAR        __Section[(MAXIMUM_HYPERCALL_PAGE_COUNT + 1) * PAGE_SI=
ZE];
-
-static ULONG        XenBaseLeaf =3D 0x40000000;
-
-static PHYSICAL_ADDRESS HypercallPage[MAXIMUM_HYPERCALL_PAGE_COUNT];
-static ULONG            HypercallPageCount;
-static BOOLEAN          HypercallPageInitialized;
-
-typedef UCHAR           HYPERCALL_GATE[32];
-typedef HYPERCALL_GATE  *PHYPERCALL_GATE;
-
-PHYPERCALL_GATE     Hypercall;
-ULONG               HypercallMsr;
-
-XEN_API
-VOID
-HypercallPopulate(
-    VOID
-    )
-{
-    ULONG       Index;
-
-    for (Index =3D 0; Index < HypercallPageCount; Index++) {
-        LogPrintf(LOG_LEVEL_INFO,
-                  "XEN: HYPERCALL PAGE %d @ %08x.%08x\n",
-                  Index,
-                  HypercallPage[Index].HighPart,
-                  HypercallPage[Index].LowPart);
-
-        __writemsr(HypercallMsr, HypercallPage[Index].QuadPart);
-    }
-
-    HypercallPageInitialized =3D TRUE;
-}
-
-VOID
+typedef enum _HYPERCALL_INSTRUCTION {
+    HYPERCALL_INSTRUCTION_UNKNOWN,
+    HYPERCALL_INSTRUCTION_VMCALL,
+    HYPERCALL_INSTRUCTION_VMMCALL,
+} HYPERCALL_INSTRUCTION;
+
+typedef struct _CPU_VENDOR_DATA {
+    ULONG                   EBX;
+    ULONG                   ECX;
+    ULONG                   EDX;
+    HYPERCALL_INSTRUCTION   Instruction;
+} CPU_VENDOR_DATA;
+
+static const CPU_VENDOR_DATA    HypercallVendorData[] =3D {
+    // Note that the vendor data goes EBX-ECX-EDX
+    {
+        // "GenuineIntel"
+        0x756E6547, 0x6C65746E, 0x49656E69,
+        HYPERCALL_INSTRUCTION_VMCALL
+    },
+    {
+        // "AuthenticAMD"
+        0x68747541, 0x444D4163, 0x69746E65,
+        HYPERCALL_INSTRUCTION_VMMCALL
+    },
+    {
+        // "CentaurHauls"
+        0x746E6543, 0x736C7561, 0x48727561,
+        HYPERCALL_INSTRUCTION_VMCALL
+    },
+    {
+        // "  Shanghai  "
+        0x68532020, 0x20206961, 0x68676E61,
+        HYPERCALL_INSTRUCTION_VMCALL
+    },
+    {
+        // "HygonGenuine"
+        0x6F677948, 0x656E6975, 0x6E65476E,
+        HYPERCALL_INSTRUCTION_VMMCALL
+    },
+};
+
+static HYPERCALL_INSTRUCTION    HypercallInstruction
+    =3D HYPERCALL_INSTRUCTION_UNKNOWN;
+
+NTSTATUS
 HypercallInitialize(
     VOID
     )
 {
-    ULONG       EAX =3D 'DEAD';
-    ULONG       EBX =3D 'DEAD';
-    ULONG       ECX =3D 'DEAD';
-    ULONG       EDX =3D 'DEAD';
-    ULONG_PTR   Index;
+    ULONG                   XenBaseLeaf =3D 0x40000000;
+    ULONG                   EAX =3D 'DEAD';
+    ULONG                   EBX =3D 'DEAD';
+    ULONG                   ECX =3D 'DEAD';
+    ULONG                   EDX =3D 'DEAD';
+    HYPERCALL_INSTRUCTION   Instruction =3D HYPERCALL_INSTRUCTION_UNKNOWN;
+    ULONG                   Index;

     for (;;) {
         CHAR    Signature[13] =3D {0};
@@ -103,13 +108,13 @@ HypercallInitialize(
         if (strcmp(Signature, "XenVMMXenVMM") =3D=3D 0 &&
             EAX >=3D XenBaseLeaf + 2)
             break;
-
+
         XenBaseLeaf +=3D 0x100;
-
+
         if (XenBaseLeaf > 0x40000100) {
             LogPrintf(LOG_LEVEL_INFO,
                       "XEN: BASE CPUID LEAF NOT FOUND\n");
-            return;
+            return STATUS_NOT_SUPPORTED;
         }
     }

@@ -117,27 +122,46 @@ HypercallInitialize(
               "XEN: BASE CPUID LEAF @ %08x\n",
               XenBaseLeaf);

-    if ((ULONG_PTR)__Section & (PAGE_SIZE - 1))
-        Hypercall =3D (PVOID)(((ULONG_PTR)__Section + PAGE_SIZE - 1) & ~(P=
AGE_SIZE - 1));
-    else
-        Hypercall =3D (PVOID)__Section;
-
-    ASSERT3U(((ULONG_PTR)Hypercall & (PAGE_SIZE - 1)), =3D=3D, 0);
+    __CpuId(0, &EAX, &EBX, &ECX, &EDX);
+    for (Index =3D 0; Index < ARRAYSIZE(HypercallVendorData); Index++) {
+        const CPU_VENDOR_DATA   *CurrentData =3D &HypercallVendorData[Inde=
x];

-    for (Index =3D 0; Index < MAXIMUM_HYPERCALL_PAGE_COUNT; Index++)
-        HypercallPage[Index] =3D MmGetPhysicalAddress((PUCHAR)Hypercall +
-                                                    (Index << PAGE_SHIFT))=
;
+        if (EBX =3D=3D CurrentData->EBX &&
+            ECX =3D=3D CurrentData->ECX &&
+            EDX =3D=3D CurrentData->EDX) {
+            Instruction =3D CurrentData->Instruction;
+            break;
+        }
+    }

-    __CpuId(XenBaseLeaf + 2, &EAX, &EBX, NULL, NULL);
-    HypercallPageCount =3D EAX;
-    ASSERT(HypercallPageCount <=3D MAXIMUM_HYPERCALL_PAGE_COUNT);
-    HypercallMsr =3D EBX;
+    if (Instruction =3D=3D HYPERCALL_INSTRUCTION_UNKNOWN) {
+        LogPrintf(LOG_LEVEL_INFO,
+                  "XEN: CANNOT DETECT HYPERCALL INSTRUCTION\n");
+        return STATUS_NOT_SUPPORTED;
+    }

-    HypercallPopulate();
+    HypercallInstruction =3D Instruction;
+    return STATUS_SUCCESS;
 }

-extern uintptr_t __stdcall hypercall2(uint32_t ord, uintptr_t arg1, uintpt=
r_t arg2);
-extern uintptr_t __stdcall hypercall3(uint32_t ord, uintptr_t arg1, uintpt=
r_t arg2, uintptr_t arg3);
+extern uintptr_t __stdcall hypercall2_vmcall(
+    uint32_t    ord,
+    uintptr_t   arg1,
+    uintptr_t   arg2);
+extern uintptr_t __stdcall hypercall2_vmmcall(
+    uint32_t    ord,
+    uintptr_t   arg1,
+    uintptr_t   arg2);
+extern uintptr_t __stdcall hypercall3_vmcall(
+    uint32_t    ord,
+    uintptr_t   arg1,
+    uintptr_t   arg2,
+    uintptr_t   arg3);
+extern uintptr_t __stdcall hypercall3_vmmcall(
+    uint32_t    ord,
+    uintptr_t   arg1,
+    uintptr_t   arg2,
+    uintptr_t   arg3);

 LONG_PTR
 __Hypercall(
@@ -149,9 +173,6 @@ __Hypercall(
     va_list     Arguments;
     ULONG_PTR   Value;

-    if (!HypercallPageInitialized)
-        return -ENOSYS;
-
     va_start(Arguments, Count);
     switch (Count) {
     case 2: {
@@ -159,7 +180,16 @@ __Hypercall(
         uintptr_t  arg1 =3D va_arg(Arguments, ULONG_PTR);
         uintptr_t  arg2 =3D va_arg(Arguments, ULONG_PTR);

-        Value =3D hypercall2(ord, arg1, arg2);
+        switch (HypercallInstruction) {
+        case HYPERCALL_INSTRUCTION_VMCALL:
+            Value =3D hypercall2_vmcall(ord, arg1, arg2);
+            break;
+        case HYPERCALL_INSTRUCTION_VMMCALL:
+            Value =3D hypercall2_vmmcall(ord, arg1, arg2);
+            break;
+        default:
+            BUG("NO HYPERCALL INSTRUCTION");
+        }
         break;
     }
     case 3: {
@@ -168,7 +198,16 @@ __Hypercall(
         uintptr_t  arg2 =3D va_arg(Arguments, ULONG_PTR);
         uintptr_t  arg3 =3D va_arg(Arguments, ULONG_PTR);

-        Value =3D hypercall3(ord, arg1, arg2, arg3);
+        switch (HypercallInstruction) {
+        case HYPERCALL_INSTRUCTION_VMCALL:
+            Value =3D hypercall3_vmcall(ord, arg1, arg2, arg3);
+            break;
+        case HYPERCALL_INSTRUCTION_VMMCALL:
+            Value =3D hypercall3_vmmcall(ord, arg1, arg2, arg3);
+            break;
+        default:
+            BUG("NO HYPERCALL INSTRUCTION");
+        }
         break;
     }
     default:
@@ -185,12 +224,4 @@ HypercallTeardown(
     VOID
     )
 {
-    ULONG   Index;
-
-    Hypercall =3D NULL;
-
-    for (Index =3D 0; Index < MAXIMUM_HYPERCALL_PAGE_COUNT; Index++)
-        HypercallPage[Index].QuadPart =3D 0;
-
-    HypercallPageCount =3D 0;
 }
diff --git a/src/xen/hypercall.h b/src/xen/hypercall.h
index 306d9ab..6f4c7e0 100644
--- a/src/xen/hypercall.h
+++ b/src/xen/hypercall.h
@@ -40,7 +40,7 @@

 #include <public/xen.h>

-extern VOID
+extern NTSTATUS
 HypercallInitialize(
     VOID
     );
diff --git a/src/xen/i386/hypercall_thunk.asm b/src/xen/i386/hypercall_thun=
k.asm
index a15ae27..be68db3 100644
--- a/src/xen/i386/hypercall_thunk.asm
+++ b/src/xen/i386/hypercall_thunk.asm
@@ -5,28 +5,69 @@
                         .model  FLAT
                         .code

-                        extrn   _Hypercall:dword
+                        ; uintptr_t __stdcall hypercall2_vmcall(
+                        ;     uint32_t    ord,
+                        ;     uintptr_t   arg1,
+                        ;     uintptr_t   arg2);
+                        public _hypercall2_vmcall@12
+_hypercall2_vmcall@12   proc
+                        push    ebp
+                        mov     ebp, esp
+                        push    ebx
+                        mov     eax, [ebp + 08h]                ; ord
+                        mov     ebx, [ebp + 0ch]                ; arg1
+                        mov     ecx, [ebp + 10h]                ; arg2
+                        vmcall
+                        pop     ebx
+                        leave
+                        ret     0Ch
+_hypercall2_vmcall@12   endp

-                        ; uintptr_t __stdcall hypercall2(uint32_t ord, uin=
tptr_t arg1, uintptr_t arg2);
-                        public _hypercall2@12
-_hypercall2@12         proc
+                        ; uintptr_t __stdcall hypercall2_vmmcall(
+                        ;     uint32_t    ord,
+                        ;     uintptr_t   arg1,
+                        ;     uintptr_t   arg2);
+                        public _hypercall2_vmmcall@12
+_hypercall2_vmmcall@12  proc
                         push    ebp
                         mov     ebp, esp
                         push    ebx
                         mov     eax, [ebp + 08h]                ; ord
                         mov     ebx, [ebp + 0ch]                ; arg1
                         mov     ecx, [ebp + 10h]                ; arg2
-                        shl     eax, 5
-                        add     eax, dword ptr [_Hypercall]
-                        call    eax
+                        vmmcall
                         pop     ebx
                         leave
                         ret     0Ch
-_hypercall2@12         endp
+_hypercall2_vmmcall@12  endp
+
+                        ; uintptr_t __stdcall hypercall3_vmcall(
+                        ;     uint32_t    ord,
+                        ;     uintptr_t   arg1,
+                        ;     uintptr_t   arg2,
+                        ;     uintptr_t   arg3);
+                        public _hypercall3_vmcall@16
+_hypercall3_vmcall@16   proc
+                        push    ebp
+                        mov     ebp, esp
+                        push    ebx
+                        mov     eax, [ebp + 08h]                ; ord
+                        mov     ebx, [ebp + 0ch]                ; arg1
+                        mov     ecx, [ebp + 10h]                ; arg2
+                        mov     edx, [ebp + 14h]                ; arg3
+                        vmcall
+                        pop     ebx
+                        leave
+                        ret     10h
+_hypercall3_vmcall@16   endp

-                        ; uintptr_t __stdcall hypercall3(uint32_t ord, uin=
tptr_t arg1, uintptr_t arg2, uintptr_t arg3);
-                        public _hypercall3@16
-_hypercall3@16         proc
+                        ; uintptr_t __stdcall hypercall3_vmmcall(
+                        ;     uint32_t    ord,
+                        ;     uintptr_t   arg1,
+                        ;     uintptr_t   arg2,
+                        ;     uintptr_t   arg3);
+                        public _hypercall3_vmmcall@16
+_hypercall3_vmmcall@16  proc
                         push    ebp
                         mov     ebp, esp
                         push    ebx
@@ -34,12 +75,10 @@ _hypercall3@16      proc
                         mov     ebx, [ebp + 0ch]                ; arg1
                         mov     ecx, [ebp + 10h]                ; arg2
                         mov     edx, [ebp + 14h]                ; arg3
-                        shl     eax, 5
-                        add     eax, dword ptr [_Hypercall]
-                        call    eax
+                        vmmcall
                         pop     ebx
                         leave
                         ret     10h
-_hypercall3@16         endp
+_hypercall3_vmmcall@16  endp

                         end
diff --git a/src/xenbus/fdo.c b/src/xenbus/fdo.c
index 8695a56..a5a0ca1 100644
--- a/src/xenbus/fdo.c
+++ b/src/xenbus/fdo.c
@@ -3831,8 +3831,6 @@ FdoS4ToS3(

     LogResume();

-    HypercallPopulate();
-
     UnplugDevices();

 not_active:
diff --git a/src/xenbus/suspend.c b/src/xenbus/suspend.c
index cd292c0..687f86c 100644
--- a/src/xenbus/suspend.c
+++ b/src/xenbus/suspend.c
@@ -205,8 +205,6 @@ SuspendEarly(
     if (Cpu !=3D 0)
         return;

-    HypercallPopulate();
-
     UnplugDevices();

     for (ListEntry =3D Context->EarlyList.Flink;
--
2.51.2.windows.1



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Fri Mar 06 16:08:09 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Fri, 06 Mar 2026 16:08:09 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1247896.1546284 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vyXih-000719-6C; Fri, 06 Mar 2026 16:08:07 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1247896.1546284; Fri, 06 Mar 2026 16:08:07 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vyXih-000712-3S; Fri, 06 Mar 2026 16:08:07 +0000
Received: by outflank-mailman (input) for mailman id 1247896;
 Fri, 06 Mar 2026 16:08:06 +0000
Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254]
 helo=se1-gles-sth1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=kxzm=BG=citrix.com=owen.smith@srs-se1.protection.inumbo.net>)
 id 1vyXig-00070w-Cn
 for win-pv-devel@lists.xenproject.org; Fri, 06 Mar 2026 16:08:06 +0000
Received: from na1pdmzitismtp01.tibco.com (na1pdmzitismtp01.corp.cloud.com
 [160.101.131.8]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS
 id a81123ec-1976-11f1-b164-2bf370ae4941;
 Fri, 06 Mar 2026 17:08:04 +0100 (CET)
Received: from mewpvdipd2033.citrite.net (unknown [10.113.48.64])
 by na1pdmzitismtp01.tibco.com (Postfix) with ESMTP id 313944268FC3;
 Fri,  6 Mar 2026 11:07:40 -0500 (EST)
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: a81123ec-1976-11f1-b164-2bf370ae4941
From: Owen Smith <owen.smith@citrix.com>
To: win-pv-devel@lists.xenproject.org
Cc: Owen Smith <owen.smith@citrix.com>
Subject: [PATCH 1/2] Unplug: Set bit for NVME disk unplug
Date: Fri,  6 Mar 2026 16:07:59 +0000
Message-ID: <20260306160800.774-1-owen.smith@citrix.com>
X-Mailer: git-send-email 2.51.2.windows.1
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit

When issuing a DISK unplug command, set the bits for emulated IDE/SCSI
and emulated NVME devices.

Also defines and uses symbols to represent each bit in the unplug protocol.

Signed-off-by: Owen Smith <owen.smith@citrix.com>
---
 src/xen/unplug.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/src/xen/unplug.c b/src/xen/unplug.c
index 282ed93..3b6593a 100644
--- a/src/xen/unplug.c
+++ b/src/xen/unplug.c
@@ -49,6 +49,12 @@
 
 #define UNPLUG_TAG  'LPNU'
 
+#define UNPLUG_FLAGS_IDE_SCSI_DISKS   0x0001
+#define UNPLUG_FLAGS_ALL_NICS         0x0002
+#define UNPLUG_FLAGS_AUX_IDE_DISKS    0x0004  // ignored if UNPLUG_FLAGS_IDE_SCSI_DISKS is set
+#define UNPLUG_FLAGS_NVME_DISKS       0x0008
+#define UNPLUG_FLAGS_ALL_DISKS        (UNPLUG_FLAGS_IDE_SCSI_DISKS | UNPLUG_FLAGS_NVME_DISKS)
+
 typedef struct _UNPLUG_DATA {
     PSTR        Name;
     BOOLEAN     Found;
@@ -116,19 +122,19 @@ UnplugDeviceType(
     case UNPLUG_DISKS:
         if (Context->BootEmulated) {
 #pragma prefast(suppress:28138)
-            WRITE_PORT_USHORT((PUSHORT)0x10, 0x0004);
+            WRITE_PORT_USHORT((PUSHORT)0x10, UNPLUG_FLAGS_AUX_IDE_DISKS);
 
             LogPrintf(LOG_LEVEL_WARNING, "UNPLUG: AUX DISKS\n");
         } else {
 #pragma prefast(suppress:28138)
-            WRITE_PORT_USHORT((PUSHORT)0x10, 0x0001);
+            WRITE_PORT_USHORT((PUSHORT)0x10, UNPLUG_FLAGS_ALL_DISKS);
 
             LogPrintf(LOG_LEVEL_WARNING, "UNPLUG: DISKS\n");
         }
         break;
     case UNPLUG_NICS:
 #pragma prefast(suppress:28138)
-        WRITE_PORT_USHORT((PUSHORT)0x10, 0x0002);
+        WRITE_PORT_USHORT((PUSHORT)0x10, UNPLUG_FLAGS_ALL_NICS);
 
         LogPrintf(LOG_LEVEL_WARNING, "UNPLUG: NICS\n");
         break;
-- 
2.51.2.windows.1



From win-pv-devel-bounces@lists.xenproject.org Fri Mar 06 16:08:13 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Fri, 06 Mar 2026 16:08:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1247897.1546288 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vyXin-00072v-7c; Fri, 06 Mar 2026 16:08:13 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1247897.1546288; Fri, 06 Mar 2026 16:08:13 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vyXin-00072n-4q; Fri, 06 Mar 2026 16:08:13 +0000
Received: by outflank-mailman (input) for mailman id 1247897;
 Fri, 06 Mar 2026 16:08:11 +0000
Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254]
 helo=se1-gles-sth1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=kxzm=BG=citrix.com=owen.smith@srs-se1.protection.inumbo.net>)
 id 1vyXil-00070w-Re
 for win-pv-devel@lists.xenproject.org; Fri, 06 Mar 2026 16:08:11 +0000
Received: from na1pdmzitismtp01.tibco.com (na1pdmzitismtp01.corp.cloud.com
 [160.101.131.8]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS
 id abfabf53-1976-11f1-b164-2bf370ae4941;
 Fri, 06 Mar 2026 17:08:11 +0100 (CET)
Received: from mewpvdipd2033.citrite.net (unknown [10.113.48.64])
 by na1pdmzitismtp01.tibco.com (Postfix) with ESMTP id C8F654268FC3;
 Fri,  6 Mar 2026 11:07:46 -0500 (EST)
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: abfabf53-1976-11f1-b164-2bf370ae4941
From: Owen Smith <owen.smith@citrix.com>
To: win-pv-devel@lists.xenproject.org
Cc: david ambu <david.preetham@citrix.com>
Subject: [PATCH 2/2] Xenbus remove event message information from INF file
Date: Fri,  6 Mar 2026 16:08:00 +0000
Message-ID: <20260306160800.774-2-owen.smith@citrix.com>
X-Mailer: git-send-email 2.51.2.windows.1
In-Reply-To: <20260306160800.774-1-owen.smith@citrix.com>
References: <20260306160800.774-1-owen.smith@citrix.com>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit

From: david ambu <david.preetham@citrix.com>

1876359a4fcdc7ee794f13ee190c05df6299d7a7 made the event message
information in the INF file redundant.

Signed-off-by: david ambu <david.preetham@citrix.com>
---
 src/xenbus.inf | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/src/xenbus.inf b/src/xenbus.inf
index adc70bd..702127b 100644
--- a/src/xenbus.inf
+++ b/src/xenbus.inf
@@ -80,7 +80,7 @@ FeatureScore=0xFE
 AddReg = XenBus_Interrupts
 
 [XenBus_Inst.Services]
-AddService=xenbus_monitor,%SPSVCSINST_STARTSERVICE%,Monitor_Service,Monitor_EventLog
+AddService=xenbus_monitor,%SPSVCSINST_STARTSERVICE%,Monitor_Service
 AddService=xenbus,%SPSVCINST_ASSOCSERVICE%,XenBus_Service
 AddService=xenfilt,,XenFilt_Service,
 
@@ -148,13 +148,6 @@ HKR,"Parameters","DialogTitle",0x00000000,%DialogTitle%
 HKR,"Parameters","DialogText",0x00000000,%DialogText%
 HKR,"Parameters","DialogQuestion",0x00000000,%DialogQuestion%
 
-[Monitor_EventLog]
-AddReg=Monitor_EventLog_AddReg
-
-[Monitor_EventLog_AddReg]
-HKR,,EventMessageFile,0x00020000,"%%SystemRoot%%\System32\xenbus_monitor_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.dll"
-HKR,,TypesSupported,0x00010001,7
-
 [Strings] 
 
 Vendor="@VENDOR_NAME@" 
-- 
2.51.2.windows.1



From win-pv-devel-bounces@lists.xenproject.org Fri Mar 06 19:46:16 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Fri, 06 Mar 2026 19:46:16 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1248234.1546471 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vyb7m-00030v-SW; Fri, 06 Mar 2026 19:46:14 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1248234.1546471; Fri, 06 Mar 2026 19:46:14 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vyb7m-00030n-Pp; Fri, 06 Mar 2026 19:46:14 +0000
Received: by outflank-mailman (input) for mailman id 1248234;
 Fri, 06 Mar 2026 19:46:13 +0000
Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50]
 helo=se1-gles-flk1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=3pNL=BG=bounce.vates.tech=bounce-md_30504962.69ab2efd.v1-b35a53dad95f492ebadeabdefb9502c1@srs-se1.protection.inumbo.net>)
 id 1vyb7l-00030h-Lo
 for win-pv-devel@lists.xenproject.org; Fri, 06 Mar 2026 19:46:13 +0000
Received: from mail133-21.atl131.mandrillapp.com
 (mail133-21.atl131.mandrillapp.com [198.2.133.21])
 by se1-gles-flk1.inumbo.com (Halon) with ESMTPS
 id 1db3b177-1995-11f1-9ccf-f158ae23cfc8;
 Fri, 06 Mar 2026 20:46:07 +0100 (CET)
Received: from pmta13.mandrill.prod.atl01.rsglab.com (localhost [127.0.0.1])
 by mail133-21.atl131.mandrillapp.com (Mailchimp) with ESMTP id
 4fSH2j2jWLz1XLF2Y
 for <win-pv-devel@lists.xenproject.org>; Fri,  6 Mar 2026 19:46:05 +0000 (GMT)
Received: from [37.26.189.201] by mandrillapp.com id
 b35a53dad95f492ebadeabdefb9502c1; Fri, 06 Mar 2026 19:46:05 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: 1db3b177-1995-11f1-9ccf-f158ae23cfc8
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com;
	s=mte1; t=1772826365; x=1773096365;
	bh=n6AorJH1bb26CJdJlROWE2fcFM3isAdo1mVDHYnFLPI=;
	h=From:Subject:To:Cc:Message-Id:Feedback-ID:Date:MIME-Version:
	 Content-Type:Content-Transfer-Encoding:CC:Date:Subject:From;
	b=iyQIudD6c6qRl3Gyt8CSGxo6hgBPN3k/n06/aB080RgatVj1iUib1JXJc6SfBYEVW
	 e9UF+W+fSjeizYwxOlDE33saCzh3V58wJhMbQxD4DYYtcpIeX2k/w9LD2GJdt0I8+K
	 3psdGTSJSrAYN+z1SHvSHDE2UbFy/vTNctaJFt7ZZnpzHcdhF8lFHFNI8SLs4PCgQE
	 FgvGicIjARvkcRkNJSe4P8rOpxAZTCzDdqSEHirYqHd9UGXFxKqAQ+1MdmKBTkKqYC
	 bOdpJj9TSPPMO839KBwK/hzhcCzhlgzfNxSuWhXKw9gwvXBupgrXd2Ziydx2lrrTct
	 bfD1oUwxdDcUg==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1;
	t=1772826365; x=1773086865; i=ngoc-tu.dinh@vates.tech;
	bh=n6AorJH1bb26CJdJlROWE2fcFM3isAdo1mVDHYnFLPI=;
	h=From:Subject:To:Cc:Message-Id:Feedback-ID:Date:MIME-Version:
	 Content-Type:Content-Transfer-Encoding:CC:Date:Subject:From;
	b=f4Y6Z/TiWcpBasRd+usqpgCR+Cb4QQ3tL/GTrPWb06FftRbTY5uQJurAXpBZOW8T5
	 FML8/cIWjXwLdsSuEiVtoNzpNg1L1yf+f0lwnHkPGf50QteDhZ+ZFCC8cGsjVxL5Bq
	 dw3NBVosemYZoVVA8GyoPxGiUoP6vOCHqYmv5Je3T0WHsXJnXy2/As0t3CbRqi6bfF
	 4/O98K6hnYKZT1wnZixDJt1rKYalZF3i8ESj5Fs+zLl8RN50jk+pxYXi7sa112MYq4
	 tFGilBuEKRbJrYl7HTyINotNcYwyNsjTMW1taJ/R8HDZRrAADlU/2tUQ3PUMTzPNQo
	 ozsgxDAGTAgvw==
From: "Tu Dinh" <ngoc-tu.dinh@vates.tech>
Subject: =?utf-8?Q?[PATCH]=20Fix=20compilation=20of=20checked=20build?=
X-Mailer: git-send-email 2.53.0.windows.1
X-Bm-Disclaimer: Yes
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1772826364477
To: win-pv-devel@lists.xenproject.org
Cc: "Tu Dinh" <ngoc-tu.dinh@vates.tech>, "Owen Smith" <owen.smith@citrix.com>
Message-Id: <20260306194602.1642-1-ngoc-tu.dinh@vates.tech>
X-Native-Encoded: 1
X-Report-Abuse: =?UTF-8?Q?Please=20forward=20a=20copy=20of=20this=20message,=20including=20all=20headers,=20to=20abuse@mandrill.com.=20You=20can=20also=20report=20abuse=20here:=20https://mandrillapp.com/contact/abuse=3Fid=3D30504962.b35a53dad95f492ebadeabdefb9502c1?=
X-Mandrill-User: md_30504962
Feedback-ID: 30504962:30504962.20260306:md
Date: Fri, 06 Mar 2026 19:46:05 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit

* Redefine XEN_API to __declspec(dllexport) to avoid declaring LogPrintf
  and similar symbols in the same binary as dllimport.
* The BUG() macro was not correctly identified as noreturn in checked
  builds, causing a warning about uninitialized variables. Use
  ASSERT(FALSE) (which does not signal unreachable code) and set the
  variable's value at the end instead.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
---
 src/xen/hypercall.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/xen/hypercall.c b/src/xen/hypercall.c
index 3c68709..fd7401a 100644
--- a/src/xen/hypercall.c
+++ b/src/xen/hypercall.c
@@ -30,6 +30,9 @@
  * SUCH DAMAGE.
  */
 
+#undef  XEN_API
+#define XEN_API __declspec(dllexport)
+
 #include <ntddk.h>
 #include <xen.h>
 #include <intrin.h>
@@ -188,7 +191,8 @@ __Hypercall(
             Value = hypercall2_vmmcall(ord, arg1, arg2);
             break;
         default:
-            BUG("NO HYPERCALL INSTRUCTION");
+            ASSERT(FALSE);
+            Value = 0;
         }
         break;
     }
@@ -206,7 +210,8 @@ __Hypercall(
             Value = hypercall3_vmmcall(ord, arg1, arg2, arg3);
             break;
         default:
-            BUG("NO HYPERCALL INSTRUCTION");
+            ASSERT(FALSE);
+            Value = 0;
         }
         break;
     }
-- 
2.53.0.windows.1



--
 | Vates

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Fri Mar 06 19:57:13 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Fri, 06 Mar 2026 19:57:13 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1248243.1546475 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vybIO-0004FL-LZ; Fri, 06 Mar 2026 19:57:12 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1248243.1546475; Fri, 06 Mar 2026 19:57:12 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vybIO-0004FE-IV; Fri, 06 Mar 2026 19:57:12 +0000
Received: by outflank-mailman (input) for mailman id 1248243;
 Fri, 06 Mar 2026 19:57:11 +0000
Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50]
 helo=se1-gles-flk1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=drz5=BG=bounce.vates.tech=bounce-md_30504962.69ab3190.v1-56b88aab2eea412c94d62a7d560aa271@srs-se1.protection.inumbo.net>)
 id 1vybIN-0004Et-EW
 for win-pv-devel@lists.xenproject.org; Fri, 06 Mar 2026 19:57:11 +0000
Received: from mail133-21.atl131.mandrillapp.com
 (mail133-21.atl131.mandrillapp.com [198.2.133.21])
 by se1-gles-flk1.inumbo.com (Halon) with ESMTPS
 id a6906419-1996-11f1-9ccf-f158ae23cfc8;
 Fri, 06 Mar 2026 20:57:06 +0100 (CET)
Received: from pmta13.mandrill.prod.atl01.rsglab.com (localhost [127.0.0.1])
 by mail133-21.atl131.mandrillapp.com (Mailchimp) with ESMTP id
 4fSHHN73Wbz1XLDth
 for <win-pv-devel@lists.xenproject.org>; Fri,  6 Mar 2026 19:57:04 +0000 (GMT)
Received: from [37.26.189.201] by mandrillapp.com id
 56b88aab2eea412c94d62a7d560aa271; Fri, 06 Mar 2026 19:57:04 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: a6906419-1996-11f1-9ccf-f158ae23cfc8
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com;
	s=mte1; t=1772827025; x=1773097025;
	bh=BlU6JJWAddn375+DJp38A7Dkq4lEmA5ABmwkPYUZGaU=;
	h=From:Subject:Message-Id:To:Cc:References:In-Reply-To:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=aR3lALH9QhEn++Nq3SxTorb+PmreKpmPHIr7L6MLrwYEV2GVZYmOCaI/s1G8V8pd7
	 G4yUtm7ijIZe7DqM+K00lXGTTZvehJ5aIg5MelDC3wdQ4nCmGhpu36jgnM+Vh69Py5
	 VSDtI2JcCawfWm1qxJUzetCJ3gyrFwjO6Ni2efUGLiY+R6b5YTKnALN2ks/g6s7s3Q
	 JnZxRG6tEX9Eu3TD/6GO03dhpBOrbD9sJWfqK44yDUEE/7uw+IIgPIaahbOQz+xOHz
	 ERnM1y4lETK3IthP++OeSPslPculNnddFLA9r5CIPLSf17aShUz6X8xzz3lhgctIU3
	 G+5iBFfJ8Z7WA==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1;
	t=1772827025; x=1773087525; i=ngoc-tu.dinh@vates.tech;
	bh=BlU6JJWAddn375+DJp38A7Dkq4lEmA5ABmwkPYUZGaU=;
	h=From:Subject:Message-Id:To:Cc:References:In-Reply-To:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=aMsu7J3nA8kE53JUEWhe9zRtWwmEmiYeg6sjnRzR1t0w2EZx8Y9aiRasLzyQ6xfzO
	 16obH507H09XLJzt2Yrs/F5GvzH1k5AbJns4IZtrO+nCnDy6zjBIqJ7gksjc2Oh63A
	 mFHzIuDf3aRLKtcUMUH3Xu5m7HyV5OjBjbW6qS2dKmKagYdywNL80omHjlSO3GDiDT
	 XrC9UE20GP9AE3Eg74D0947Vt9Tqe8F8Yc3bs4S2fpTL+5bVvlcGLSdN9vmryukZG9
	 TjFcKEP7Cl8u4cqizmR8omUbr8sAQMI0QItSipZABOd3igU68n2TNTvN4NVMsj5F6r
	 12wZ53xEWQTOA==
From: "Tu Dinh" <ngoc-tu.dinh@vates.tech>
Subject: =?utf-8?Q?Re:=20[PATCH=202/2]=20Xenbus=20remove=20event=20message=20information=20from=20INF=20file?=
X-Bm-Disclaimer: Yes
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1772827023948
Message-Id: <a18e73c0-7531-41ae-9c2b-a0c5e5d68131@vates.tech>
To: "Owen Smith" <owen.smith@citrix.com>, win-pv-devel@lists.xenproject.org
Cc: "david ambu" <david.preetham@citrix.com>
References: <20260306160800.774-1-owen.smith@citrix.com> <20260306160800.774-2-owen.smith@citrix.com>
In-Reply-To: <20260306160800.774-2-owen.smith@citrix.com>
X-Native-Encoded: 1
X-Report-Abuse: =?UTF-8?Q?Please=20forward=20a=20copy=20of=20this=20message,=20including=20all=20headers,=20to=20abuse@mandrill.com.=20You=20can=20also=20report=20abuse=20here:=20https://mandrillapp.com/contact/abuse=3Fid=3D30504962.56b88aab2eea412c94d62a7d560aa271?=
X-Mandrill-User: md_30504962
Feedback-ID: 30504962:30504962.20260306:md
Date: Fri, 06 Mar 2026 19:57:04 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit

On 06/03/2026 17:08, Owen Smith wrote:
> From: david ambu <david.preetham@citrix.com>
> 
> 1876359a4fcdc7ee794f13ee190c05df6299d7a7 made the event message
> information in the INF file redundant.
> 
> Signed-off-by: david ambu <david.preetham@citrix.com>

Is xenbus_monitor.dll still needed, can it be removed from the source 
tree altogether?

> ---
>   src/xenbus.inf | 9 +--------
>   1 file changed, 1 insertion(+), 8 deletions(-)
> 
> diff --git a/src/xenbus.inf b/src/xenbus.inf
> index adc70bd..702127b 100644
> --- a/src/xenbus.inf
> +++ b/src/xenbus.inf
> @@ -80,7 +80,7 @@ FeatureScore=0xFE
>   AddReg = XenBus_Interrupts
>   
>   [XenBus_Inst.Services]
> -AddService=xenbus_monitor,%SPSVCSINST_STARTSERVICE%,Monitor_Service,Monitor_EventLog
> +AddService=xenbus_monitor,%SPSVCSINST_STARTSERVICE%,Monitor_Service
>   AddService=xenbus,%SPSVCINST_ASSOCSERVICE%,XenBus_Service
>   AddService=xenfilt,,XenFilt_Service,
>   
> @@ -148,13 +148,6 @@ HKR,"Parameters","DialogTitle",0x00000000,%DialogTitle%
>   HKR,"Parameters","DialogText",0x00000000,%DialogText%
>   HKR,"Parameters","DialogQuestion",0x00000000,%DialogQuestion%
>   
> -[Monitor_EventLog]
> -AddReg=Monitor_EventLog_AddReg
> -
> -[Monitor_EventLog_AddReg]
> -HKR,,EventMessageFile,0x00020000,"%%SystemRoot%%\System32\xenbus_monitor_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.dll"
> -HKR,,TypesSupported,0x00010001,7
> -
>   [Strings]
>   
>   Vendor="@VENDOR_NAME@"



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Fri Mar 06 20:18:15 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Fri, 06 Mar 2026 20:18:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1248259.1546479 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vybck-0006oB-3x; Fri, 06 Mar 2026 20:18:14 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1248259.1546479; Fri, 06 Mar 2026 20:18:14 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vybck-0006o4-1N; Fri, 06 Mar 2026 20:18:14 +0000
Received: by outflank-mailman (input) for mailman id 1248259;
 Fri, 06 Mar 2026 20:18:12 +0000
Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254]
 helo=se1-gles-sth1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=o9zW=BG=bounce.vates.tech=bounce-md_30504962.69ab3681.v1-f313a4cd47b6485c84c420bfd0d6b83a@srs-se1.protection.inumbo.net>)
 id 1vybci-0006nx-Gr
 for win-pv-devel@lists.xenproject.org; Fri, 06 Mar 2026 20:18:12 +0000
Received: from mail132-19.atl131.mandrillapp.com
 (mail132-19.atl131.mandrillapp.com [198.2.132.19])
 by se1-gles-sth1.inumbo.com (Halon) with ESMTPS
 id 98486619-1999-11f1-b164-2bf370ae4941;
 Fri, 06 Mar 2026 21:18:10 +0100 (CET)
Received: from pmta09.mandrill.prod.atl01.rsglab.com (localhost [127.0.0.1])
 by mail132-19.atl131.mandrillapp.com (Mailchimp) with ESMTP id 4fSHlj2qH4z4j4
 for <win-pv-devel@lists.xenproject.org>; Fri,  6 Mar 2026 20:18:09 +0000 (GMT)
Received: from [37.26.189.201] by mandrillapp.com id
 f313a4cd47b6485c84c420bfd0d6b83a; Fri, 06 Mar 2026 20:18:09 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: 98486619-1999-11f1-b164-2bf370ae4941
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com;
	s=mte1; t=1772828289; x=1773098289;
	bh=4Ck7meVBs99VqCgIs36Gr+VF0j4YzJTS6XQtAC4qsh4=;
	h=From:Subject:Message-Id:To:References:In-Reply-To:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=ZI0BQwWLZVITFKXVFyJ4Fq9gD+E/B3TR/+8YiBBanS+AU+ZZnen24IPv48Tbei2KB
	 dSme+H0KLBhE/OSKSw79X3d1pNWhJCP/fLIa+lizpLIL5DQshEUsGiiJPcdW7xZgS4
	 xEHxq285f4AZKvuudFFI8+uEaj+bdwQNPiItEXijTuIwcKOK8KnUJhPttu4K9JpHzt
	 XNXrVLBoNh/QyBnzqjcAXvTHfoAVl7Tpw37xUcPOUpkbCO5m3TnbvBRC0SMll5Ra5m
	 +RiNd7Smeeu/X5a4paBMXsxraCLzYWC37JwIInGec3NgSVci3jZcShxKTWiMfxgMOc
	 FLgsHtItALSwg==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1;
	t=1772828289; x=1773088789; i=ngoc-tu.dinh@vates.tech;
	bh=4Ck7meVBs99VqCgIs36Gr+VF0j4YzJTS6XQtAC4qsh4=;
	h=From:Subject:Message-Id:To:References:In-Reply-To:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=OjtiZ1sRfwo2dbqFnaJcs+zXs6iILvtA8Se+ofNwjyOXTNw12wSWXfEclWKe9MMaY
	 MWFFAIq3Gsa+HN0ZtuCgUSkoJm6Dj+rVpGXvQSc4LSActpXxYZ8SwjLZ9c7NFZqo4+
	 K/730Nh0BrjJ5Y9/IOA9rZ2ywECAeeOBDT3+88PNEyyQMbevriii62wLWGXV+UZKGv
	 FMEQuM07ZfZkzzAdi5421FVFspWZkn7hFFANyAutkBL7xadNOOlWcr8+OtIuHnxk+/
	 ZnNdvUgtI3apUPFwRmIVzpSAuKuLCDIM9I0QbVxuCtIT0B8c5C9BhharBouwTigXHd
	 N1f6xsR6KvBnA==
From: "Tu Dinh" <ngoc-tu.dinh@vates.tech>
Subject: =?utf-8?Q?Re:=20[PATCH=201/2]=20Unplug:=20Set=20bit=20for=20NVME=20disk=20unplug?=
X-Bm-Disclaimer: Yes
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1772828288613
Message-Id: <6df7026c-0e80-4024-911d-b48bb449ebeb@vates.tech>
To: "Owen Smith" <owen.smith@citrix.com>, win-pv-devel@lists.xenproject.org
References: <20260306160800.774-1-owen.smith@citrix.com>
In-Reply-To: <20260306160800.774-1-owen.smith@citrix.com>
X-Native-Encoded: 1
X-Report-Abuse: =?UTF-8?Q?Please=20forward=20a=20copy=20of=20this=20message,=20including=20all=20headers,=20to=20abuse@mandrill.com.=20You=20can=20also=20report=20abuse=20here:=20https://mandrillapp.com/contact/abuse=3Fid=3D30504962.f313a4cd47b6485c84c420bfd0d6b83a?=
X-Mandrill-User: md_30504962
Feedback-ID: 30504962:30504962.20260306:md
Date: Fri, 06 Mar 2026 20:18:09 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit

On 06/03/2026 17:08, Owen Smith wrote:
> When issuing a DISK unplug command, set the bits for emulated IDE/SCSI
> and emulated NVME devices.
> 
> Also defines and uses symbols to represent each bit in the unplug protocol.
> 
> Signed-off-by: Owen Smith <owen.smith@citrix.com>

Acked-by: Tu Dinh <ngoc-tu.dinh@vates.tech>

I haven't ever tested the BootEmulated path, but it looks broken on VMs 
with NVMe anyway (can't unplug just the boot disk).

> ---
>   src/xen/unplug.c | 12 +++++++++---
>   1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/src/xen/unplug.c b/src/xen/unplug.c
> index 282ed93..3b6593a 100644
> --- a/src/xen/unplug.c
> +++ b/src/xen/unplug.c
> @@ -49,6 +49,12 @@
>   
>   #define UNPLUG_TAG  'LPNU'
>   
> +#define UNPLUG_FLAGS_IDE_SCSI_DISKS   0x0001
> +#define UNPLUG_FLAGS_ALL_NICS         0x0002
> +#define UNPLUG_FLAGS_AUX_IDE_DISKS    0x0004  // ignored if UNPLUG_FLAGS_IDE_SCSI_DISKS is set
> +#define UNPLUG_FLAGS_NVME_DISKS       0x0008
> +#define UNPLUG_FLAGS_ALL_DISKS        (UNPLUG_FLAGS_IDE_SCSI_DISKS | UNPLUG_FLAGS_NVME_DISKS)
> +
>   typedef struct _UNPLUG_DATA {
>       PSTR        Name;
>       BOOLEAN     Found;
> @@ -116,19 +122,19 @@ UnplugDeviceType(
>       case UNPLUG_DISKS:
>           if (Context->BootEmulated) {
>   #pragma prefast(suppress:28138)
> -            WRITE_PORT_USHORT((PUSHORT)0x10, 0x0004);
> +            WRITE_PORT_USHORT((PUSHORT)0x10, UNPLUG_FLAGS_AUX_IDE_DISKS);
>   
>               LogPrintf(LOG_LEVEL_WARNING, "UNPLUG: AUX DISKS\n");
>           } else {
>   #pragma prefast(suppress:28138)
> -            WRITE_PORT_USHORT((PUSHORT)0x10, 0x0001);
> +            WRITE_PORT_USHORT((PUSHORT)0x10, UNPLUG_FLAGS_ALL_DISKS);
>   
>               LogPrintf(LOG_LEVEL_WARNING, "UNPLUG: DISKS\n");
>           }
>           break;
>       case UNPLUG_NICS:
>   #pragma prefast(suppress:28138)
> -        WRITE_PORT_USHORT((PUSHORT)0x10, 0x0002);
> +        WRITE_PORT_USHORT((PUSHORT)0x10, UNPLUG_FLAGS_ALL_NICS);
>   
>           LogPrintf(LOG_LEVEL_WARNING, "UNPLUG: NICS\n");
>           break;



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Mon Mar 09 07:48:35 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Mon, 09 Mar 2026 07:48:35 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1249145.1546646 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vzVLu-0000Jp-3t; Mon, 09 Mar 2026 07:48:34 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1249145.1546646; Mon, 09 Mar 2026 07:48:34 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vzVLu-0000Ji-0z; Mon, 09 Mar 2026 07:48:34 +0000
Received: by outflank-mailman (input) for mailman id 1249145;
 Mon, 09 Mar 2026 07:48:33 +0000
Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254]
 helo=se1-gles-sth1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=flx5=BJ=citrix.com=owen.smith@srs-se1.protection.inumbo.net>)
 id 1vzVLs-0000JT-TT
 for win-pv-devel@lists.xenproject.org; Mon, 09 Mar 2026 07:48:32 +0000
Received: from CH5PR02CU005.outbound.protection.outlook.com
 (mail-northcentralusazlp170120005.outbound.protection.outlook.com
 [2a01:111:f403:c105::5])
 by se1-gles-sth1.inumbo.com (Halon) with ESMTPS
 id 5d305d3c-1b8c-11f1-b164-2bf370ae4941;
 Mon, 09 Mar 2026 08:48:31 +0100 (CET)
Received: from SA6PR03MB7760.namprd03.prod.outlook.com (2603:10b6:806:43c::5)
 by SJ0PR03MB6343.namprd03.prod.outlook.com (2603:10b6:a03:399::11)
 with Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9678.24; Mon, 9 Mar
 2026 07:48:27 +0000
Received: from SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38]) by SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38%7]) with mapi id 15.20.9678.023; Mon, 9 Mar 2026
 07:48:26 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: 5d305d3c-1b8c-11f1-b164-2bf370ae4941
ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;
 b=Ry6y/SKK6sEpHs52sXBBlMuxQ1BSeZJMEvxpDPHduw7k5KCMvuyBLRuR3bzy5R3MguYak7Cd6qlWLqLSTBbuTF2m41Eg1WWMyQJGVhuH+Jvk6ewnXJ9sVfxQj5cbGYe25Bld0rP19l/dD3Ngr5/uYi706Sp0/kQ2Uu0QNEWVTVI3tEF5Tqh6s9T8Z/Iq2/yD2FN03MWAmEKe7Ky0AnicsSYnidsv0n+Vpw4VgHRI9xAtMApsojdS5xvy8yx7mOr7GTHi6hH2eJDTn4u+RzAYcMgXL0QiCRnxrupCbz/rxFnbCvwPrbG1IIOubbhFmxBlNQaFo4USDqECu95wY8jg8w==
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=FS9Kdhz/nFOgTTZe+v3d0ZzolQ59Yyp8i114HJbVxfY=;
 b=Cb7G3VxAH38YQlNeCBTCzcK9zSNDFRgurxyHBQ9GlJ/Ehyx34rqwVQQK8xGd2jVgTOlXLGoI1qk7P8EQGK9YcGF0b8w8Lmmc3HRgPm7vomBJkxbmnJERxrp6v5xW0ZfYWBW6Jjlj7Ys+TAXlZVBi859rUTR7IgqmhwxEG/78rQI0D2uVBlkef2o6VtPcW78Phs9UttDlyEwX3B4b6XRdAcGXa+UOdqrwQB61I5QYAGXwj69CnsM4AMDm/NLMd4oQ0Dm/27OInGVu1G1gPgbkdGDNqmdZBZTwf+EH5Tsgc74BZ7lPbFGqQ/e/1Totev6hqrb2LBq9FnTRoeKLJHDysQ==
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
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com;
 s=selector1;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=FS9Kdhz/nFOgTTZe+v3d0ZzolQ59Yyp8i114HJbVxfY=;
 b=jSeM5yRMbvbs+poE2uPCe4gl8fME+GX06zJp3SnXjLI18tsW+y9D3YRIanaobOf8WmCs7iZJGUO0reT9WPqrkAU/XwvxLM5DxX/NMf1kq1uVO746zIcpHghYXbiwpuZFEMQI942TT6Dad107UiBglmLOMHJ/mgsKW7goqKkFyCs=
From: Owen Smith <owen.smith@citrix.com>
To: Tu Dinh <ngoc-tu.dinh@vates.tech>, "win-pv-devel@lists.xenproject.org"
	<win-pv-devel@lists.xenproject.org>
Subject: Re: [PATCH] Fix compilation of checked build
Thread-Topic: [PATCH] Fix compilation of checked build
Thread-Index: AQHcraHgMyhDAwQfPUqY3VZG+GeRz7Wl1YkA
Date: Mon, 9 Mar 2026 07:48:26 +0000
Message-ID:
 <SA6PR03MB7760DBF2D226BD7550D51FE0FE79A@SA6PR03MB7760.namprd03.prod.outlook.com>
References: <20260306194602.1642-1-ngoc-tu.dinh@vates.tech>
In-Reply-To: <20260306194602.1642-1-ngoc-tu.dinh@vates.tech>
Accept-Language: en-GB, en-US
Content-Language: en-GB
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
msip_labels:
authentication-results: dkim=none (message not signed)
 header.d=none;dmarc=none action=none header.from=citrix.com;
x-ms-publictraffictype: Email
x-ms-traffictypediagnostic: SA6PR03MB7760:EE_|SJ0PR03MB6343:EE_
x-ms-office365-filtering-correlation-id: f7f055ae-20a6-4332-55f2-08de7db03f7b
x-ms-exchange-senderadcheck: 1
x-ms-exchange-antispam-relay: 0
x-microsoft-antispam: BCL:0;ARA:13230040|1800799024|366016|376014|38070700021;
x-microsoft-antispam-message-info:
 r9X6il0PSzABi50l6JBuPAn+rtNc2xUEqV+XzNuUrR+hXZo6Ky1aNQyyrGmtHBO/3ATlRGbRiQCQspocwCnnPXS9ScdU1OQARe6j0qhpMi9J1GHZOqD19GaqL4XmSbb9EE0foYktsoerzfbymLYMl1FOE+dQDN/aV9Ph/ewI5UbNKUHzOFdch9QDVQaoIf2zdTJm+9wZJdEj4jNWfLubs3Df+EXO8gC5N4XS0A/CXCh4UAWC7TadkMdaLeRZo8goYFn23Cc8+J+7Tp04nrUhvXsbjey1Qh4rp+pjssSwyra+oD4KLEn9YJUhAc61LDc0RORKLqRmpAiH0TKPAtWg5D1aXecmHi1wtgF3FSMPKqFp1Vi4seAO1W+kovqeQIrBmg1iy+Q7eK/HBmDir+yf+Awl94l4/jachAyNEVvQdrt5ImGE4byy0uuBIbXFRbXsNn2IFqPLaTUuYzI+/X77zmukwp5wS/pDQC6GzKn1bdR0GwaposPZi4nJktJsTfyndxYdwZKvCPa+Vk0vp1OWr3wAF8jUMiGLZRt0W4IdegWz6hPQWewPYjX1t8AaLLo7U4d9RvYVOkfuZWm0mN98mIMNVD5xU3ixGE3oyIa2U1tqC+Ev6xDmTtGrAdu+HyqBbiC5p3rMv+w0uD0oJNlP6N2Js0MTZHyNxOw1/fRh5gRsECCY6kODDmLBjRNDKYAXlWRiD20kOUxezuWC2iqXsYjBIjiczlaj16YWAr+Zono=
x-forefront-antispam-report:
 CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SA6PR03MB7760.namprd03.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(1800799024)(366016)(376014)(38070700021);DIR:OUT;SFP:1101;
x-ms-exchange-antispam-messagedata-chunkcount: 1
x-ms-exchange-antispam-messagedata-0:
 =?us-ascii?Q?55Yp2gVBRnp/ywAhzOa2wHU9QGlMUaGqsCslkWzVW6coveGmFCxW1yruKz4z?=
 =?us-ascii?Q?y8uMdWFc8rP92er1TJTozXb0IFDmKrdRNXJwXZoZb5B2N4EwWqbVFlhaD8Tn?=
 =?us-ascii?Q?K5MmXOa8mc/03C42IxTjQXhlP6E3NLMllJr7Vq2nbzpeft4YDvKh80DDf5Ml?=
 =?us-ascii?Q?7ahM36qXzCaBcuyJK3F4dNQbGF6WNbYbdJcPN8p3sNX+nIn1dpS/QA/6NhDV?=
 =?us-ascii?Q?LdJQanFDmXUx9h8gC8bdO4k/LdPd6OYEKWaSr/lElukrJGGc9fjxq5RanbHy?=
 =?us-ascii?Q?njBjhb+D1X3t5pGEIb9pDKkUKk3Oq7qGPRtzXQ+Wpx8cdCWdy79aFaj1oI9O?=
 =?us-ascii?Q?Gzs7SG70DT2KwmeKRIWPzfrv9TwPLKPbDF8UyYRJgUw0Bv/IOckxTeQ66PeM?=
 =?us-ascii?Q?T0MYWOFeFwcPQLfFI+KnBpjh+3P4xKv/387TQ4ttXicTvxv9By6uzPUIntPu?=
 =?us-ascii?Q?23XjCMI27taldqgvUkHeu1EM1Vl7ADribrsRQyBROAS9hcdU4Fy0fafPI8Of?=
 =?us-ascii?Q?Z95PJDQMGlPoVB9Vcem6VuNBpb95lj970SItWlRUJn2CU2YrnOKGL0zrXMmL?=
 =?us-ascii?Q?gHseB6DaXtmKh4K3m6C1guXXdv61yBRxJGb1AG9u46H39kt5pP/08XyWKmXM?=
 =?us-ascii?Q?Pn/GJEA56ISSiWm9/FDwmUwmNyy/UxpHFUd1KHOV8yMt89WnP26gm8Y0rMD0?=
 =?us-ascii?Q?9kavnYpfibm1VeruYX5IH39Kql17vFlSr+tOVbBx3KKB41ymMwnAKnD/54dZ?=
 =?us-ascii?Q?MuB8z3EcKzzTxvILu5qKl9NsYIxBnFxjvFwMX+aDqxywJmzQPcpFsyWp7yqZ?=
 =?us-ascii?Q?6S2Bm3HVQcest8RyA0pt0YXQPafl0/2BESwYKe/VeB3l70W3e10XzWxGifdJ?=
 =?us-ascii?Q?8IrTGFDJipmySVi3MigRjSZvuWPF91W/wbVFRZTDOOlARY87KhS4h/x10RRP?=
 =?us-ascii?Q?+MOTSypgHcn6HTrexRO2DY2xFuM77oMll3KQ56wT3dBjiZLHjbkq854RZYwH?=
 =?us-ascii?Q?FlY/REWnnYJps/62F5Ih2sqp39+jEqmM+pJF04lrRorb4RT+j9er6f2k1UG9?=
 =?us-ascii?Q?kvjdB9HMUJzSAQIoWzKCu1EpRnim9o7FON4Git2x11xnz64dhhEIv5jhU9T1?=
 =?us-ascii?Q?2un58787OXzkKjqIxvS0mtulmN9cV8OfRZ0mevRV0lO86JbQzFW+AAP1vnIj?=
 =?us-ascii?Q?4eaYMbehwZVB0bOZx4xepgWHcHKyWOe4Dq9IfrbjxrY6e2TevVOYhLH7/ySu?=
 =?us-ascii?Q?9F5/WpNH47qBf0wqbTj1mB7J0qRhXy9qmx6mLNLGEPBxqhEkb/N0ntnjHBRL?=
 =?us-ascii?Q?FoEyz87oUGK/iZGsIGHesBWbWUbNw4jGl5tM/a0gyKaMBt/JjF065qtT+fIP?=
 =?us-ascii?Q?rUd6sIlmXBdzzglC44iTpCKJ1kp8RCYRu+WK0cv29jua027R5reqWcIPbhrj?=
 =?us-ascii?Q?ivBVEwMmW5obimSqgNBqiO5yiOjnOkmff3DP0pJ+ojAFQfKGPsE1nRK/OyWt?=
 =?us-ascii?Q?ZYQ/nxrBWQ2a+fGpMnRV8PEtYtVLuggnsMUNram9yjL4s0RYA7bugGO2OLY8?=
 =?us-ascii?Q?bz3Zn5x1H2WQEqOeNVs84Xpoy2/G+Jog/hFSApBVlkceHLSo3emRNouIUfUZ?=
 =?us-ascii?Q?W5Q6rH5Of0AgawAEDhOb2AfcdqQA4xjPQaOFaMp+TXWXQVKZYX91dQHn3J7W?=
 =?us-ascii?Q?DTtQCFnVz9OOaHzJdcXaOsuXsmwEvj6HcplmH39Xht6v0L6f?=
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
X-OriginatorOrg: citrix.com
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-AuthSource: SA6PR03MB7760.namprd03.prod.outlook.com
X-MS-Exchange-CrossTenant-Network-Message-Id: f7f055ae-20a6-4332-55f2-08de7db03f7b
X-MS-Exchange-CrossTenant-originalarrivaltime: 09 Mar 2026 07:48:26.5781
 (UTC)
X-MS-Exchange-CrossTenant-fromentityheader: Hosted
X-MS-Exchange-CrossTenant-id: 335836de-42ef-43a2-b145-348c2ee9ca5b
X-MS-Exchange-CrossTenant-mailboxtype: HOSTED
X-MS-Exchange-CrossTenant-userprincipalname: 5cc37FfUrIH6Ik/V80wYpkZAN1Lk3aHcN9D1myJ7xK0h9ohmZg8KgOmjdCjfWozFl9DH1XW7pvz0DNO/AiBnGg==
X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ0PR03MB6343

I would prefer to keep the BUG() statements, as this logs the issue and is =
present
 in free builds. It would mean assigning Value before the BUG statement to =
avoid
unreachable code warnings in free builds.

Owen

________________________________________
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
Sent: 06 March 2026 7:46 PM
To: win-pv-devel@lists.xenproject.org
Cc: Tu Dinh; Owen Smith
Subject: [PATCH] Fix compilation of checked build

* Redefine XEN_API to __declspec(dllexport) to avoid declaring LogPrintf
  and similar symbols in the same binary as dllimport.
* The BUG() macro was not correctly identified as noreturn in checked
  builds, causing a warning about uninitialized variables. Use
  ASSERT(FALSE) (which does not signal unreachable code) and set the
  variable's value at the end instead.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
---
 src/xen/hypercall.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/xen/hypercall.c b/src/xen/hypercall.c
index 3c68709..fd7401a 100644
--- a/src/xen/hypercall.c
+++ b/src/xen/hypercall.c
@@ -30,6 +30,9 @@
  * SUCH DAMAGE.
  */

+#undef  XEN_API
+#define XEN_API __declspec(dllexport)
+
 #include <ntddk.h>
 #include <xen.h>
 #include <intrin.h>
@@ -188,7 +191,8 @@ __Hypercall(
             Value =3D hypercall2_vmmcall(ord, arg1, arg2);
             break;
         default:
-            BUG("NO HYPERCALL INSTRUCTION");
+            ASSERT(FALSE);
+            Value =3D 0;
         }
         break;
     }
@@ -206,7 +210,8 @@ __Hypercall(
             Value =3D hypercall3_vmmcall(ord, arg1, arg2, arg3);
             break;
         default:
-            BUG("NO HYPERCALL INSTRUCTION");
+            ASSERT(FALSE);
+            Value =3D 0;
         }
         break;
     }
--
2.53.0.windows.1



--
 | Vates

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Mon Mar 09 07:55:54 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Mon, 09 Mar 2026 07:55:54 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1249148.1546649 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vzVSz-0001VJ-Ky; Mon, 09 Mar 2026 07:55:53 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1249148.1546649; Mon, 09 Mar 2026 07:55:53 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vzVSz-0001VC-IJ; Mon, 09 Mar 2026 07:55:53 +0000
Received: by outflank-mailman (input) for mailman id 1249148;
 Mon, 09 Mar 2026 07:55:52 +0000
Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254]
 helo=se1-gles-sth1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=ArXH=BJ=bounce.vates.tech=bounce-md_30504962.69ae7d04.v1-dd7a38c1c21049f182188d09e4278085@srs-se1.protection.inumbo.net>)
 id 1vzVSy-0001V4-98
 for win-pv-devel@lists.xenproject.org; Mon, 09 Mar 2026 07:55:52 +0000
Received: from mail132-19.atl131.mandrillapp.com
 (mail132-19.atl131.mandrillapp.com [198.2.132.19])
 by se1-gles-sth1.inumbo.com (Halon) with ESMTPS
 id 636a78d9-1b8d-11f1-b164-2bf370ae4941;
 Mon, 09 Mar 2026 08:55:50 +0100 (CET)
Received: from pmta09.mandrill.prod.atl01.rsglab.com (localhost [127.0.0.1])
 by mail132-19.atl131.mandrillapp.com (Mailchimp) with ESMTP id 4fTq7m6c9zz19d
 for <win-pv-devel@lists.xenproject.org>; Mon,  9 Mar 2026 07:55:48 +0000 (GMT)
Received: from [37.26.189.201] by mandrillapp.com id
 dd7a38c1c21049f182188d09e4278085; Mon, 09 Mar 2026 07:55:48 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: 636a78d9-1b8d-11f1-b164-2bf370ae4941
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com;
	s=mte1; t=1773042948; x=1773312948;
	bh=GXaiPzWrZti7RuEObsf+5oikhXxaib2+LzUBhmAaVgY=;
	h=From:Subject:Message-Id:To:References:In-Reply-To:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=rROvJkKK5Pe0bdNY59r82A6GTQzJUlNHI9T4D9DBXfJUec8j9+yGvEYH80Ucz/dK2
	 MaL5M6fblWgVwZ+bFUI02rRsWTZNTxG35mesMpw6AAf7TGDllz1FVsvsFWLDxWwzmI
	 5YcldC339t9q8sy7ZeNGbZqaG+NEBbAIHerkQKjRZTG9jZJBe5jgIazsFedy05n3/r
	 L2Jx/iCxazI3VlHckmJJMeceHr8VBZ5jiOm/4kP6aKJhY6hex++kT67UM2f8hEGGJi
	 WOj9xagLzqFVtS7BRthoy5+NoIk9XZlnCDWh8VzBhvOE3tWSz819w6QConPwLkhfv1
	 BE8pDkYU7dE+w==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1;
	t=1773042948; x=1773303448; i=ngoc-tu.dinh@vates.tech;
	bh=GXaiPzWrZti7RuEObsf+5oikhXxaib2+LzUBhmAaVgY=;
	h=From:Subject:Message-Id:To:References:In-Reply-To:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=pZyD7BxZFhhU7DhbyjIS41YtXL0NRZRYS2OxL7BPpZzqCnptCaje4/j9jxbJfOe2b
	 t83py9QvtgIqG1XWea5XWvd47FrLfkfSAIZUMj8SvQWsH/cMecguERlLUCfJbeQxq+
	 xIf32cACOTJrQBCNavtaFhPwsJI3Bo01+KUFOlkV8ja28h4n7PxvP/WMiNCnIawJJa
	 U6DneXzjmy7oyuH2gSAdDvW71XMcVvEGNoCKynmkHuh22ZO+JQX7TissX+LdIsc4KJ
	 vYMQt2/8gtbwb3vqDweJTckK544jo2frAiQCZLpI4qKa5vsUTxFUIkPgaXosm/nQSY
	 LsJb9m4TFy+fg==
From: "Tu Dinh" <ngoc-tu.dinh@vates.tech>
Subject: =?utf-8?Q?Re:=20[PATCH]=20Fix=20compilation=20of=20checked=20build?=
X-Bm-Disclaimer: Yes
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1773042948078
Message-Id: <af241a84-c059-4cf8-b2e4-72e4389605e9@vates.tech>
To: "Owen Smith" <owen.smith@citrix.com>, win-pv-devel@lists.xenproject.org
References: <20260306194602.1642-1-ngoc-tu.dinh@vates.tech> <SA6PR03MB7760DBF2D226BD7550D51FE0FE79A@SA6PR03MB7760.namprd03.prod.outlook.com>
In-Reply-To: <SA6PR03MB7760DBF2D226BD7550D51FE0FE79A@SA6PR03MB7760.namprd03.prod.outlook.com>
X-Native-Encoded: 1
X-Report-Abuse: =?UTF-8?Q?Please=20forward=20a=20copy=20of=20this=20message,=20including=20all=20headers,=20to=20abuse@mandrill.com.=20You=20can=20also=20report=20abuse=20here:=20https://mandrillapp.com/contact/abuse=3Fid=3D30504962.dd7a38c1c21049f182188d09e4278085?=
X-Mandrill-User: md_30504962
Feedback-ID: 30504962:30504962.20260309:md
Date: Mon, 09 Mar 2026 07:55:48 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit

On 09/03/2026 08:48, Owen Smith wrote:
> I would prefer to keep the BUG() statements, as this logs the issue and is present
>   in free builds. It would mean assigning Value before the BUG statement to avoid
> unreachable code warnings in free builds.
> 
> Owen
 >

Thanks, that's definitely better. While I'm at it I'll replace the 
ASSERT(FALSE) in the invalid argument count case as well.

I'll send a v2 soon.

> ________________________________________
> From: Tu Dinh <ngoc-tu.dinh@vates.tech>
> Sent: 06 March 2026 7:46 PM
> To: win-pv-devel@lists.xenproject.org
> Cc: Tu Dinh; Owen Smith
> Subject: [PATCH] Fix compilation of checked build
> 
> * Redefine XEN_API to __declspec(dllexport) to avoid declaring LogPrintf
>    and similar symbols in the same binary as dllimport.
> * The BUG() macro was not correctly identified as noreturn in checked
>    builds, causing a warning about uninitialized variables. Use
>    ASSERT(FALSE) (which does not signal unreachable code) and set the
>    variable's value at the end instead.
> 
> Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
> ---
>   src/xen/hypercall.c | 9 +++++++--
>   1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/src/xen/hypercall.c b/src/xen/hypercall.c
> index 3c68709..fd7401a 100644
> --- a/src/xen/hypercall.c
> +++ b/src/xen/hypercall.c
> @@ -30,6 +30,9 @@
>    * SUCH DAMAGE.
>    */
> 
> +#undef  XEN_API
> +#define XEN_API __declspec(dllexport)
> +
>   #include <ntddk.h>
>   #include <xen.h>
>   #include <intrin.h>
> @@ -188,7 +191,8 @@ __Hypercall(
>               Value = hypercall2_vmmcall(ord, arg1, arg2);
>               break;
>           default:
> -            BUG("NO HYPERCALL INSTRUCTION");
> +            ASSERT(FALSE);
> +            Value = 0;
>           }
>           break;
>       }
> @@ -206,7 +210,8 @@ __Hypercall(
>               Value = hypercall3_vmmcall(ord, arg1, arg2, arg3);
>               break;
>           default:
> -            BUG("NO HYPERCALL INSTRUCTION");
> +            ASSERT(FALSE);
> +            Value = 0;
>           }
>           break;
>       }
> --
> 2.53.0.windows.1
> 
> 
> 
> --
>   | Vates
> 
> XCP-ng & Xen Orchestra - Vates solutions
> 
> web: https://vates.tech
> 



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Mon Mar 09 07:57:30 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Mon, 09 Mar 2026 07:57:30 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1249149.1546654 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vzVUX-0001gO-PV; Mon, 09 Mar 2026 07:57:29 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1249149.1546654; Mon, 09 Mar 2026 07:57:29 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vzVUX-0001gG-MS; Mon, 09 Mar 2026 07:57:29 +0000
Received: by outflank-mailman (input) for mailman id 1249149;
 Mon, 09 Mar 2026 07:57:28 +0000
Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50]
 helo=se1-gles-flk1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=luy8=BJ=bounce.vates.tech=bounce-md_30504962.69ae7d5c.v1-cd99788e9d0542049a3a4424e52bef0e@srs-se1.protection.inumbo.net>)
 id 1vzVUW-0001eu-OT
 for win-pv-devel@lists.xenproject.org; Mon, 09 Mar 2026 07:57:28 +0000
Received: from mail133-21.atl131.mandrillapp.com
 (mail133-21.atl131.mandrillapp.com [198.2.133.21])
 by se1-gles-flk1.inumbo.com (Halon) with ESMTPS
 id 976a1d69-1b8d-11f1-9ccf-f158ae23cfc8;
 Mon, 09 Mar 2026 08:57:18 +0100 (CET)
Received: from pmta13.mandrill.prod.atl01.rsglab.com (localhost [127.0.0.1])
 by mail133-21.atl131.mandrillapp.com (Mailchimp) with ESMTP id
 4fTq9S51k0z1XLDvH
 for <win-pv-devel@lists.xenproject.org>; Mon,  9 Mar 2026 07:57:16 +0000 (GMT)
Received: from [37.26.189.201] by mandrillapp.com id
 cd99788e9d0542049a3a4424e52bef0e; Mon, 09 Mar 2026 07:57:16 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: 976a1d69-1b8d-11f1-9ccf-f158ae23cfc8
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com;
	s=mte1; t=1773043036; x=1773313036;
	bh=zY8FRcHPF2pSQJMp37XaauKL/Ejo3zct/vGdTgu7Qb0=;
	h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=WQalbE7LbMvjtpTwp5wk+Izyc6oXg/6u+QiLl+rrruRk+P/YKBs+cKQ8VTq276Ubi
	 XH/EYxonKLDYotzvui67F1GT8fNWcF5Q3vrBdnWMrNFuWeCpxcMZQ0Jt14toAlSRy8
	 8zze0a6Pz/NI4hCosto8ia6NUKdh6nO9xo1y4+KWn2H0YZfP93W/7WhPz3par/6z86
	 H9ew7OkcXrBg65d7+vIhAS0QTuwLKrhK/4uVJJQ6GlRExktZceWP5mSo+AcBjQypJc
	 GF08NS0w+vYkfM2FVDQk5x7dH6Buck6XhxnPq5CBmHSIQ0hjbKEoBiTOp728CUg6M2
	 wlFXRTPodLnZg==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1;
	t=1773043036; x=1773303536; i=ngoc-tu.dinh@vates.tech;
	bh=zY8FRcHPF2pSQJMp37XaauKL/Ejo3zct/vGdTgu7Qb0=;
	h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=qsSPMQJBY3NOtGKJbEhEuVRUjs2hXzqzMOiUtMyCPXdTqtn7hO2YedaRKKDGk//iK
	 r+MbtbvEPW+NMomaQxKy/Ryi+rU64m8bq1EcrcRWB1jOQgNGsq5RwEmglKTe8F0MPW
	 lz24d25Trmo8MJXMmq98JTcCn84GRJ5ST2OUeT51lXLmxhZig5HMPYQ4Jx7QHecAWX
	 UuHNXdBI6uHPZV+ZTkX9lj1O1SwI1nnkKcZ1IIsBOLYr4B5Jf0MAkIyN2oqMdchAzI
	 xMx7ifa9jW1MJwbY0GepHLwXbGWBv6oKsOxkr0trXRxxMq8Msp3xUDS1hXDg85G2ND
	 o1jBRr8jl9IYg==
From: "Tu Dinh" <ngoc-tu.dinh@vates.tech>
Subject: =?utf-8?Q?[PATCH=20v2]=20Fix=20compilation=20of=20checked=20build?=
X-Mailer: git-send-email 2.53.0.windows.1
X-Bm-Disclaimer: Yes
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1773043035903
To: win-pv-devel@lists.xenproject.org
Cc: "Tu Dinh" <ngoc-tu.dinh@vates.tech>, "Owen Smith" <owen.smith@citrix.com>
Message-Id: <20260309075713.142-1-ngoc-tu.dinh@vates.tech>
In-Reply-To: <SA6PR03MB7760DBF2D226BD7550D51FE0FE79A@SA6PR03MB7760.namprd03.prod.outlook.com>
References: <SA6PR03MB7760DBF2D226BD7550D51FE0FE79A@SA6PR03MB7760.namprd03.prod.outlook.com>
X-Native-Encoded: 1
X-Report-Abuse: =?UTF-8?Q?Please=20forward=20a=20copy=20of=20this=20message,=20including=20all=20headers,=20to=20abuse@mandrill.com.=20You=20can=20also=20report=20abuse=20here:=20https://mandrillapp.com/contact/abuse=3Fid=3D30504962.cd99788e9d0542049a3a4424e52bef0e?=
X-Mandrill-User: md_30504962
Feedback-ID: 30504962:30504962.20260309:md
Date: Mon, 09 Mar 2026 07:57:16 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit

* Redefine XEN_API to __declspec(dllexport) to avoid declaring LogPrintf
  and similar symbols in the same binary as dllimport.
* The BUG() macro was not correctly identified as noreturn in checked
  builds, causing a warning about uninitialized variables. Set the Value
  variable before calling BUG() as a workaround.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
---
 src/xen/hypercall.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/xen/hypercall.c b/src/xen/hypercall.c
index 3c68709..e5b2927 100644
--- a/src/xen/hypercall.c
+++ b/src/xen/hypercall.c
@@ -30,6 +30,9 @@
  * SUCH DAMAGE.
  */
 
+#undef  XEN_API
+#define XEN_API __declspec(dllexport)
+
 #include <ntddk.h>
 #include <xen.h>
 #include <intrin.h>
@@ -188,6 +191,7 @@ __Hypercall(
             Value = hypercall2_vmmcall(ord, arg1, arg2);
             break;
         default:
+            Value = 0;
             BUG("NO HYPERCALL INSTRUCTION");
         }
         break;
@@ -206,13 +210,14 @@ __Hypercall(
             Value = hypercall3_vmmcall(ord, arg1, arg2, arg3);
             break;
         default:
+            Value = 0;
             BUG("NO HYPERCALL INSTRUCTION");
         }
         break;
     }
     default:
-        ASSERT(FALSE);
         Value = 0;
+        BUG("INVALID HYPERCALL ARGUMENT COUNT");
     }
     va_end(Arguments);
 
-- 
2.53.0.windows.1



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Mon Mar 09 08:09:43 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Mon, 09 Mar 2026 08:09:43 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1249165.1546667 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vzVgM-0004D4-2I; Mon, 09 Mar 2026 08:09:42 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1249165.1546667; Mon, 09 Mar 2026 08:09:42 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1vzVgL-0004Cx-VX; Mon, 09 Mar 2026 08:09:41 +0000
Received: by outflank-mailman (input) for mailman id 1249165;
 Mon, 09 Mar 2026 08:09:40 +0000
Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50]
 helo=se1-gles-flk1.inumbo.com)
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <SRS0=flx5=BJ=citrix.com=owen.smith@srs-se1.protection.inumbo.net>)
 id 1vzVgK-0004Cr-Et
 for win-pv-devel@lists.xenproject.org; Mon, 09 Mar 2026 08:09:40 +0000
Received: from BL2PR02CU003.outbound.protection.outlook.com
 (mail-eastusazlp17011000f.outbound.protection.outlook.com
 [2a01:111:f403:c100::f])
 by se1-gles-flk1.inumbo.com (Halon) with ESMTPS
 id 4ea8d6d4-1b8f-11f1-9ccf-f158ae23cfc8;
 Mon, 09 Mar 2026 09:09:34 +0100 (CET)
Received: from SA6PR03MB7760.namprd03.prod.outlook.com (2603:10b6:806:43c::5)
 by SA2PR03MB5739.namprd03.prod.outlook.com (2603:10b6:806:114::10)
 with Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9678.25; Mon, 9 Mar
 2026 08:09:29 +0000
Received: from SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38]) by SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38%7]) with mapi id 15.20.9678.023; Mon, 9 Mar 2026
 08:09:30 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
X-Inumbo-ID: 4ea8d6d4-1b8f-11f1-9ccf-f158ae23cfc8
ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;
 b=EzbSZOhjIU4wFMsPiIG62Ny9Yw6DCAHxpou5wnl4jWhfcOFsJNeCRTUPw3W3rC70b13T3D89kDQKTLSWMV3k3HMraAqDbFJk6NtV1udwkFaQVhvmslDydN+KeCi5rJLS/YiTKv6+aLEG1cqkOVr/U9JP+yHdTZ4yjr0HDtQJn6l+YMyy+YIPb33aysTwWPtc8gQG0IP3azboZRlI+hu/3eibm6Ok7SSrllWMRdL+Q9/+koQICW64xpacl/keJl5/R9FVj/9gXQB/s/kFVaY4TgUkYssBpfvdgrcLx8jad0OXKGTwzFG0DPc/NVHIL5+bcyqokouemCVqQlnBgH4keg==
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=UTqYj5VEgXbERZ3ayK62wZhuXSfXPcTab/vZDCnxPUQ=;
 b=J+W3NzKd6AlaoNc/AAWhkzTYI9U2bYb5WRV285JWajJi2FvQavrijmTyHkWXULZbMBKURTcfdakDy6eU6yTr/z2Pw2HfZs17OL9eHgqUlXKQn9oidjX+rjanIV38WQaA2Wd90+NGtIOX+I+BMfQzV3JAu+D/7ojvdn1fbszOoUuLcYfOnZpzMuKDSC9KRPdRxWTwIa1gY50wVdt2KboZIgOLJQJ4SW18z9ZPKpqY3Mjt0nzEaXh5GhglR958+pMyuCZVNtR7EvZOAU+cR5ire4FJa7u1y0eNzdg/WwpIeS20sQebQpLJqSvcEewusKdGrt5F7AR/yJbOrqdNdo3FsQ==
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
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com;
 s=selector1;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=UTqYj5VEgXbERZ3ayK62wZhuXSfXPcTab/vZDCnxPUQ=;
 b=hc11zTt9lR5YLbclf7p6oD2G4oLZEenBpHhVW58jHCjkUSEhFS0kxasup+qOVo+MJClFU/nC+q0yuns/2KZ2dEgFxkCMP6T1JeBOCOs5Bl1kFqlSYHQPSBMPrOMxMsoBFOm+hYZF9OPcQtPW6lmPYtFALzx41GHoZpU1cOS3iHM=
From: Owen Smith <owen.smith@citrix.com>
To: Tu Dinh <ngoc-tu.dinh@vates.tech>, "win-pv-devel@lists.xenproject.org"
	<win-pv-devel@lists.xenproject.org>
Subject: Re: [PATCH v2] Fix compilation of checked build
Thread-Topic: [PATCH v2] Fix compilation of checked build
Thread-Index: AQHcr5paJT2qcXlmGUWZBMYiTQq9V7Wl2BSL
Date: Mon, 9 Mar 2026 08:09:30 +0000
Message-ID:
 <SA6PR03MB776074FF4D73E695874008E1FE79A@SA6PR03MB7760.namprd03.prod.outlook.com>
References:
 <SA6PR03MB7760DBF2D226BD7550D51FE0FE79A@SA6PR03MB7760.namprd03.prod.outlook.com>
 <20260309075713.142-1-ngoc-tu.dinh@vates.tech>
In-Reply-To: <20260309075713.142-1-ngoc-tu.dinh@vates.tech>
Accept-Language: en-GB, en-US
Content-Language: en-GB
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
msip_labels:
authentication-results: dkim=none (message not signed)
 header.d=none;dmarc=none action=none header.from=citrix.com;
x-ms-publictraffictype: Email
x-ms-traffictypediagnostic: SA6PR03MB7760:EE_|SA2PR03MB5739:EE_
x-ms-office365-filtering-correlation-id: 4419bf55-144c-4c40-1cb6-08de7db330df
x-ms-exchange-senderadcheck: 1
x-ms-exchange-antispam-relay: 0
x-microsoft-antispam: BCL:0;ARA:13230040|1800799024|376014|366016|38070700021;
x-microsoft-antispam-message-info:
 xSFLSGkxpCkg4t4Tql9tWZyif3yho2Kcui5CnBU4OBVk6o52Qo7VJKV1bTfo1dB/7fm3xpd9z9m5d2Wg/P/bjBR2BWYwUVIoPYseYN/RHJSIXkSbTZZCaAK3FVHXLa14gVGLSbnqfaiB/2t5imJ3fCVT07oGk006Iu41uFzZPdufUFBx5Q8AfV4S43WQEVWi5fsFTZcQWow2dj7FPvcPN06O3hIk8pAo12+T88GttrQuMSbEFzSJbSTQAFyK5dsZvxcziK660Abg1ReaeuxMH8loRLpBbMAYAOjroaTTlUE42iF/Ewqk+B8J7Ob47+MXFNENV0TWhk3S28c+eNAE0O7V/5LYYe/+rRuWA8v8pyBgj6jykI+BqXBZiPeXK3WfZwOOTsMOf5Pe+1UFumveoGeRJN9Av6zuUVC69pfU3PDAqwqCf4jx4YYTGEY5PzwBF9YnNCD6vEhtSjgl73O9Ww6jDXJNpDlcDMkcsKrV6sBffzpy+j3UbSBCy733tOxtZ7uzEJkWWfLN3IqE4m7JbJ8U5waN1Iufd+aO021x+zsySx9ZeGkykdZ9/sPYPo7gaJ40VbYGD9CxK3UCpdfkhr+rzAF42DpFjyFJABJ4g0IAlZqSkQVOmyvTcpL09liNRuQuXBHGGzbds1+pjXvrlx8tU/h95h7lcscMx03bGI2jriV0N77yOn20UIp156kuJ0VevtYqRoYycNGdPTbCDI2ifZAfC6NgfqvOQLIaUpY=
x-forefront-antispam-report:
 CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SA6PR03MB7760.namprd03.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(1800799024)(376014)(366016)(38070700021);DIR:OUT;SFP:1101;
x-ms-exchange-antispam-messagedata-chunkcount: 1
x-ms-exchange-antispam-messagedata-0:
 =?us-ascii?Q?OhuqnJ8y+ifvy2SxuyZdT0taamgOk1OKubFcnVeCBRUYkh8gsmQOPWdtnzah?=
 =?us-ascii?Q?7OuJZ7cl00JpT8HdjyZEfTchQ/dXHJWznEc2xUBzN0cvZh/QExy1AZxBPTzR?=
 =?us-ascii?Q?AHfPGIHnS5nDib6SrjTr+9wRbcVnd06x1hwRfyJOzBi13dKxagvi0vGCuIbG?=
 =?us-ascii?Q?0O1Z4tVMxq6H5znVgDQ33qqyfhOzDLavYIvIGPpaXwHS67Xo0RKfat/sHy3I?=
 =?us-ascii?Q?b+KGIHxruBiT+iWoQkFjIL7VljBqh+dz+cO3GdolgysOvWAfJEXRIQDFfxNk?=
 =?us-ascii?Q?N7YXp9MHQYAa2KbyFX8vuk7cEl9aOeWeGhMVcD1PFTcMWQCPXD9F2N/FLOgO?=
 =?us-ascii?Q?SIzdpXeoCeYsKaRHBwHBV/mNI/DHJXHRISCYI+i45aR+doeWfl0ozxCRuNWc?=
 =?us-ascii?Q?bmnNMNWcXnGouvBweXrPWMfmSSOMxMfLJaz+KjmOL4MSOXLkxkbvZGgkFw+I?=
 =?us-ascii?Q?5s2Nz5iQ2m/QtO4hDVtW/VcmnQtT0Dqm3dZjwQryz0RwppFeRvq4pa/RSlt8?=
 =?us-ascii?Q?jbj8FV/RosFrVraFbNGZo8iXtG/p/R0wLEuPGkOyoQTZcRLVLxhjCiEyMCTl?=
 =?us-ascii?Q?bauDUAULoL/T0TuAAKnx5ToZSU0u4xbFrIQIFB21bqKg8YWYLlbquX8w/MFp?=
 =?us-ascii?Q?6DfpFc0CbK5wU3Un1mBd8jCfh+nVP3nIIrfAUeRRKUnpnwL7CW1nPm484GpJ?=
 =?us-ascii?Q?ivdicHWbzNekaUD8lHzQMtHeyw5zJLUd3BmniY3G6VlL8KvE4daY3/GewZhu?=
 =?us-ascii?Q?2rQ0DNvKIIG3DE3tLYG7ugO0XRpAlZ9Wu/yEGErGAVtDmr5cy44zCJViHbmr?=
 =?us-ascii?Q?0hYomMS9rfSuq6ekeH3c1NQU2/JUDzT62rjPe0HgZN65emdaWIEQFbN2LqIM?=
 =?us-ascii?Q?KGGNBn8CUW6FEMgCKkGz/FsJOfHgJid2W8ceMithrgC1nEO+Ej1J5yD/5nD6?=
 =?us-ascii?Q?HP6UQ51VtyO9+Zmxs1Qp0CCvXus2kBY+dOgwCMArFz1AFaHjlma/4PziNfmO?=
 =?us-ascii?Q?FrrEEAyv8SK11LfRkfsrG0J2LU1rT+/ZxyZQ467kY5rpodQuS3Jza/JEPemx?=
 =?us-ascii?Q?MS5RPovSlJfz/1j1Qbw09zfQ1kaAsmnoXz+PzjhWpli2as+j7l5FDbfEorwy?=
 =?us-ascii?Q?u29X2lY+ENZf6oWYJpNMlRqEhmxNSmUi1r2p7Ec15jfFsGOzDjmewdXS5Y4D?=
 =?us-ascii?Q?+sP7GUXINi7hY7bHgowBsI7IChwWMRz7CTk8tqSy2xmASaKdW5DpvAoYUF7C?=
 =?us-ascii?Q?bJDgccjr7G6QyZTLgIsL5aMERTRa8k3noBMX4SjlIk7Hudor4C0Wyd5mX9P/?=
 =?us-ascii?Q?WaUPsnDDgVkkn7jyT4GEki3O0BhFbDruw6d5R2TgTVcgEkCnaVlPGNOR5Zdp?=
 =?us-ascii?Q?c0hPbcq2wGJWwEAGylO6AczrWpNlf4mflskefVvKMc8HYkktFtjqhndTCmSu?=
 =?us-ascii?Q?JUHX3dQhCQIKxAAnbtRnMmpFQrQBzGF4EWWVhNZvrUh67qFGgA/mWnhhJEeq?=
 =?us-ascii?Q?iGNUyMYfawm+3rZ9KuOA9g8fQcLMC3kUGgk5tc5VgG0t9HZBNpfsKy8/MiM6?=
 =?us-ascii?Q?lYwrv5WnulL8R/tssLyio8QuF93wJECQgZ6FTJ820iFNt/9QEShj9+61cwXy?=
 =?us-ascii?Q?NSn4EBlsWR3pFHwtjMYm4Q1tdaLfSeiJUjy31b1P02T/wMwBT92hv0fMc2H8?=
 =?us-ascii?Q?CslQrfXF+hNesA7TEWrxSgArR4oWvHCIZsbLmq7xShGsz885kXN20SdMOjUU?=
 =?us-ascii?Q?oYffNaKDbg=3D=3D?=
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
X-OriginatorOrg: citrix.com
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-AuthSource: SA6PR03MB7760.namprd03.prod.outlook.com
X-MS-Exchange-CrossTenant-Network-Message-Id: 4419bf55-144c-4c40-1cb6-08de7db330df
X-MS-Exchange-CrossTenant-originalarrivaltime: 09 Mar 2026 08:09:30.5512
 (UTC)
X-MS-Exchange-CrossTenant-fromentityheader: Hosted
X-MS-Exchange-CrossTenant-id: 335836de-42ef-43a2-b145-348c2ee9ca5b
X-MS-Exchange-CrossTenant-mailboxtype: HOSTED
X-MS-Exchange-CrossTenant-userprincipalname: k3g84iRL1UDubTY/MVZW+xWGBHEb0JOCZc1iU76kT4YzUGzoGgf0QjYIFJOcJv8kGkORtq9gPBDKX5y1Y/6chw==
X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA2PR03MB5739

Reviewed-by: Owen Smith <owen.smith@citrix.com>

________________________________________
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
Sent: 09 March 2026 7:57 AM
To: win-pv-devel@lists.xenproject.org
Cc: Tu Dinh; Owen Smith
Subject: [PATCH v2] Fix compilation of checked build

* Redefine XEN_API to __declspec(dllexport) to avoid declaring LogPrintf
  and similar symbols in the same binary as dllimport.
* The BUG() macro was not correctly identified as noreturn in checked
  builds, causing a warning about uninitialized variables. Set the Value
  variable before calling BUG() as a workaround.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
---
 src/xen/hypercall.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/xen/hypercall.c b/src/xen/hypercall.c
index 3c68709..e5b2927 100644
--- a/src/xen/hypercall.c
+++ b/src/xen/hypercall.c
@@ -30,6 +30,9 @@
  * SUCH DAMAGE.
  */

+#undef  XEN_API
+#define XEN_API __declspec(dllexport)
+
 #include <ntddk.h>
 #include <xen.h>
 #include <intrin.h>
@@ -188,6 +191,7 @@ __Hypercall(
             Value =3D hypercall2_vmmcall(ord, arg1, arg2);
             break;
         default:
+            Value =3D 0;
             BUG("NO HYPERCALL INSTRUCTION");
         }
         break;
@@ -206,13 +210,14 @@ __Hypercall(
             Value =3D hypercall3_vmmcall(ord, arg1, arg2, arg3);
             break;
         default:
+            Value =3D 0;
             BUG("NO HYPERCALL INSTRUCTION");
         }
         break;
     }
     default:
-        ASSERT(FALSE);
         Value =3D 0;
+        BUG("INVALID HYPERCALL ARGUMENT COUNT");
     }
     va_end(Arguments);

--
2.53.0.windows.1



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Fri Mar 27 09:33:49 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Fri, 27 Mar 2026 09:33:49 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1265262.1556263 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1w63Zb-0004xK-J3; Fri, 27 Mar 2026 09:33:47 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1265262.1556263; Fri, 27 Mar 2026 09:33:47 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1w63Zb-0004xC-G8; Fri, 27 Mar 2026 09:33:47 +0000
Received: by outflank-mailman (input) for mailman id 1265262;
 Fri, 27 Mar 2026 09:33:46 +0000
Received: from mx.expurgate.net ([195.190.135.10])
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <bounce-md_30504962.69c64ef7.v1-147a066bffe24896bc64765ba9139aa7@bounce.vates.tech>)
 id 1w63Za-0004x6-7T
 for win-pv-devel@lists.xenproject.org; Fri, 27 Mar 2026 09:33:46 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1w63ZX-001rqe-Tv
 for win-pv-devel@lists.xenproject.org; Fri, 27 Mar 2026 10:33:45 +0100
Received: from [10.42.69.6] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from
 <bounce-md_30504962.69c64ef7.v1-147a066bffe24896bc64765ba9139aa7@bounce.vates.tech>)
 id 69c64ef6-bab6-0a2a0a5309dd-0a2a450690e6-18
 for <win-pv-devel@lists.xenproject.org>; Fri, 27 Mar 2026 10:33:45 +0100
Received: from [198.2.132.14] (helo=mail132-14.atl131.mandrillapp.com)
 by tlsNG-16d1c6.mxtls.expurgate.net with ESMTPS (eXpurgate 4.55.2)
 (envelope-from
 <bounce-md_30504962.69c64ef7.v1-147a066bffe24896bc64765ba9139aa7@bounce.vates.tech>)
 id 69c64ef8-3034-0a2a45060019-c602840eb325-3
 for <win-pv-devel@lists.xenproject.org>; Fri, 27 Mar 2026 10:33:45 +0100
Received: from pmta09.mandrill.prod.atl01.rsglab.com (localhost [127.0.0.1])
 by mail132-14.atl131.mandrillapp.com (Mailchimp) with ESMTP id
 4fhwSR5j3Jz8XRxvP
 for <win-pv-devel@lists.xenproject.org>; Fri, 27 Mar 2026 09:33:43 +0000 (GMT)
Received: from [37.26.189.201] by mandrillapp.com id
 147a066bffe24896bc64765ba9139aa7; Fri, 27 Mar 2026 09:33:43 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=mte1 header.d=mandrillapp.com header.i="@mandrillapp.com" header.h="From:Subject:To:Cc:Message-Id:Feedback-ID:Date:MIME-Version:Content-Type:Content-Transfer-Encoding"; dkim=pass header.s=mte1 header.d=vates.tech header.i="ngoc-tu.dinh@vates.tech" header.h="From:Subject:To:Cc:Message-Id:Feedback-ID:Date:MIME-Version:Content-Type:Content-Transfer-Encoding"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com;
	s=mte1; t=1774604023; x=1774874023;
	bh=0P/QmY9q/FHfcsO+guuCxd7zK6ibFvkmsY8zz+k0MF8=;
	h=From:Subject:To:Cc:Message-Id:Feedback-ID:Date:MIME-Version:
	 Content-Type:Content-Transfer-Encoding:CC:Date:Subject:From;
	b=WeI0Ok6zqBfDawdmDUMhvYoLbqeiaYSrB+QQcAhP+Bl54ngnAq4QTUahmPhMshsqA
	 f7iWAqyDeHB/b9Qhlmr4jEC75mL4qHfcU+4UANUcCZZWt5wH8J0s8ny1UFIunvqy8r
	 wY4axQEkZXHNXaPNdtv2+VBGdmo9RqXZr4OR8aRfOWG2SRoPzLgDoBkJ3MCoYt33vj
	 uf82mqrBwFOSFvy24haaqdvIhNr32dt6V/+H1J0+Et/WyX80L2PLQWxBpSFrEnCii9
	 yfKlklXTEWCpWbwFDhwEDaM50dWAMVReVU6WNiak5OsRbSvtPpky1zFLdHnhKs7oHG
	 2d+KsVk04ZvXA==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1;
	t=1774604023; x=1774864523; i=ngoc-tu.dinh@vates.tech;
	bh=0P/QmY9q/FHfcsO+guuCxd7zK6ibFvkmsY8zz+k0MF8=;
	h=From:Subject:To:Cc:Message-Id:Feedback-ID:Date:MIME-Version:
	 Content-Type:Content-Transfer-Encoding:CC:Date:Subject:From;
	b=tzLPjPjVqtRvhztMQolDIz1lzwbIwYtBmC28YMRjJf+WXt3ucDhO1DRWzsdYMcHc4
	 qhN18cOey4ZENzzpWTvGHcoRQZ8nFwOqLwWmb0xq5KpxDn6bG31k9HxjKo2GyCczIa
	 ReDI5LEWosJm7zzLc4Q4yBzXKJSOq4bxHj5/q6hSZz1Si+xppH+GseIJGzzybzVDQY
	 12LqD2JcxM9GVehc6ekvUIarkdim42kFUV4Is7HcWUn0yf42B/jadRB48sv3zILAUF
	 zjLATVouy6K+36mCNZ0Yp7WYRAUIyYx7Aro6ckbGVOPfJh4E+h2wfexEp5GAzhn2VI
	 8GHXwANHKu3YQ==
From: "Tu Dinh" <ngoc-tu.dinh@vates.tech>
Subject: =?utf-8?Q?[RFC=20PATCH]=20Call=20EvtchnUnmask=20within=20the=20BlkifRing=20lock?=
X-Mailer: git-send-email 2.53.0.windows.2
X-Bm-Disclaimer: Yes
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1774604022743
To: win-pv-devel@lists.xenproject.org
Cc: "Tu Dinh" <ngoc-tu.dinh@vates.tech>, "Owen Smith" <owen.smith@citrix.com>
Message-Id: <20260327093338.493-1-ngoc-tu.dinh@vates.tech>
X-Native-Encoded: 1
X-Report-Abuse: =?UTF-8?Q?Please=20forward=20a=20copy=20of=20this=20message,=20including=20all=20headers,=20to=20abuse@mandrill.com.=20You=20can=20also=20report=20abuse=20here:=20https://mandrillapp.com/contact/abuse=3Fid=3D30504962.147a066bffe24896bc64765ba9139aa7?=
X-Mandrill-User: md_30504962
Feedback-ID: 30504962:30504962.20260327:md
Date: Fri, 27 Mar 2026 09:33:43 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit
X-purgate-ID: tlsNG-16d1c6/1774604025-7A1931C2-4ED743DC/0/0
X-purgate-type: clean
X-purgate-size: 6567

The call to EvtchnUnmask accesses Channel outside of the blkif ring
lock. Therefore, it can access a stale channel if the DPC is still
running after the channel has been closed in BlkifRingDisconnect. Since
BlkifRingDisconnect runs at DISPATCH_LEVEL, we cannot use
KeFlushQueuedDpcs and have to guard against the event channel's closure
via the Enabled flag instead.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
---

Notes:
    This issue is reliably reproducible by repeatedly suspending/resuming or
    migrating a VM, which at some point will cause it to lock up when trying
    to acquire a lock on the event channel. The failure will typically
    happen within 100 resume cycles. Note the corrupted event channel below:
    
        nt!KeBugCheckEx:
        fffff803`e3f3ad20 48894c2408      mov     qword ptr [rsp+8],rcx ss:0018:fffff803`79b9eb50=0000000000000080
        0: kd> kP
         # Child-SP          RetAddr               Call Site
        00 fffff803`79b9eb48 fffff803`e3f832e2     nt!KeBugCheckEx
        01 fffff803`79b9eb50 fffff803`e3f7d8d9     nt!HalpNMIHalt+0x2e
        02 fffff803`79b9eb90 fffff803`750a129b     nt!HalBugCheckSystem+0x69
        03 fffff803`79b9ebd0 fffff803`e411f632     PSHED!PshedBugCheckSystem+0xb
        04 fffff803`79b9ec00 fffff803`e3f830bb     nt!WheaReportHwError+0x2b5752
        05 fffff803`79b9ecc0 fffff803`e3ff6daf     nt!HalHandleNMI+0x14b
        06 fffff803`79b9ecf0 fffff803`e40eeac2     nt!KiProcessNMI+0xff
        07 fffff803`79b9ed30 fffff803`e40ee82e     nt!KxNmiInterrupt+0x82
        08 fffff803`79b9ee70 fffff803`e3c94e6c     nt!KiNmiInterrupt+0x26e
        09 ffff9600`a38a7640 fffff803`e3c94d5e     nt!KxWaitForSpinLockAndAcquire+0x1c
        0a ffff9600`a38a7670 fffff803`e4064a62     nt!KeAcquireSpinLockRaiseToDpc+0x5e
        0b ffff9600`a38a76a0 fffff803`e45df368     nt!DifKeAcquireSpinLockRaiseToDpcWrapper+0xd2
        0c ffff9600`a38a76f0 fffff803`761f59ea     nt!VerifierKeAcquireSpinLockRaiseToDpc+0x28
        0d ffff9600`a38a7720 fffff803`78a1dcd0     xenbus!EvtchnUnmask(
                    struct _INTERFACE * Interface = <Value unavailable error>,
                    struct _XENBUS_EVTCHN_CHANNEL * Channel = 0xffffbe01`a45fcf80,
                    unsigned char InUpcall = 0x00 '',
                    unsigned char Force = 0x01 '')+0x3a [xenbus\src\xenbus\evtchn.c @ 824]
        0e ffff9600`a38a7760 fffff803`e3c95b42     xenvbd!BlkifRingDpc(
                    struct _KDPC * Dpc = 0xfffff803`74b29a00,
                    void * Context = 0xffffbe01`a4116e50,
                    void * Argument1 = 0x00000000`00000000,
                    void * Argument2 = 0x00000000`00000000)+0x3c0 [xenvbd\src\xenvbd\ring.c @ 1627]
        0f ffff9600`a38a77d0 fffff803`e4006592     nt!KiExecuteAllDpcs+0x692
        10 ffff9600`a38a7a10 fffff803`e3ec7dca     nt!KiExecuteDpc+0xc2
        11 ffff9600`a38a7bf0 fffff803`e40e3c74     nt!PspSystemThreadStartup+0x5a
        12 ffff9600`a38a7c40 00000000`00000000     nt!KiStartSystemThread+0x34
        0: kd> dx -id 0,0,ffffbe019f6f5040 -r1 ((xenbus!_XENBUS_EVTCHN_CHANNEL *)0xffffbe01a45fcf80)
        ((xenbus!_XENBUS_EVTCHN_CHANNEL *)0xffffbe01a45fcf80)                 : 0xffffbe01a45fcf80 [Type: _XENBUS_EVTCHN_CHANNEL *]
            [+0x000] Magic            : 0x28 [Type: unsigned long]
            [+0x008] Lock             : 0xffffffff [Type: unsigned __int64]
            [+0x010] ListEntry        [Type: _LIST_ENTRY]
            [+0x020] PendingListEntry [Type: _LIST_ENTRY]
            [+0x030] Pending          : -1542361520 [Type: long]
            [+0x038] Caller           : 0xffffbe01a4cb9010 [Type: void *]
            [+0x040] Callback         : 0xffffbe01a4cb9010 : 0xffffbe01a4cb9010 [Type: unsigned char (__cdecl*)(_KINTERRUPT *,void *)]
            [+0x048] Argument         : 0xffffbe01a4cb9010 [Type: void *]
            [+0x050] Active           : 0x65 [Type: unsigned char]
            [+0x054] Count            : 0x0 [Type: unsigned long]
            [+0x058] Type             : -1527206080 [Type: _XENBUS_EVTCHN_TYPE]
            [+0x05c] Parameters       [Type: _XENBUS_EVTCHN_PARAMETERS]
            [+0x064] Mask             : 0x1 [Type: unsigned char]
            [+0x068] LocalPort        : 0x1 [Type: unsigned long]
            [+0x06c] Cpu              : 0x0 [Type: unsigned long]
            [+0x070] Closed           : 0x2f [Type: unsigned char]
    
    Xencons may benefit from the same change.
    
    This patch will probably hurt performance in some way, but calling
    EvtchnUnmask within the lock is needed to ensure that the channel is
    alive.
    
    Xencons tries to fix this problem by skipping the unmask call when the
    ring is not enabled, but Enabled could have gone stale by the time it
    has reached the unmask, and so KeFlushQueuedDpcs is still needed to
    chase out any running DPCs before closing the channel.
    
    It might be possible to fix this by signaling the end of each DPC with
    an atomic, then synchronize with that in RingDisconnect, but I haven't
    investigated whether that'd help performance.

 src/xenvbd/ring.c | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/src/xenvbd/ring.c b/src/xenvbd/ring.c
index 50f8d58..409d6ab 100644
--- a/src/xenvbd/ring.c
+++ b/src/xenvbd/ring.c
@@ -1611,19 +1611,27 @@ BlkifRingDpc(
 
         KeRaiseIrql(DISPATCH_LEVEL, &Irql);
         __BlkifRingAcquireLock(BlkifRing);
-        Retry = BlkifRingPoll(BlkifRing);
+
+        if (BlkifRing->Enabled) {
+            Retry = BlkifRingPoll(BlkifRing);
+
+            if (!Retry) {
+                (VOID) XENBUS_EVTCHN(Unmask,
+                                     &Ring->EvtchnInterface,
+                                     BlkifRing->Channel,
+                                     FALSE,
+                                     TRUE);
+            }
+        } else {
+            Retry = FALSE;
+        }
+
         __BlkifRingReleaseLock(BlkifRing);
         KeLowerIrql(Irql);
 
         if (!Retry)
             break;
     }
-
-    XENBUS_EVTCHN(Unmask,
-                  &Ring->EvtchnInterface,
-                  BlkifRing->Channel,
-                  FALSE,
-                  TRUE);
 }
 
 #define TIME_US(_us)        ((_us) * 10)
-- 
2.53.0.windows.2



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Fri Mar 27 09:37:00 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Fri, 27 Mar 2026 09:37:00 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1265272.1556275 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1w63ci-0005bO-1H; Fri, 27 Mar 2026 09:37:00 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1265272.1556275; Fri, 27 Mar 2026 09:37:00 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1w63ch-0005bH-Uq; Fri, 27 Mar 2026 09:36:59 +0000
Received: by outflank-mailman (input) for mailman id 1265272;
 Fri, 27 Mar 2026 09:36:59 +0000
Received: from mx.expurgate.net ([195.190.135.10])
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <bounce-md_30504962.69c64fb8.v1-fa5c2cbb3dba4aaea6805ac5ae087398@bounce.vates.tech>)
 id 1w63ch-0005b9-6n
 for win-pv-devel@lists.xenproject.org; Fri, 27 Mar 2026 09:36:59 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1w63ce-001t1j-W8
 for win-pv-devel@lists.xenproject.org; Fri, 27 Mar 2026 10:36:58 +0100
Received: from [10.42.69.3] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from
 <bounce-md_30504962.69c64fb8.v1-fa5c2cbb3dba4aaea6805ac5ae087398@bounce.vates.tech>)
 id 69c64fae-bab6-0a2a0a5309dd-0a2a4503a3be-32
 for <win-pv-devel@lists.xenproject.org>; Fri, 27 Mar 2026 10:36:58 +0100
Received: from [198.2.179.37] (helo=mail179-37.suw41.mandrillapp.com)
 by tlsNG-33051d.mxtls.expurgate.net with ESMTPS (eXpurgate 4.55.2)
 (envelope-from
 <bounce-md_30504962.69c64fb8.v1-fa5c2cbb3dba4aaea6805ac5ae087398@bounce.vates.tech>)
 id 69c64fb9-1947-0a2a45030019-c602b325690f-3
 for <win-pv-devel@lists.xenproject.org>; Fri, 27 Mar 2026 10:36:58 +0100
Received: from pmta12.mandrill.prod.suw01.rsglab.com (localhost [127.0.0.1])
 by mail179-37.suw41.mandrillapp.com (Mailchimp) with ESMTP id
 4fhwX909hczG0CMG9
 for <win-pv-devel@lists.xenproject.org>; Fri, 27 Mar 2026 09:36:57 +0000 (GMT)
Received: from [37.26.189.201] by mandrillapp.com id
 fa5c2cbb3dba4aaea6805ac5ae087398; Fri, 27 Mar 2026 09:36:56 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=mte1 header.d=mandrillapp.com header.i="@mandrillapp.com" header.h="From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID:Date:MIME-Version:Content-Type:Content-Transfer-Encoding"; dkim=pass header.s=mte1 header.d=vates.tech header.i="ngoc-tu.dinh@vates.tech" header.h="From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID:Date:MIME-Version:Content-Type:Content-Transfer-Encoding"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com;
	s=mte1; t=1774604217; x=1774874217;
	bh=IdTCgynKVinhp/HFxfsQjxPXWDYgihV74e6QHQhOlyY=;
	h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=1ghrwC0VMGi/JtFmnCwETRc6L9ROCaOqh8JL6rCg4X9+sMdlcRzGrayu21Xqqnmcp
	 35V7f7EPI1wcayY+pXqHIzojBJxw9j8cHGQNFb/z9YVWTLeOYxrEhCUEkM2mL6CW6W
	 sri8ZqNklgm4LoElH41psT1XHW6yXaR6Qg7MlGLi6X0/ujRpfvnjvmAClXW3FzlMi0
	 A7wS3Py81GU0Sel63cWKKNtwjoQDBqYXEd0ZNqXmJFNtVej8fKP2t46S8kyW6cLV+B
	 H38wAj0HV2WWEDFUEHw0FcrqZvO49VO9Sc1RsHSplC0NhFpfVQLdvRtSgao+fZCjwu
	 jsdp6gTlyyp0g==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1;
	t=1774604217; x=1774864717; i=ngoc-tu.dinh@vates.tech;
	bh=IdTCgynKVinhp/HFxfsQjxPXWDYgihV74e6QHQhOlyY=;
	h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=ajJ2WjMyQwbMRUU1vtvt6dckqvZI/A67PiToZ2uv6v8vFkqaopkAVNQ28xGlLl/65
	 uK6dQE/B9r9Gu0BBOxyLc7z8uFuuW67OnWhplh2ZK+qCma1OVGPT6Lu8M2HztHxbVT
	 4lRcQbP01yoBfvZG8Xb2SdVNXY+5MSB98MuYW1OZH6RM62XPIUuwnaDfRjPdpOETDt
	 YHhgM2S+PQtPFsw+3a7whUVwySuboZ2Agy0bKMmBY2ybXQZuvJd0WXygIRCznFwt0k
	 XzYi6fdlCd5FvScg7h5V8zSOBg3jKP5g+Gx1HEihLeGq9NVNwJq6vijfQF+6E5cVhc
	 +dKDHFa34c7rg==
From: "Tu Dinh" <ngoc-tu.dinh@vates.tech>
Subject: =?utf-8?Q?[RFC=20XENCONS=20PATCH]=20Call=20EvtchnUnmask=20within=20the=20BlkifRing=20lock?=
X-Mailer: git-send-email 2.53.0.windows.2
X-Bm-Disclaimer: Yes
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1774604216224
To: win-pv-devel@lists.xenproject.org
Cc: "Tu Dinh" <ngoc-tu.dinh@vates.tech>, "Owen Smith" <owen.smith@citrix.com>
Message-Id: <20260327093653.130-1-ngoc-tu.dinh@vates.tech>
In-Reply-To: <20260327093338.493-1-ngoc-tu.dinh@vates.tech>
References: <20260327093338.493-1-ngoc-tu.dinh@vates.tech>
X-Native-Encoded: 1
X-Report-Abuse: =?UTF-8?Q?Please=20forward=20a=20copy=20of=20this=20message,=20including=20all=20headers,=20to=20abuse@mandrill.com.=20You=20can=20also=20report=20abuse=20here:=20https://mandrillapp.com/contact/abuse=3Fid=3D30504962.fa5c2cbb3dba4aaea6805ac5ae087398?=
X-Mandrill-User: md_30504962
Feedback-ID: 30504962:30504962.20260327:md
Date: Fri, 27 Mar 2026 09:36:56 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit
X-purgate-ID: tlsNG-33051d/1774604218-EAE8572C-025E1492/0/0
X-purgate-type: clean
X-purgate-size: 2006

The call to EvtchnUnmask accesses Channel outside of the ring lock.
Therefore, it can access a stale channel if the DPC is still running
after the channel has been closed in RingDisconnect. Since
RingDisconnect runs at DISPATCH_LEVEL, we cannot use KeFlushQueuedDpcs
and have to guard against the event channel's closure via the Enabled
flag instead.

Ported from XenVbd.
---
 src/xencons/ring.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/src/xencons/ring.c b/src/xencons/ring.c
index afa9311..61c082b 100644
--- a/src/xencons/ring.c
+++ b/src/xencons/ring.c
@@ -567,30 +567,30 @@ RingDpc(
     ASSERT(Ring != NULL);
 
     for (;;) {
-        BOOLEAN Enabled;
         BOOLEAN Retry;
         KIRQL   Irql;
 
         KeAcquireSpinLock(&Ring->Lock, &Irql);
-        Enabled = Ring->Enabled;
-        KeReleaseSpinLock(&Ring->Lock, Irql);
 
-        if (!Enabled)
-            break;
+        if (Ring->Enabled) {
+            Retry = RingPoll(Ring);
+
+            if (!Retry) {
+                (VOID) XENBUS_EVTCHN(Unmask,
+                                     &Ring->EvtchnInterface,
+                                     Ring->Channel,
+                                     FALSE,
+                                     FALSE);
+            }
+        } else {
+            Retry = FALSE;
+        }
 
-        KeRaiseIrql(DISPATCH_LEVEL, &Irql);
-        Retry = RingPoll(Ring);
-        KeLowerIrql(Irql);
+        KeReleaseSpinLock(&Ring->Lock, Irql);
 
         if (!Retry)
             break;
     }
-
-    (VOID) XENBUS_EVTCHN(Unmask,
-                         &Ring->EvtchnInterface,
-                         Ring->Channel,
-                         FALSE,
-                         FALSE);
 }
 
 _Function_class_(KSERVICE_ROUTINE)
-- 
2.53.0.windows.2



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Fri Mar 27 09:56:25 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Fri, 27 Mar 2026 09:56:25 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1265283.1556279 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1w63vU-0000Gg-Bm; Fri, 27 Mar 2026 09:56:24 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1265283.1556279; Fri, 27 Mar 2026 09:56:24 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1w63vU-0000GZ-9C; Fri, 27 Mar 2026 09:56:24 +0000
Received: by outflank-mailman (input) for mailman id 1265283;
 Fri, 27 Mar 2026 09:56:23 +0000
Received: from mx.expurgate.net ([195.190.135.10])
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <bounce-md_30504962.69c65444.v1-d68f5930715c4b90ba47e3aae2cadd55@bounce.vates.tech>)
 id 1w63vT-0000GS-5L
 for win-pv-devel@lists.xenproject.org; Fri, 27 Mar 2026 09:56:23 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1w63vS-00ByBh-Hn
 for win-pv-devel@lists.xenproject.org; Fri, 27 Mar 2026 10:56:22 +0100
Received: from [10.42.69.7] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from
 <bounce-md_30504962.69c65444.v1-d68f5930715c4b90ba47e3aae2cadd55@bounce.vates.tech>)
 id 69c65441-5cb7-0a2a0a5109dd-0a2a4507edd8-32
 for <win-pv-devel@lists.xenproject.org>; Fri, 27 Mar 2026 10:56:22 +0100
Received: from [198.2.132.14] (helo=mail132-14.atl131.mandrillapp.com)
 by tlsNG-ef75cf.mxtls.expurgate.net with ESMTPS (eXpurgate 4.55.2)
 (envelope-from
 <bounce-md_30504962.69c65444.v1-d68f5930715c4b90ba47e3aae2cadd55@bounce.vates.tech>)
 id 69c65445-fd74-0a2a45070019-c602840e7155-3
 for <win-pv-devel@lists.xenproject.org>; Fri, 27 Mar 2026 10:56:22 +0100
Received: from pmta09.mandrill.prod.atl01.rsglab.com (localhost [127.0.0.1])
 by mail132-14.atl131.mandrillapp.com (Mailchimp) with ESMTP id
 4fhwyX710Bz8XRyhC
 for <win-pv-devel@lists.xenproject.org>; Fri, 27 Mar 2026 09:56:20 +0000 (GMT)
Received: from [37.26.189.201] by mandrillapp.com id
 d68f5930715c4b90ba47e3aae2cadd55; Fri, 27 Mar 2026 09:56:20 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=mte1 header.d=mandrillapp.com header.i="@mandrillapp.com" header.h="From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID:Date:MIME-Version:Content-Type:Content-Transfer-Encoding"; dkim=pass header.s=mte1 header.d=vates.tech header.i="ngoc-tu.dinh@vates.tech" header.h="From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID:Date:MIME-Version:Content-Type:Content-Transfer-Encoding"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com;
	s=mte1; t=1774605381; x=1774875381;
	bh=BqpPD7NZjP+vHBfFyAVtpI7myb5QBK3cJJiZPK3zZTQ=;
	h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=hQdNsKSr1rO9LTv5bNAtqZ6hxPWJXZWxBQHq0BwIZZEQdKnMpaQLtAVKDO4a6Ibx9
	 hFOfckHkNnJhXSgHcGzXlMTkzMWJ41YduTRhc3R1twmUSnEgOTavMKq2+DVUZg1dEn
	 SobtKx5cGabHz4NGmUPNMCnfgZHtzj4troyl9IMeGbuPCRkfBcFjsgLBp+isNIm9Lv
	 Qo1DvtyeoILyZeB7vrr+ayZTCIGbUemz/Zd1s6ODplsD3AOUgdm8JRasB87NFFqnWy
	 +5ZzwDa8kImVWFHemxzPNwcER2NDarDQHuE/Tyw+8L5QPrqgr6cvwblKwYnyNFuYRr
	 2T2A3rWbfpn8A==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1;
	t=1774605381; x=1774865881; i=ngoc-tu.dinh@vates.tech;
	bh=BqpPD7NZjP+vHBfFyAVtpI7myb5QBK3cJJiZPK3zZTQ=;
	h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=1aMcQSptLD4gV5m3Q73I0oUyBrGi70itWdtDegy7jGnw5li+2Gltqd1A9yhNBc7Dl
	 gVlJqKlyOtQHvgE1sem6/lhgeWvEufQWA07F0AT+iG4tHioW13JQDE0YxJ7C92mOnz
	 yx5ZhjNgx/sqI/YHunDPEkn5F2p6wuOUyu04EtqRTwzwGvq6TI/nKEyJsYyM6yhvPo
	 08BmEGI6isDWgI2fy9YfANLPGP37iOtxAB9xgfxckdPMiK54gMAZHDRswl2v2ZMc9O
	 L+HhwXzyXam80Ah4pNXnyojZ/+HLYp27tsVHm0CyFnnRMrL0aGYN5LvMAHbTDzzfAs
	 zG9DgE6gpItsA==
From: "Tu Dinh" <ngoc-tu.dinh@vates.tech>
Subject: =?utf-8?Q?[RFC=20XENCONS=20PATCH=20RESEND]=20Call=20EvtchnUnmask=20within=20the=20BlkifRing=20lock?=
X-Mailer: git-send-email 2.53.0.windows.2
X-Bm-Disclaimer: Yes
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1774605380201
To: win-pv-devel@lists.xenproject.org
Cc: "Tu Dinh" <ngoc-tu.dinh@vates.tech>, "Owen Smith" <owen.smith@citrix.com>
Message-Id: <20260327095617.1792-1-ngoc-tu.dinh@vates.tech>
In-Reply-To: <20260327093653.130-1-ngoc-tu.dinh@vates.tech>
References: <20260327093653.130-1-ngoc-tu.dinh@vates.tech>
X-Native-Encoded: 1
X-Report-Abuse: =?UTF-8?Q?Please=20forward=20a=20copy=20of=20this=20message,=20including=20all=20headers,=20to=20abuse@mandrill.com.=20You=20can=20also=20report=20abuse=20here:=20https://mandrillapp.com/contact/abuse=3Fid=3D30504962.d68f5930715c4b90ba47e3aae2cadd55?=
X-Mandrill-User: md_30504962
Feedback-ID: 30504962:30504962.20260327:md
Date: Fri, 27 Mar 2026 09:56:20 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit
X-purgate-ID: tlsNG-ef75cf/1774605382-4FCA2303-DF37EDEC/0/0
X-purgate-type: clean
X-purgate-size: 2076

The call to EvtchnUnmask accesses Channel outside of the ring lock.
Therefore, it can access a stale channel if the DPC is still running
after the channel has been closed in RingDisconnect. Since
RingDisconnect runs at DISPATCH_LEVEL, we cannot use KeFlushQueuedDpcs
and have to guard against the event channel's closure via the Enabled
flag instead.

Ported from XenVbd.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
---
Resend with signoff.
---
 src/xencons/ring.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/src/xencons/ring.c b/src/xencons/ring.c
index afa9311..61c082b 100644
--- a/src/xencons/ring.c
+++ b/src/xencons/ring.c
@@ -567,30 +567,30 @@ RingDpc(
     ASSERT(Ring != NULL);

     for (;;) {
-        BOOLEAN Enabled;
         BOOLEAN Retry;
         KIRQL   Irql;

         KeAcquireSpinLock(&Ring->Lock, &Irql);
-        Enabled = Ring->Enabled;
-        KeReleaseSpinLock(&Ring->Lock, Irql);

-        if (!Enabled)
-            break;
+        if (Ring->Enabled) {
+            Retry = RingPoll(Ring);
+
+            if (!Retry) {
+                (VOID) XENBUS_EVTCHN(Unmask,
+                                     &Ring->EvtchnInterface,
+                                     Ring->Channel,
+                                     FALSE,
+                                     FALSE);
+            }
+        } else {
+            Retry = FALSE;
+        }

-        KeRaiseIrql(DISPATCH_LEVEL, &Irql);
-        Retry = RingPoll(Ring);
-        KeLowerIrql(Irql);
+        KeReleaseSpinLock(&Ring->Lock, Irql);

         if (!Retry)
             break;
     }
-
-    (VOID) XENBUS_EVTCHN(Unmask,
-                         &Ring->EvtchnInterface,
-                         Ring->Channel,
-                         FALSE,
-                         FALSE);
 }

 _Function_class_(KSERVICE_ROUTINE)
--
2.53.0.windows.2


--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Fri Mar 27 14:01:49 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Fri, 27 Mar 2026 14:01:49 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1265744.1556525 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1w67kx-000090-La; Fri, 27 Mar 2026 14:01:47 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1265744.1556525; Fri, 27 Mar 2026 14:01:47 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1w67kx-00008t-Is; Fri, 27 Mar 2026 14:01:47 +0000
Received: by outflank-mailman (input) for mailman id 1265744;
 Fri, 27 Mar 2026 14:01:46 +0000
Received: from mx.expurgate.net ([195.190.135.10])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <owen.smith@citrix.com>) id 1w67kw-00008T-9R
 for win-pv-devel@lists.xenproject.org; Fri, 27 Mar 2026 14:01:46 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1w67kv-008Wo8-Ka
 for win-pv-devel@lists.xenproject.org; Fri, 27 Mar 2026 15:01:45 +0100
Received: from [10.42.69.5] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1)
 (envelope-from <owen.smith@citrix.com>)
 id 69c68dc6-e002-0a2a0a5209dd-0a2a4505b05a-12
 for <win-pv-devel@lists.xenproject.org>; Fri, 27 Mar 2026 15:01:45 +0100
Received: from [40.107.209.61]
 (helo=PH8PR06CU001.outbound.protection.outlook.com)
 by tlsNG-c201ff.mxtls.expurgate.net with ESMTPS (eXpurgate 4.55.2)
 (envelope-from <owen.smith@citrix.com>)
 id 69c68dc6-5aeb-0a2a45050019-286bd13d96da-3
 for <win-pv-devel@lists.xenproject.org>; Fri, 27 Mar 2026 15:01:44 +0100
Received: from SA6PR03MB7760.namprd03.prod.outlook.com (2603:10b6:806:43c::5)
 by BY5PR03MB4920.namprd03.prod.outlook.com (2603:10b6:a03:1f0::18)
 with Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9723.19; Fri, 27 Mar
 2026 14:01:39 +0000
Received: from SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38]) by SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38%7]) with mapi id 15.20.9745.023; Fri, 27 Mar 2026
 14:01:39 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=citrix.com header.i="@citrix.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:x-ms-exchange-senderadcheck"
ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;
 b=OeWD6w++X+lQpFWuSyWj6RWdLVN4Oj14skWwUbsbkNR0UfZoG3D+hAtsGW22KCXc/aOtTyeXY/z1VxpYUWra7VEUlM6o71i20+PU/QyLhBdEm2DkIoaArheN2o/CcyWqXoAxD4tzH4m09OB9ROtAXzpcnmV4nQz98VuU4ydLpir3f9l5iIzyWxLX5bFqKGmN5y7stAuSem3nBIOSWi1pjrNOGDB35gdV/2pnRWdLDF7r2rETlpuWYfaFOya4AhAXVObgGjlMFIZOIPESk07/HLf0GaN/DrMmxHUSFvhgxLYtTz0UuVMYvskbMu9sXg8SDnQEVJDGaKU01eiTNi6uMQ==
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=CFinFyn8NM32H1WFp9uggNaqLX8jxpt5SCnqsa3geks=;
 b=vwJoT1qGw5+sPzUNZvXvWKKl/BU7TTTJw7Rc0chX4aqR/hOz2h9G5ltvTYssVC5pQdImG4TLVYyV5MRNnlIyYRyCRcKXZA4bdtlfxxP92qw6h8YKXvsqC9KI9Wc8Y6ohziNbLR1x0khU3CJu6Omz1EFFq8EPxS88MnUO/jPhj26lhvABOu7WQbHBvd9nwUhHlvrC/4r0hU+WBWw4dEnBR4YWwwTFTWsYwwXOQtgWVFMGXpKhFbIRwQuwyuXKeKzSV7StHJxxVlfsGrjONIfktNOKI0VYlTjI3WY6OHv9PF40TlSku1ByXtBg0k9dcYat4NDKinD33TMGTqCbJyGc+Q==
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
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com;
 s=selector1;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=CFinFyn8NM32H1WFp9uggNaqLX8jxpt5SCnqsa3geks=;
 b=oko4gKqJjIYK6udwcp9Bkoqve3+bJR0MZSfY/mHc3ZxdZUg1BAMrUQC8YiY8o3eWFc6Hd7yYXpGnv4lBz7H8NBXNT+4ICXyC2L0ldEh2nuJ0V91oAK8UQt6bvhvpmlSJT/fJ+uq53qH2Z7B0noP5WB4y2ofq1v3pL/ZV58WgRp8=
From: Owen Smith <owen.smith@citrix.com>
To: Tu Dinh <ngoc-tu.dinh@vates.tech>, "win-pv-devel@lists.xenproject.org"
	<win-pv-devel@lists.xenproject.org>
Subject: Re: [RFC PATCH] Call EvtchnUnmask within the BlkifRing lock
Thread-Topic: [RFC PATCH] Call EvtchnUnmask within the BlkifRing lock
Thread-Index: AQHcvczPQtA3BJsBtk6irODhNC6JUbXCZuLb
Date: Fri, 27 Mar 2026 14:01:39 +0000
Message-ID:
 <SA6PR03MB77603FABB8FD375640EC9110FE57A@SA6PR03MB7760.namprd03.prod.outlook.com>
References: <20260327093338.493-1-ngoc-tu.dinh@vates.tech>
In-Reply-To: <20260327093338.493-1-ngoc-tu.dinh@vates.tech>
Accept-Language: en-GB, en-US
Content-Language: en-GB
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
msip_labels:
authentication-results: dkim=none (message not signed)
 header.d=none;dmarc=none action=none header.from=citrix.com;
x-ms-publictraffictype: Email
x-ms-traffictypediagnostic: SA6PR03MB7760:EE_|BY5PR03MB4920:EE_
x-ms-office365-filtering-correlation-id: 988fa2f2-60fe-4821-567f-08de8c095df9
x-ms-exchange-senderadcheck: 1
x-ms-exchange-antispam-relay: 0
x-microsoft-antispam:
 BCL:0;ARA:13230040|376014|366016|1800799024|22082099003|56012099003|18002099003|38070700021;
x-microsoft-antispam-message-info:
 OXAX2AIg4ut7GXY+aRWQWqItdaWEiIX3oXWQJjQsJ8VflGghhgQdLTC/tf45uLf7VLb/NDvyWsVBXElEMFvCxzBfcNb+pdO2NUgDvhj6NJH2UXXe+SFclQw2JLA7KJ6wr+lYyQPkNXsWyPmoEmyhLnSWGdo2EeLCqvcwaePknzHz5e6WtN4tgYTt2Bz7Y3f0KuNyCI18xTzhgPUXnCZOxGTQiU+6GeVjOt0BFsDoWc4EYMrM73UCdtCwusrVtbo/uGuuZEtUJrDKHYvQXCkGSzybeRJpfHq8E/OuISQdatOXiLcEPLY21fj/WqOiiLKk/26rNhewuu/W873/ZJItJBAYP/RsEIVsc2N8THgZZIcioTcy5JaAjsOKODtCDhekQqP3zC9KN6HnBKKTtsWtkQdTB2h+syGPAHjg54r9DrG95UTBfrETpEd9GoIg9sd3tvBFxS13CfODJynmbQaTf1nk7OoUFIT46BRHG9r3czJCOkFvQuoDDrXIWtBxnQHdNA1QzcxUe4yIBWXvzZcu35uu+jee2BDBC67dLZonIYlcWykBWnIvjpV1vFE1LJ33OpOKC6/d4iw6nr5AAjpTkLJltlxBteWVa16IVkxEAC6lcwQSYNlaPDFZZ/+wEOY691grU1CDuNW9z3nKWyu5CIY7kk322KDortYi4evu5GIboSSMMGCaLJPr2CZ63jBjKh3w3fJvUa32enFzapi+sOPLmzDdFKhiOyZgyAW7wjg=
x-forefront-antispam-report:
 CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SA6PR03MB7760.namprd03.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024)(22082099003)(56012099003)(18002099003)(38070700021);DIR:OUT;SFP:1101;
x-ms-exchange-antispam-messagedata-chunkcount: 1
x-ms-exchange-antispam-messagedata-0:
 =?us-ascii?Q?qPxMsw8QZDiE4n0E2c4p8/vCyNeHkyujN4oGqKzWy+SGa2JHnLLcJI7BvriW?=
 =?us-ascii?Q?kgCZPLoWthY7E0t/ramdHUP+mWWIQbDqgHRQhPEHQlK3QMN7hJ0suO9QY4mo?=
 =?us-ascii?Q?RyCJ7kap7Id4qAtuY3CRra0qgc0BxBQtlEeZhDXzgMMu0YFdOpDUilB6GYCX?=
 =?us-ascii?Q?59M5xpNSNB8Wdoa0ipxsNGi0Im5FJc1K+Yrxme8/jL7lq5DUanhuWleZaQRW?=
 =?us-ascii?Q?FkxTtiE/JnGxSjTAZldjmmeFuqHANjea2O1VioM/9VPVcQ1cY77aVZNAVLFY?=
 =?us-ascii?Q?KnbmTc4vhbSpxjsdrF0kCwPxyJNrDmunmZl04rIIfesP4u8xuSf0SYhCI8kB?=
 =?us-ascii?Q?2LLfhpLQzacjXlDDhTbbb3xiCbWZjAdGbrZngaYuVompa5sNOBR1aWA+Owmf?=
 =?us-ascii?Q?9tj0+8wEznd3gTqkikC8HHrBkQB3SvGdqDJeLIJ5yyM9cSzPN9aAZ5LnWns7?=
 =?us-ascii?Q?d0KWIi1BM/ATfXVxPwtCMOWO2t4F1RQk1tUR+yX+f5ILe1h8nEHAD0LiECPa?=
 =?us-ascii?Q?BF6H7FwHQTrGIeaMiHpYtixiHGf/hVlju1sQfATolw6WmMx6XBT9t3E6oV35?=
 =?us-ascii?Q?/gzwoznffIJgEYo4ixnowJlGonrSX1YQFDro89S8YGQb6MlP1zVvYfO+V0fa?=
 =?us-ascii?Q?GlN/MvC1X96uXHGhzG6Vvfq+MbPQBJSRXJ8EFxJjKMQfN4tCrj9ezhBg6tfJ?=
 =?us-ascii?Q?HuKK+mJoI8AizDvLdzAmFEiRiU/J8IYK4mwkaFh0gql8DI9BOgZD7No7UuX6?=
 =?us-ascii?Q?HKqCWV39XxiiKpPNhHUiOJLjqzzfvzxlcohZF9jRttRMLOt/EnbcHfATYn5f?=
 =?us-ascii?Q?g6DLwcoQo9tywhPhQS0NOms5ILrENBDNV1GnXaH975xusZ+TqFUvDX37x0Lj?=
 =?us-ascii?Q?3bFoeNrpb84sJqapB/1L9VVAGxXJOyOomssyV0dCXKyuopYBagkRKBDNZ4aq?=
 =?us-ascii?Q?E2FZIRv0QxspXZR8ER+tlGvJCnXjGauqXs3RiY2stnoE21OSoc0sixsOxW7M?=
 =?us-ascii?Q?fov9V6KCnJaEyX2w+J9aeXGpTSq9JwwAtzzPFsc87tLl1gafQRFWcDO1PrJh?=
 =?us-ascii?Q?/s3MhLgwdUt20zLbk2aKurrz6XQOlHrANUqZGZsBuIAwFIx/Pm1zC9kJQISL?=
 =?us-ascii?Q?kRTmOA6MWipwPIsORFEde1vMb+AKws5Npfq7EVm+sGQOPPkl7bgh0I7Lu/dz?=
 =?us-ascii?Q?V0KuAhWCWm37zHyRzrt1HximZCmulfRLM2TpsPr+MTU/O5GqIv7w60/zZoE1?=
 =?us-ascii?Q?QTNtZ48gib70DogyY0KeTyrYikRpl9rg6pKYshodXDSXvi608sw2+J5YOtmE?=
 =?us-ascii?Q?HRVwVbcp9JVTJ9/owlWjQRl+DjLqTXpe49avsyYmdm7pVAWaIzgaxXVRq8xr?=
 =?us-ascii?Q?MpezX8hnWTUKoF9Wa/4D1+WALbyz0lbAiW6xPsk3YrIrSYIgyabOM3OEcBr9?=
 =?us-ascii?Q?GKOmIiGQWp760WG0DwtDFr3jX/R0/CnpHUwwZs01CwunnJOH3djW6iUkl6gE?=
 =?us-ascii?Q?UgJ04ZGKDi7RDnFHPfFUKc+jxNtlYUybZ8AM8d1mtJZ8tn0LmT6mE704ctOV?=
 =?us-ascii?Q?wXBSOm86FthBtGB7MDpcWbfo5RRPDA8l8fZxp5/Jl1inTsKtJBcgtNidkggl?=
 =?us-ascii?Q?nbKxzRcBfL54X89RLooa4Z7Z5qvFMs1kadVTRMsUl2GJGSCTpQFViZefGh04?=
 =?us-ascii?Q?O7IagYk9GLuoSfo97oTHIeg9wS9XkcQYLijLHnsA7MAsAX9G?=
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
X-OriginatorOrg: citrix.com
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-AuthSource: SA6PR03MB7760.namprd03.prod.outlook.com
X-MS-Exchange-CrossTenant-Network-Message-Id: 988fa2f2-60fe-4821-567f-08de8c095df9
X-MS-Exchange-CrossTenant-originalarrivaltime: 27 Mar 2026 14:01:39.2327
 (UTC)
X-MS-Exchange-CrossTenant-fromentityheader: Hosted
X-MS-Exchange-CrossTenant-id: 335836de-42ef-43a2-b145-348c2ee9ca5b
X-MS-Exchange-CrossTenant-mailboxtype: HOSTED
X-MS-Exchange-CrossTenant-userprincipalname: EMPpFius8vFv/4DwOvDeHds8WLRCji8wRpA1DriGqU4T+oiEkH0fYTPeMskv4wRiEA/PufKznk/IP+xJ1HIpRQ==
X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY5PR03MB4920
X-purgate-ID: tlsNG-c201ff/1774620104-81550488-F9305C00/0/0
X-purgate-type: clean
X-purgate-size: 7109


BlkifRingPoll already checks that BlkifRing->Enabled is TRUE, but in this
case the return value would be FALSE, which would need another check
to protect against Unmask being called on a Channel that has been closed.

Owen

________________________________________
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
Sent: 27 March 2026 9:33 AM
To: win-pv-devel@lists.xenproject.org
Cc: Tu Dinh; Owen Smith
Subject: [RFC PATCH] Call EvtchnUnmask within the BlkifRing lock

The call to EvtchnUnmask accesses Channel outside of the blkif ring
lock. Therefore, it can access a stale channel if the DPC is still
running after the channel has been closed in BlkifRingDisconnect. Since
BlkifRingDisconnect runs at DISPATCH_LEVEL, we cannot use
KeFlushQueuedDpcs and have to guard against the event channel's closure
via the Enabled flag instead.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
---

Notes:
    This issue is reliably reproducible by repeatedly suspending/resuming o=
r
    migrating a VM, which at some point will cause it to lock up when tryin=
g
    to acquire a lock on the event channel. The failure will typically
    happen within 100 resume cycles. Note the corrupted event channel below=
:

        nt!KeBugCheckEx:
        fffff803`e3f3ad20 48894c2408      mov     qword ptr [rsp+8],rcx ss:=
0018:fffff803`79b9eb50=3D0000000000000080
        0: kd> kP
         # Child-SP          RetAddr               Call Site
        00 fffff803`79b9eb48 fffff803`e3f832e2     nt!KeBugCheckEx
        01 fffff803`79b9eb50 fffff803`e3f7d8d9     nt!HalpNMIHalt+0x2e
        02 fffff803`79b9eb90 fffff803`750a129b     nt!HalBugCheckSystem+0x6=
9
        03 fffff803`79b9ebd0 fffff803`e411f632     PSHED!PshedBugCheckSyste=
m+0xb
        04 fffff803`79b9ec00 fffff803`e3f830bb     nt!WheaReportHwError+0x2=
b5752
        05 fffff803`79b9ecc0 fffff803`e3ff6daf     nt!HalHandleNMI+0x14b
        06 fffff803`79b9ecf0 fffff803`e40eeac2     nt!KiProcessNMI+0xff
        07 fffff803`79b9ed30 fffff803`e40ee82e     nt!KxNmiInterrupt+0x82
        08 fffff803`79b9ee70 fffff803`e3c94e6c     nt!KiNmiInterrupt+0x26e
        09 ffff9600`a38a7640 fffff803`e3c94d5e     nt!KxWaitForSpinLockAndA=
cquire+0x1c
        0a ffff9600`a38a7670 fffff803`e4064a62     nt!KeAcquireSpinLockRais=
eToDpc+0x5e
        0b ffff9600`a38a76a0 fffff803`e45df368     nt!DifKeAcquireSpinLockR=
aiseToDpcWrapper+0xd2
        0c ffff9600`a38a76f0 fffff803`761f59ea     nt!VerifierKeAcquireSpin=
LockRaiseToDpc+0x28
        0d ffff9600`a38a7720 fffff803`78a1dcd0     xenbus!EvtchnUnmask(
                    struct _INTERFACE * Interface =3D <Value unavailable er=
ror>,
                    struct _XENBUS_EVTCHN_CHANNEL * Channel =3D 0xffffbe01`=
a45fcf80,
                    unsigned char InUpcall =3D 0x00 '',
                    unsigned char Force =3D 0x01 '')+0x3a [xenbus\src\xenbu=
s\evtchn.c @ 824]
        0e ffff9600`a38a7760 fffff803`e3c95b42     xenvbd!BlkifRingDpc(
                    struct _KDPC * Dpc =3D 0xfffff803`74b29a00,
                    void * Context =3D 0xffffbe01`a4116e50,
                    void * Argument1 =3D 0x00000000`00000000,
                    void * Argument2 =3D 0x00000000`00000000)+0x3c0 [xenvbd=
\src\xenvbd\ring.c @ 1627]
        0f ffff9600`a38a77d0 fffff803`e4006592     nt!KiExecuteAllDpcs+0x69=
2
        10 ffff9600`a38a7a10 fffff803`e3ec7dca     nt!KiExecuteDpc+0xc2
        11 ffff9600`a38a7bf0 fffff803`e40e3c74     nt!PspSystemThreadStartu=
p+0x5a
        12 ffff9600`a38a7c40 00000000`00000000     nt!KiStartSystemThread+0=
x34
        0: kd> dx -id 0,0,ffffbe019f6f5040 -r1 ((xenbus!_XENBUS_EVTCHN_CHAN=
NEL *)0xffffbe01a45fcf80)
        ((xenbus!_XENBUS_EVTCHN_CHANNEL *)0xffffbe01a45fcf80)              =
   : 0xffffbe01a45fcf80 [Type: _XENBUS_EVTCHN_CHANNEL *]
            [+0x000] Magic            : 0x28 [Type: unsigned long]
            [+0x008] Lock             : 0xffffffff [Type: unsigned __int64]
            [+0x010] ListEntry        [Type: _LIST_ENTRY]
            [+0x020] PendingListEntry [Type: _LIST_ENTRY]
            [+0x030] Pending          : -1542361520 [Type: long]
            [+0x038] Caller           : 0xffffbe01a4cb9010 [Type: void *]
            [+0x040] Callback         : 0xffffbe01a4cb9010 : 0xffffbe01a4cb=
9010 [Type: unsigned char (__cdecl*)(_KINTERRUPT *,void *)]
            [+0x048] Argument         : 0xffffbe01a4cb9010 [Type: void *]
            [+0x050] Active           : 0x65 [Type: unsigned char]
            [+0x054] Count            : 0x0 [Type: unsigned long]
            [+0x058] Type             : -1527206080 [Type: _XENBUS_EVTCHN_T=
YPE]
            [+0x05c] Parameters       [Type: _XENBUS_EVTCHN_PARAMETERS]
            [+0x064] Mask             : 0x1 [Type: unsigned char]
            [+0x068] LocalPort        : 0x1 [Type: unsigned long]
            [+0x06c] Cpu              : 0x0 [Type: unsigned long]
            [+0x070] Closed           : 0x2f [Type: unsigned char]

    Xencons may benefit from the same change.

    This patch will probably hurt performance in some way, but calling
    EvtchnUnmask within the lock is needed to ensure that the channel is
    alive.

    Xencons tries to fix this problem by skipping the unmask call when the
    ring is not enabled, but Enabled could have gone stale by the time it
    has reached the unmask, and so KeFlushQueuedDpcs is still needed to
    chase out any running DPCs before closing the channel.

    It might be possible to fix this by signaling the end of each DPC with
    an atomic, then synchronize with that in RingDisconnect, but I haven't
    investigated whether that'd help performance.

 src/xenvbd/ring.c | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/src/xenvbd/ring.c b/src/xenvbd/ring.c
index 50f8d58..409d6ab 100644
--- a/src/xenvbd/ring.c
+++ b/src/xenvbd/ring.c
@@ -1611,19 +1611,27 @@ BlkifRingDpc(

         KeRaiseIrql(DISPATCH_LEVEL, &Irql);
         __BlkifRingAcquireLock(BlkifRing);
-        Retry =3D BlkifRingPoll(BlkifRing);
+
+        if (BlkifRing->Enabled) {
+            Retry =3D BlkifRingPoll(BlkifRing);
+
+            if (!Retry) {
+                (VOID) XENBUS_EVTCHN(Unmask,
+                                     &Ring->EvtchnInterface,
+                                     BlkifRing->Channel,
+                                     FALSE,
+                                     TRUE);
+            }
+        } else {
+            Retry =3D FALSE;
+        }
+
         __BlkifRingReleaseLock(BlkifRing);
         KeLowerIrql(Irql);

         if (!Retry)
             break;
     }
-
-    XENBUS_EVTCHN(Unmask,
-                  &Ring->EvtchnInterface,
-                  BlkifRing->Channel,
-                  FALSE,
-                  TRUE);
 }

 #define TIME_US(_us)        ((_us) * 10)
--
2.53.0.windows.2



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Fri Mar 27 15:07:51 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Fri, 27 Mar 2026 15:07:51 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1265843.1556586 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1w68mr-0001VG-RA; Fri, 27 Mar 2026 15:07:49 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1265843.1556586; Fri, 27 Mar 2026 15:07:49 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1w68mr-0001V9-Nr; Fri, 27 Mar 2026 15:07:49 +0000
Received: by outflank-mailman (input) for mailman id 1265843;
 Fri, 27 Mar 2026 15:07:48 +0000
Received: from mx.expurgate.net ([195.190.135.10])
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <bounce-md_30504962.69c69d41.v1-8f99d43670b6438490354ee721da006d@bounce.vates.tech>)
 id 1w68mq-0001Uk-10
 for win-pv-devel@lists.xenproject.org; Fri, 27 Mar 2026 15:07:48 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1w68mp-006XRW-2L
 for win-pv-devel@lists.xenproject.org; Fri, 27 Mar 2026 16:07:47 +0100
Received: from [10.42.69.11] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from
 <bounce-md_30504962.69c69d41.v1-8f99d43670b6438490354ee721da006d@bounce.vates.tech>)
 id 69c69d40-5cb7-0a2a0a5109dd-0a2a450bba3c-12
 for <win-pv-devel@lists.xenproject.org>; Fri, 27 Mar 2026 16:07:47 +0100
Received: from [198.2.132.14] (helo=mail132-14.atl131.mandrillapp.com)
 by tlsNG-42698a.mxtls.expurgate.net with ESMTPS (eXpurgate 4.55.2)
 (envelope-from
 <bounce-md_30504962.69c69d41.v1-8f99d43670b6438490354ee721da006d@bounce.vates.tech>)
 id 69c69d41-ef63-0a2a450b0019-c602840e729d-3
 for <win-pv-devel@lists.xenproject.org>; Fri, 27 Mar 2026 16:07:46 +0100
Received: from pmta09.mandrill.prod.atl01.rsglab.com (localhost [127.0.0.1])
 by mail132-14.atl131.mandrillapp.com (Mailchimp) with ESMTP id
 4fj3ss3Stgz8XRqs7
 for <win-pv-devel@lists.xenproject.org>; Fri, 27 Mar 2026 15:07:45 +0000 (GMT)
Received: from [37.26.189.201] by mandrillapp.com id
 8f99d43670b6438490354ee721da006d; Fri, 27 Mar 2026 15:07:45 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=mte1 header.d=mandrillapp.com header.i="@mandrillapp.com" header.h="From:Subject:Message-Id:To:References:In-Reply-To:Feedback-ID:Date:MIME-Version:Content-Type:Content-Transfer-Encoding"; dkim=pass header.s=mte1 header.d=vates.tech header.i="ngoc-tu.dinh@vates.tech" header.h="From:Subject:Message-Id:To:References:In-Reply-To:Feedback-ID:Date:MIME-Version:Content-Type:Content-Transfer-Encoding"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com;
	s=mte1; t=1774624065; x=1774894065;
	bh=B5/vlOp4omGCCz2VxOaMdBmWlpiSh0KetjS9TYTagdU=;
	h=From:Subject:Message-Id:To:References:In-Reply-To:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=jRo6ZDXXYx1kaBkUS0fFsaEXel0Jh4s9X1f15JIsF0uow46le7/WENNQLRDJbVa2d
	 Ohxizs9nNJgp+rrp+OfKsV9aoz7I3QuHu5hicsWFR7fi71BKIrHyoQnfwq7fFHnDVB
	 5NP4c/wVJY28aZrRht5ifL2D9RjAY64Oguy3z7uarju4m+nfGw0jqPrEFverTDKKES
	 rMq1bf98i672C0cRllOHy0DC6nSYwsucnz8nHDvYHZ7Yb2v9uRttRVsZNxoDBooXPv
	 5F870B/WlG8gIqpb/xYp+dnmvHAIZGoCyVdD047B5Bl/rXmUcLf0dVMsoaEnYuaK5D
	 9i++VUqoUTBeg==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1;
	t=1774624065; x=1774884565; i=ngoc-tu.dinh@vates.tech;
	bh=B5/vlOp4omGCCz2VxOaMdBmWlpiSh0KetjS9TYTagdU=;
	h=From:Subject:Message-Id:To:References:In-Reply-To:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=zX5kTGogWk0HkCN2ShybCXlhZ0J2DPWq/tUN4lJPV6XX/ro7AF7p3pMxdD0bUZBK9
	 bjZzDlC5yKs2Tobcj3pks5FpVvDlfhSajNFcq+wC8j0INQVm2Pb0AhyvtSm+o8bqDD
	 barZwuEMH05NKwcAGK3z9xncjFD5eazg7EIPZbGH/MyQ2gVBp4ZQTvzmvZePWk6dGI
	 EfUeIj0SXCKm6PjtGcS0wMPjmL28FKeOjuvxFnnqUJBAWYZU+n/MVVeNNDfpSj4hZw
	 5bbgXNHTJoDrFgGQUT9yDHgVt3gakC5UYQRK31i4qvX3oOLtrgrLzX6B0Kj0VXvOGZ
	 lk5O62VBz1S3w==
From: "Tu Dinh" <ngoc-tu.dinh@vates.tech>
Subject: =?utf-8?Q?Re:=20[RFC=20PATCH]=20Call=20EvtchnUnmask=20within=20the=20BlkifRing=20lock?=
X-Bm-Disclaimer: Yes
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1774624064640
Message-Id: <15f1992f-b96f-4859-897d-f431437b7107@vates.tech>
To: "Owen Smith" <owen.smith@citrix.com>, win-pv-devel@lists.xenproject.org
References: <20260327093338.493-1-ngoc-tu.dinh@vates.tech> <SA6PR03MB77603FABB8FD375640EC9110FE57A@SA6PR03MB7760.namprd03.prod.outlook.com>
In-Reply-To: <SA6PR03MB77603FABB8FD375640EC9110FE57A@SA6PR03MB7760.namprd03.prod.outlook.com>
X-Native-Encoded: 1
X-Report-Abuse: =?UTF-8?Q?Please=20forward=20a=20copy=20of=20this=20message,=20including=20all=20headers,=20to=20abuse@mandrill.com.=20You=20can=20also=20report=20abuse=20here:=20https://mandrillapp.com/contact/abuse=3Fid=3D30504962.8f99d43670b6438490354ee721da006d?=
X-Mandrill-User: md_30504962
Feedback-ID: 30504962:30504962.20260327:md
Date: Fri, 27 Mar 2026 15:07:45 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit
X-purgate-ID: tlsNG-42698a/1774624066-A183F112-D572EDAF/0/0
X-purgate-type: clean
X-purgate-size: 9324

On 27/03/2026 15:01, Owen Smith wrote:
> 
> BlkifRingPoll already checks that BlkifRing->Enabled is TRUE, but in this
> case the return value would be FALSE, which would need another check
> to protect against Unmask being called on a Channel that has been closed.
> 
> Owen

Do you mean something like this?

diff --git a/src/xenvbd/ring.c b/src/xenvbd/ring.c
index 50f8d58..ddf12fc 100644
--- a/src/xenvbd/ring.c
+++ b/src/xenvbd/ring.c
@@ -1211,7 +1211,8 @@ __BlkifRingCompleteResponse(

  static FORCEINLINE BOOLEAN
  BlkifRingPoll(
-    IN  PXENVBD_BLKIF_RING  BlkifRing
+    IN  PXENVBD_BLKIF_RING  BlkifRing,
+    IN  PBOOLEAN            Enabled
      )
  {
  #define XENVBD_BATCH(_Ring) (RING_SIZE(&(_Ring)->Front) / 4)
@@ -1222,8 +1223,12 @@ BlkifRingPoll(
      Ring = BlkifRing->Ring;
      Retry = FALSE;

-    if (!BlkifRing->Enabled)
+    if (BlkifRing->Enabled) {
+        *Enabled = TRUE;
+    } else {
+        *Enabled = FALSE;
          goto done;
+    }

      for (;;) {
          RING_IDX            rsp_prod;
@@ -1607,23 +1612,26 @@ BlkifRingDpc(

      for (;;) {
          BOOLEAN         Retry;
+        BOOLEAN         Enabled;
          KIRQL           Irql;

          KeRaiseIrql(DISPATCH_LEVEL, &Irql);
          __BlkifRingAcquireLock(BlkifRing);
-        Retry = BlkifRingPoll(BlkifRing);
+        Retry = BlkifRingPoll(BlkifRing, &Enabled);
+
+        if (Enabled)
+            (VOID) XENBUS_EVTCHN(Unmask,
+                                 &Ring->EvtchnInterface,
+                                 BlkifRing->Channel,
+                                 FALSE,
+                                 TRUE);
+
          __BlkifRingReleaseLock(BlkifRing);
          KeLowerIrql(Irql);

          if (!Retry)
              break;
      }
-
-    XENBUS_EVTCHN(Unmask,
-                  &Ring->EvtchnInterface,
-                  BlkifRing->Channel,
-                  FALSE,
-                  TRUE);
  }

  #define TIME_US(_us)        ((_us) * 10)
--

> 
> ________________________________________
> From: Tu Dinh <ngoc-tu.dinh@vates.tech>
> Sent: 27 March 2026 9:33 AM
> To: win-pv-devel@lists.xenproject.org
> Cc: Tu Dinh; Owen Smith
> Subject: [RFC PATCH] Call EvtchnUnmask within the BlkifRing lock
> 
> The call to EvtchnUnmask accesses Channel outside of the blkif ring
> lock. Therefore, it can access a stale channel if the DPC is still
> running after the channel has been closed in BlkifRingDisconnect. Since
> BlkifRingDisconnect runs at DISPATCH_LEVEL, we cannot use
> KeFlushQueuedDpcs and have to guard against the event channel's closure
> via the Enabled flag instead.
> 
> Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
> ---
> 
> Notes:
>      This issue is reliably reproducible by repeatedly suspending/resuming or
>      migrating a VM, which at some point will cause it to lock up when trying
>      to acquire a lock on the event channel. The failure will typically
>      happen within 100 resume cycles. Note the corrupted event channel below:
> 
>          nt!KeBugCheckEx:
>          fffff803`e3f3ad20 48894c2408      mov     qword ptr [rsp+8],rcx ss:0018:fffff803`79b9eb50=0000000000000080
>          0: kd> kP
>           # Child-SP          RetAddr               Call Site
>          00 fffff803`79b9eb48 fffff803`e3f832e2     nt!KeBugCheckEx
>          01 fffff803`79b9eb50 fffff803`e3f7d8d9     nt!HalpNMIHalt+0x2e
>          02 fffff803`79b9eb90 fffff803`750a129b     nt!HalBugCheckSystem+0x69
>          03 fffff803`79b9ebd0 fffff803`e411f632     PSHED!PshedBugCheckSystem+0xb
>          04 fffff803`79b9ec00 fffff803`e3f830bb     nt!WheaReportHwError+0x2b5752
>          05 fffff803`79b9ecc0 fffff803`e3ff6daf     nt!HalHandleNMI+0x14b
>          06 fffff803`79b9ecf0 fffff803`e40eeac2     nt!KiProcessNMI+0xff
>          07 fffff803`79b9ed30 fffff803`e40ee82e     nt!KxNmiInterrupt+0x82
>          08 fffff803`79b9ee70 fffff803`e3c94e6c     nt!KiNmiInterrupt+0x26e
>          09 ffff9600`a38a7640 fffff803`e3c94d5e     nt!KxWaitForSpinLockAndAcquire+0x1c
>          0a ffff9600`a38a7670 fffff803`e4064a62     nt!KeAcquireSpinLockRaiseToDpc+0x5e
>          0b ffff9600`a38a76a0 fffff803`e45df368     nt!DifKeAcquireSpinLockRaiseToDpcWrapper+0xd2
>          0c ffff9600`a38a76f0 fffff803`761f59ea     nt!VerifierKeAcquireSpinLockRaiseToDpc+0x28
>          0d ffff9600`a38a7720 fffff803`78a1dcd0     xenbus!EvtchnUnmask(
>                      struct _INTERFACE * Interface = <Value unavailable error>,
>                      struct _XENBUS_EVTCHN_CHANNEL * Channel = 0xffffbe01`a45fcf80,
>                      unsigned char InUpcall = 0x00 '',
>                      unsigned char Force = 0x01 '')+0x3a [xenbus\src\xenbus\evtchn.c @ 824]
>          0e ffff9600`a38a7760 fffff803`e3c95b42     xenvbd!BlkifRingDpc(
>                      struct _KDPC * Dpc = 0xfffff803`74b29a00,
>                      void * Context = 0xffffbe01`a4116e50,
>                      void * Argument1 = 0x00000000`00000000,
>                      void * Argument2 = 0x00000000`00000000)+0x3c0 [xenvbd\src\xenvbd\ring.c @ 1627]
>          0f ffff9600`a38a77d0 fffff803`e4006592     nt!KiExecuteAllDpcs+0x692
>          10 ffff9600`a38a7a10 fffff803`e3ec7dca     nt!KiExecuteDpc+0xc2
>          11 ffff9600`a38a7bf0 fffff803`e40e3c74     nt!PspSystemThreadStartup+0x5a
>          12 ffff9600`a38a7c40 00000000`00000000     nt!KiStartSystemThread+0x34
>          0: kd> dx -id 0,0,ffffbe019f6f5040 -r1 ((xenbus!_XENBUS_EVTCHN_CHANNEL *)0xffffbe01a45fcf80)
>          ((xenbus!_XENBUS_EVTCHN_CHANNEL *)0xffffbe01a45fcf80)                 : 0xffffbe01a45fcf80 [Type: _XENBUS_EVTCHN_CHANNEL *]
>              [+0x000] Magic            : 0x28 [Type: unsigned long]
>              [+0x008] Lock             : 0xffffffff [Type: unsigned __int64]
>              [+0x010] ListEntry        [Type: _LIST_ENTRY]
>              [+0x020] PendingListEntry [Type: _LIST_ENTRY]
>              [+0x030] Pending          : -1542361520 [Type: long]
>              [+0x038] Caller           : 0xffffbe01a4cb9010 [Type: void *]
>              [+0x040] Callback         : 0xffffbe01a4cb9010 : 0xffffbe01a4cb9010 [Type: unsigned char (__cdecl*)(_KINTERRUPT *,void *)]
>              [+0x048] Argument         : 0xffffbe01a4cb9010 [Type: void *]
>              [+0x050] Active           : 0x65 [Type: unsigned char]
>              [+0x054] Count            : 0x0 [Type: unsigned long]
>              [+0x058] Type             : -1527206080 [Type: _XENBUS_EVTCHN_TYPE]
>              [+0x05c] Parameters       [Type: _XENBUS_EVTCHN_PARAMETERS]
>              [+0x064] Mask             : 0x1 [Type: unsigned char]
>              [+0x068] LocalPort        : 0x1 [Type: unsigned long]
>              [+0x06c] Cpu              : 0x0 [Type: unsigned long]
>              [+0x070] Closed           : 0x2f [Type: unsigned char]
> 
>      Xencons may benefit from the same change.
> 
>      This patch will probably hurt performance in some way, but calling
>      EvtchnUnmask within the lock is needed to ensure that the channel is
>      alive.
> 
>      Xencons tries to fix this problem by skipping the unmask call when the
>      ring is not enabled, but Enabled could have gone stale by the time it
>      has reached the unmask, and so KeFlushQueuedDpcs is still needed to
>      chase out any running DPCs before closing the channel.
> 
>      It might be possible to fix this by signaling the end of each DPC with
>      an atomic, then synchronize with that in RingDisconnect, but I haven't
>      investigated whether that'd help performance.
> 
>   src/xenvbd/ring.c | 22 +++++++++++++++-------
>   1 file changed, 15 insertions(+), 7 deletions(-)
> 
> diff --git a/src/xenvbd/ring.c b/src/xenvbd/ring.c
> index 50f8d58..409d6ab 100644
> --- a/src/xenvbd/ring.c
> +++ b/src/xenvbd/ring.c
> @@ -1611,19 +1611,27 @@ BlkifRingDpc(
> 
>           KeRaiseIrql(DISPATCH_LEVEL, &Irql);
>           __BlkifRingAcquireLock(BlkifRing);
> -        Retry = BlkifRingPoll(BlkifRing);
> +
> +        if (BlkifRing->Enabled) {
> +            Retry = BlkifRingPoll(BlkifRing);
> +
> +            if (!Retry) {
> +                (VOID) XENBUS_EVTCHN(Unmask,
> +                                     &Ring->EvtchnInterface,
> +                                     BlkifRing->Channel,
> +                                     FALSE,
> +                                     TRUE);
> +            }
> +        } else {
> +            Retry = FALSE;
> +        }
> +
>           __BlkifRingReleaseLock(BlkifRing);
>           KeLowerIrql(Irql);
> 
>           if (!Retry)
>               break;
>       }
> -
> -    XENBUS_EVTCHN(Unmask,
> -                  &Ring->EvtchnInterface,
> -                  BlkifRing->Channel,
> -                  FALSE,
> -                  TRUE);
>   }
> 
>   #define TIME_US(_us)        ((_us) * 10)
> --
> 2.53.0.windows.2
> 
> 
> 
> --
> Ngoc Tu Dinh | Vates XCP-ng Developer
> 
> XCP-ng & Xen Orchestra - Vates solutions
> 
> web: https://vates.tech
> 



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Fri Mar 27 15:14:17 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Fri, 27 Mar 2026 15:14:17 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1265857.1556599 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1w68t6-00035N-Hi; Fri, 27 Mar 2026 15:14:16 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1265857.1556599; Fri, 27 Mar 2026 15:14:16 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1w68t6-00035F-Ek; Fri, 27 Mar 2026 15:14:16 +0000
Received: by outflank-mailman (input) for mailman id 1265857;
 Fri, 27 Mar 2026 15:14:15 +0000
Received: from mx.expurgate.net ([195.190.135.10])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <owen.smith@citrix.com>) id 1w68t5-000359-Hm
 for win-pv-devel@lists.xenproject.org; Fri, 27 Mar 2026 15:14:15 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1w68t4-007APV-OS
 for win-pv-devel@lists.xenproject.org; Fri, 27 Mar 2026 16:14:14 +0100
Received: from [10.42.69.1] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1)
 (envelope-from <owen.smith@citrix.com>)
 id 69c69eaf-2eae-0a2a0a5409dd-0a2a4501e53e-20
 for <win-pv-devel@lists.xenproject.org>; Fri, 27 Mar 2026 16:14:14 +0100
Received: from [52.101.62.68]
 (helo=DM5PR21CU001.outbound.protection.outlook.com)
 by tlsNG-d62444.mxtls.expurgate.net with ESMTPS (eXpurgate 4.55.2)
 (envelope-from <owen.smith@citrix.com>)
 id 69c69ec3-6400-0a2a45010019-34653e442ea0-3
 for <win-pv-devel@lists.xenproject.org>; Fri, 27 Mar 2026 16:14:14 +0100
Received: from SA6PR03MB7760.namprd03.prod.outlook.com (2603:10b6:806:43c::5)
 by SN7PR03MB7058.namprd03.prod.outlook.com (2603:10b6:806:353::9)
 with Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9745.20; Fri, 27 Mar
 2026 15:14:09 +0000
Received: from SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38]) by SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38%7]) with mapi id 15.20.9745.023; Fri, 27 Mar 2026
 15:14:09 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=citrix.com header.i="@citrix.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:x-ms-exchange-senderadcheck"
ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;
 b=G2IWS85IsHoJyFp9HbXfrlm5OLG3bJdkHZHqMRlhspugr7zhiE+MX+N9X2XpWpBwaab3uxwIUNFy2kO3kXb2MWC6WgNj0Qfao8Lpd9f18FylPgMZlsv6pAwq5nFL7kmtGnYdODFdqT0Q2eweQCXIokrytNGrqr+weib7U7VMAoNagDzl0wWF3UrZ3AamKYCmol3dRZEfx7XhxTKCM+2USKbxE6DnLwE7urg2zd/XVe1hWCfc8gMXzi6BgxPs6Nvm61x3eic+vU5IOZ+voLXeKItU5ci+MQWRtxUY2Hec5GD4PTC8J4cULdb4RQMle96eDZYCMxhRTfOi9MRA2Fcy2w==
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=g2CIpf/Una1RSZ92wb7ixn2KG52ID5snIIxvAGnv5cQ=;
 b=nciRynu0pyDo8X0aoD5+qaYF1LHkY9Pxz0ChJoayF+Nsa10QTUhyTlgNUwzIJyNYajEZWrLcwgwIawbPgafPmhka7pU+DiP5JhegjmcFmMo/izb75dQwzKSIXVd3+GeKRyNHvsL8w+xZ6+d1/fspX6TU4zhhrfYFvuTONZnmBN+uDBCD0BohhBRA+8zg+76qNdvg+WoDOXLwsQ097Dmls56jHozqtNqLV2huLuykNm/TIia859pubyk5OYDagimomhWjxSrwr9tslYJsMcvK+Z+QrrPWUDZ5x9ALZEdwIYhInPgOJzyGeTIvPrS2xhTt+73QVHdpcb3wnOZpIWpetg==
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
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com;
 s=selector1;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=g2CIpf/Una1RSZ92wb7ixn2KG52ID5snIIxvAGnv5cQ=;
 b=ule2rECoLKGjfJgHR6r7bi6S7Cntc95eZKVHvVsLe2cMl14PkGaumBeXBEpahwPO3GW//EtrsOzWahm8WRh6aFoKaZPChfnlAFQLEjYBgwTLnEDGOQK6NXq9/6KfYJd5HqafwRHU9Nni7SEWNhQbd0wI3AtwbpIgEY2lahG+ho8=
From: Owen Smith <owen.smith@citrix.com>
To: Tu Dinh <ngoc-tu.dinh@vates.tech>, "win-pv-devel@lists.xenproject.org"
	<win-pv-devel@lists.xenproject.org>
Subject: Re: [RFC PATCH] Call EvtchnUnmask within the BlkifRing lock
Thread-Topic: [RFC PATCH] Call EvtchnUnmask within the BlkifRing lock
Thread-Index: AQHcvczPQtA3BJsBtk6irODhNC6JUbXCZuLbgAAUcoCAAAFMNg==
Date: Fri, 27 Mar 2026 15:14:09 +0000
Message-ID:
 <SA6PR03MB7760DBA263BC5C1361B89349FE57A@SA6PR03MB7760.namprd03.prod.outlook.com>
References: <20260327093338.493-1-ngoc-tu.dinh@vates.tech>
 <SA6PR03MB77603FABB8FD375640EC9110FE57A@SA6PR03MB7760.namprd03.prod.outlook.com>
 <15f1992f-b96f-4859-897d-f431437b7107@vates.tech>
In-Reply-To: <15f1992f-b96f-4859-897d-f431437b7107@vates.tech>
Accept-Language: en-GB, en-US
Content-Language: en-GB
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
msip_labels:
authentication-results: dkim=none (message not signed)
 header.d=none;dmarc=none action=none header.from=citrix.com;
x-ms-publictraffictype: Email
x-ms-traffictypediagnostic: SA6PR03MB7760:EE_|SN7PR03MB7058:EE_
x-ms-office365-filtering-correlation-id: b8e0753a-0c36-4e66-4c22-08de8c137ee5
x-ms-exchange-senderadcheck: 1
x-ms-exchange-antispam-relay: 0
x-microsoft-antispam:
 BCL:0;ARA:13230040|366016|1800799024|376014|38070700021|13003099007|18002099003|22082099003|56012099003;
x-microsoft-antispam-message-info:
 5g29WZs1bPHdCVjB5uF9YA37dtFJb7wf/LWNVJC6Vw7Z1DsC9Ot0dEhcau+1cbBbECRW2GAfdwNkHBLIPn/gE+mbmHrGE1M/OX/X+nbPVHbP+Xu44FGvEcu0aeVoEvh7FWeVgKyw8bu4neVRDyk0xFioyFa5jm2PAVAYC0lEX4p9wMU/SN/4dCb+R3hOhQxXVJ+WF9W72iLDLBH0h9S6j56Koy8pTfxtttoSF+IZtm2mbsq6kz20E7EsmK96jWDlv6pYYz9EmBnK5GrHYJaX6+CWmvespn44qvbDr1byEJ50xqrGb4oEgEG+pti8AS8qUkH9jIrftgpczJF2RjEGKW2HSy0L7SplfYtD5Ktz794rM91SbCx3QypFih9fE/xyf8MArqPDsrUisFdVQNSmp+Pwxq0N11ECEQVS79mIPf/wV7eaJW2Y4z500/DIFA4M4QWwfFgpPa8ub7oHVbruC307Cw/FrQYpiymv/PI9Sj8w93O5puRW0VmSUI+GXIPY0Oww8/cg0fSuCzqPC69+ljg6UMVoKQ+2wMQsuxvNkJJ0hXW/Gkj9jpKThzJApfnakvMQy28DrW1zY4Mmymy2wjO4GaD/WYmZuoeOlXF8SeULA+HLnKc5e++Q0InH+zo26teo1FQ0k80dY1bJRaXONYpEQCjED1CEvQ2kTT5koR/muaMJXK5lCViGxm9gN90QTjdgZCnb/SOAwzRJf21+mkLqkiHfP4jzt5W1R6rVfZ0=
x-forefront-antispam-report:
 CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SA6PR03MB7760.namprd03.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(366016)(1800799024)(376014)(38070700021)(13003099007)(18002099003)(22082099003)(56012099003);DIR:OUT;SFP:1101;
x-ms-exchange-antispam-messagedata-chunkcount: 1
x-ms-exchange-antispam-messagedata-0:
 =?iso-8859-1?Q?HMzlt5r/2C9akqqIQkYMskIZ61Z1J6JTApkfq9S9JkQF2sYxsm2QyA75j9?=
 =?iso-8859-1?Q?l1tszbVr0j1r72Q277Ti3Ot3RxFdsuLO3i9oivxUuUvhlvVBaEvrBaQckD?=
 =?iso-8859-1?Q?fR2ZXFdLr+Tggm8VcMBp9HCGglL9SDdqo1aSSbe9LkrpkJBMcrJXgpKJoL?=
 =?iso-8859-1?Q?/78O4uohYJrr8ahRx6rpLuIUxBNxLtDcRBkbgkTEKBmRNtUjzXR79BkHld?=
 =?iso-8859-1?Q?ocSnvVUvrndLXLrqbeuQxKz3GUBd7sO1jbP+X4DEfWecIgABvLmiJ+fdmL?=
 =?iso-8859-1?Q?oLahqhZn8LlFi+Pyml0lQg18MBoxyyc7+aeeUir4ikW37Xj3GR3W/vJM9x?=
 =?iso-8859-1?Q?gQT6kDFq5trU2MSUBds/Y6fWaBBrCetp/YMqUR7JlfAA3PTyG+Iq1JI3De?=
 =?iso-8859-1?Q?kZCfcfKqOUDeTkQGj2O//Cp17MQOm/9umyR+pG6SIcA9QEtHaWwUhMU6US?=
 =?iso-8859-1?Q?YRpJhkOgCD+MuVaXi2yQlrgShETl124IkuKHK3V85mw49k8kgZ7d3nMrN9?=
 =?iso-8859-1?Q?D18OSKzjcz6K9aB0ArMJCrJlk08dOtyh7eWYq20rxlGu6TppByQOzxTCX0?=
 =?iso-8859-1?Q?Dh9i+HzzOAGJXXKrhqZHs1Q2iKYjRwxC9jYXaLIXQWdBNX0hVqLhk+e+HA?=
 =?iso-8859-1?Q?3mH9oVRye7FVCQfGfCdfxbX13v8+EnSZ7G5QTRuU7fl0K872bNHBb9jkHF?=
 =?iso-8859-1?Q?iRbvTi0R3REJFlutg3po8LRXIlbaIU8c9y77aW1d5KRnIpTXh/6jrVF4Tl?=
 =?iso-8859-1?Q?sxTBMudM4Glr7rP5BZ74iNt8IdPsrTQnL4/wAgjHNHMiGKz9y1ZTwpndsl?=
 =?iso-8859-1?Q?lqPX0AOEDYJLTnKylOtRtzX1hqxreCH3+Bv5evADaBoKB48TVTkEXGAh31?=
 =?iso-8859-1?Q?xiP0N6eaQMSEMXICvGpp0RYp5epxiW4FaVznmQVatjj2I0a0zRauoZoGER?=
 =?iso-8859-1?Q?r1pmxNdcmYzNO5s3U3CKIuG1bcNP+Je0jc0fvM3BSr63fvpDzgawtk5WNe?=
 =?iso-8859-1?Q?AOzHmWBJhh9d40/zAr1MlZQmnRh2AsQN1SbNL7Cczr9OLc/POrM2UwVwBG?=
 =?iso-8859-1?Q?v9j3uNP2O+lVII1VgpwjXRoYbt9YrmKMkj1Oi2gm3VB60xs2y1qjocCoGD?=
 =?iso-8859-1?Q?nspQnInD+O/HQz5fGQ6T8epcx7BhsigrBy4sILsBXn6t+ktPIJZLzERYj+?=
 =?iso-8859-1?Q?02rOwOB+soC0b6MDGMx+g9jUWiI1VoC/tLvjP8EPEv+RcqL68MDNeM+IJl?=
 =?iso-8859-1?Q?1Ap6xd8YMqNBwyc6Pa5RQ93dQjd5UBgTCfSF5e2k1EUB2fe5wcGF57aXg4?=
 =?iso-8859-1?Q?4lVAtsXdaBFh4zi9VSPSnHs72H7fXYpgR8qqImTWu2xJABgAsywjHgyMr5?=
 =?iso-8859-1?Q?/vUzwYNKaLUzluBX8uWr/BlrICS7xs+9Rd+W6jSB3JiJaL7AiJoIE+tsen?=
 =?iso-8859-1?Q?D+vd3SPmCJJktzxi2hYKUL/0fHkcbdh1s6bjGYDtfP0P0c0+0Yukc/aM48?=
 =?iso-8859-1?Q?TYRt5OGaf0mHcpLuON8oLSKObdLZfsLv13JHcjccICbYsrGPD5cY2dXczK?=
 =?iso-8859-1?Q?gkPmeBzE3IJkPIj6WT6i8PAGGGiNreegash+HjmhmlfINu6wVNnDe0Bf/Q?=
 =?iso-8859-1?Q?V4N8XxXiSEZnebfE58+OvIowSSqARMWgzgDDfabPx7O/olIZrszQJxFRFS?=
 =?iso-8859-1?Q?0wzjsFDDNlRAx/eMyx+UD987Xf2APXGuvHvV11NOzjG4jdJLyGoMv/fYl5?=
 =?iso-8859-1?Q?8lvEhBo3FuvADmJfPTw7nybzaRXaixSUPAg3qxMIneJlH+IzbpkFx8/W51?=
 =?iso-8859-1?Q?wNRTwgj+gg=3D=3D?=
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
X-OriginatorOrg: citrix.com
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-AuthSource: SA6PR03MB7760.namprd03.prod.outlook.com
X-MS-Exchange-CrossTenant-Network-Message-Id: b8e0753a-0c36-4e66-4c22-08de8c137ee5
X-MS-Exchange-CrossTenant-originalarrivaltime: 27 Mar 2026 15:14:09.4042
 (UTC)
X-MS-Exchange-CrossTenant-fromentityheader: Hosted
X-MS-Exchange-CrossTenant-id: 335836de-42ef-43a2-b145-348c2ee9ca5b
X-MS-Exchange-CrossTenant-mailboxtype: HOSTED
X-MS-Exchange-CrossTenant-userprincipalname: nLNwUGfDKIiwnaFGrL4ljrs6StDIIFYtsCYLhrGi3hqp3skQJTmgRC9P966q3SFc67m2L3gfr1jzeTPnd95syg==
X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR03MB7058
X-purgate-ID: tlsNG-d62444/1774624454-226E6DF3-059F2C94/0/0
X-purgate-type: clean
X-purgate-size: 14640

It may not need changes to BlkifRingPoll =0A=
=0A=
Retry =3D BlkifRingPoll(BlkifRing);=0A=
if (BlkifRing->Enabled)=0A=
    (VOID) XENBUS_EVTCHN(Unmask,.....)=0A=
=0A=
=0A=
Owen=0A=
=0A=
________________________________________=0A=
From: Tu Dinh <ngoc-tu.dinh@vates.tech>=0A=
Sent: Friday, March 27, 2026 3:07 PM=0A=
To: Owen Smith <owen.smith@citrix.com>; win-pv-devel@lists.xenproject.org <=
win-pv-devel@lists.xenproject.org>=0A=
Subject: Re: [RFC PATCH] Call EvtchnUnmask within the BlkifRing lock=0A=
=0A=
=0A=
On 27/03/2026 15:01, Owen Smith wrote:=0A=
> =0A=
> BlkifRingPoll already checks that BlkifRing->Enabled is TRUE, but in this=
=0A=
> case the return value would be FALSE, which would need another check=0A=
> to protect against Unmask being called on a Channel that has been closed.=
=0A=
> =0A=
> Owen=0A=
=0A=
Do you mean something like this?=0A=
=0A=
diff --git a/src/xenvbd/ring.c b/src/xenvbd/ring.c=0A=
index 50f8d58..ddf12fc 100644=0A=
--- a/src/xenvbd/ring.c=0A=
+++ b/src/xenvbd/ring.c=0A=
@@ -1211,7 +1211,8 @@ __BlkifRingCompleteResponse(=0A=
=0A=
=A0 static FORCEINLINE BOOLEAN=0A=
=A0 BlkifRingPoll(=0A=
-=A0=A0=A0 IN=A0 PXENVBD_BLKIF_RING=A0 BlkifRing=0A=
+=A0=A0=A0 IN=A0 PXENVBD_BLKIF_RING=A0 BlkifRing,=0A=
+=A0=A0=A0 IN=A0 PBOOLEAN=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 Enabled=0A=
=A0=A0=A0=A0=A0 )=0A=
=A0 {=0A=
=A0 #define XENVBD_BATCH(_Ring) (RING_SIZE(&(_Ring)->Front) / 4)=0A=
@@ -1222,8 +1223,12 @@ BlkifRingPoll(=0A=
=A0=A0=A0=A0=A0 Ring =3D BlkifRing->Ring;=0A=
=A0=A0=A0=A0=A0 Retry =3D FALSE;=0A=
=0A=
-=A0=A0=A0 if (!BlkifRing->Enabled)=0A=
+=A0=A0=A0 if (BlkifRing->Enabled) {=0A=
+=A0=A0=A0=A0=A0=A0=A0 *Enabled =3D TRUE;=0A=
+=A0=A0=A0 } else {=0A=
+=A0=A0=A0=A0=A0=A0=A0 *Enabled =3D FALSE;=0A=
=A0=A0=A0=A0=A0=A0=A0=A0=A0 goto done;=0A=
+=A0=A0=A0 }=0A=
=0A=
=A0=A0=A0=A0=A0 for (;;) {=0A=
=A0=A0=A0=A0=A0=A0=A0=A0=A0 RING_IDX=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 rsp_p=
rod;=0A=
@@ -1607,23 +1612,26 @@ BlkifRingDpc(=0A=
=0A=
=A0=A0=A0=A0=A0 for (;;) {=0A=
=A0=A0=A0=A0=A0=A0=A0=A0=A0 BOOLEAN=A0=A0=A0=A0=A0=A0=A0=A0 Retry;=0A=
+=A0=A0=A0=A0=A0=A0=A0 BOOLEAN=A0=A0=A0=A0=A0=A0=A0=A0 Enabled;=0A=
=A0=A0=A0=A0=A0=A0=A0=A0=A0 KIRQL=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 Irql;=0A=
=0A=
=A0=A0=A0=A0=A0=A0=A0=A0=A0 KeRaiseIrql(DISPATCH_LEVEL, &Irql);=0A=
=A0=A0=A0=A0=A0=A0=A0=A0=A0 __BlkifRingAcquireLock(BlkifRing);=0A=
-=A0=A0=A0=A0=A0=A0=A0 Retry =3D BlkifRingPoll(BlkifRing);=0A=
+=A0=A0=A0=A0=A0=A0=A0 Retry =3D BlkifRingPoll(BlkifRing, &Enabled);=0A=
+=0A=
+=A0=A0=A0=A0=A0=A0=A0 if (Enabled)=0A=
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 (VOID) XENBUS_EVTCHN(Unmask,=0A=
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0=A0 &Ring->EvtchnInterface,=0A=
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0=A0 BlkifRing->Channel,=0A=
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0=A0 FALSE,=0A=
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0=A0 TRUE);=0A=
+=0A=
=A0=A0=A0=A0=A0=A0=A0=A0=A0 __BlkifRingReleaseLock(BlkifRing);=0A=
=A0=A0=A0=A0=A0=A0=A0=A0=A0 KeLowerIrql(Irql);=0A=
=0A=
=A0=A0=A0=A0=A0=A0=A0=A0=A0 if (!Retry)=0A=
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 break;=0A=
=A0=A0=A0=A0=A0 }=0A=
-=0A=
-=A0=A0=A0 XENBUS_EVTCHN(Unmask,=0A=
-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 &Ring->EvtchnInterface=
,=0A=
-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 BlkifRing->Channel,=0A=
-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 FALSE,=0A=
-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 TRUE);=0A=
=A0 }=0A=
=0A=
=A0 #define TIME_US(_us)=A0=A0=A0=A0=A0=A0=A0 ((_us) * 10)=0A=
--=0A=
=0A=
> =0A=
> ________________________________________=0A=
> From: Tu Dinh <ngoc-tu.dinh@vates.tech>=0A=
> Sent: 27 March 2026 9:33 AM=0A=
> To: win-pv-devel@lists.xenproject.org=0A=
> Cc: Tu Dinh; Owen Smith=0A=
> Subject: [RFC PATCH] Call EvtchnUnmask within the BlkifRing lock=0A=
> =0A=
> The call to EvtchnUnmask accesses Channel outside of the blkif ring=0A=
> lock. Therefore, it can access a stale channel if the DPC is still=0A=
> running after the channel has been closed in BlkifRingDisconnect. Since=
=0A=
> BlkifRingDisconnect runs at DISPATCH_LEVEL, we cannot use=0A=
> KeFlushQueuedDpcs and have to guard against the event channel's closure=
=0A=
> via the Enabled flag instead.=0A=
> =0A=
> Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>=0A=
> ---=0A=
> =0A=
> Notes:=0A=
>=A0=A0=A0=A0=A0 This issue is reliably reproducible by repeatedly suspendi=
ng/resuming or=0A=
>=A0=A0=A0=A0=A0 migrating a VM, which at some point will cause it to lock =
up when trying=0A=
>=A0=A0=A0=A0=A0 to acquire a lock on the event channel. The failure will t=
ypically=0A=
>=A0=A0=A0=A0=A0 happen within 100 resume cycles. Note the corrupted event =
channel below:=0A=
> =0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0 nt!KeBugCheckEx:=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0 fffff803`e3f3ad20 48894c2408=A0=A0=A0=A0=A0 mo=
v=A0=A0=A0=A0 qword ptr [rsp+8],rcx ss:0018:fffff803`79b9eb50=3D00000000000=
00080=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0 0: kd> kP=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 # Child-SP=A0=A0=A0=A0=A0=A0=A0=A0=A0 RetAd=
dr=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 Call Site=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0 00 fffff803`79b9eb48 fffff803`e3f832e2=A0=A0=
=A0=A0 nt!KeBugCheckEx=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0 01 fffff803`79b9eb50 fffff803`e3f7d8d9=A0=A0=
=A0=A0 nt!HalpNMIHalt+0x2e=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0 02 fffff803`79b9eb90 fffff803`750a129b=A0=A0=
=A0=A0 nt!HalBugCheckSystem+0x69=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0 03 fffff803`79b9ebd0 fffff803`e411f632=A0=A0=
=A0=A0 PSHED!PshedBugCheckSystem+0xb=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0 04 fffff803`79b9ec00 fffff803`e3f830bb=A0=A0=
=A0=A0 nt!WheaReportHwError+0x2b5752=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0 05 fffff803`79b9ecc0 fffff803`e3ff6daf=A0=A0=
=A0=A0 nt!HalHandleNMI+0x14b=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0 06 fffff803`79b9ecf0 fffff803`e40eeac2=A0=A0=
=A0=A0 nt!KiProcessNMI+0xff=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0 07 fffff803`79b9ed30 fffff803`e40ee82e=A0=A0=
=A0=A0 nt!KxNmiInterrupt+0x82=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0 08 fffff803`79b9ee70 fffff803`e3c94e6c=A0=A0=
=A0=A0 nt!KiNmiInterrupt+0x26e=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0 09 ffff9600`a38a7640 fffff803`e3c94d5e=A0=A0=
=A0=A0 nt!KxWaitForSpinLockAndAcquire+0x1c=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0 0a ffff9600`a38a7670 fffff803`e4064a62=A0=A0=
=A0=A0 nt!KeAcquireSpinLockRaiseToDpc+0x5e=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0 0b ffff9600`a38a76a0 fffff803`e45df368=A0=A0=
=A0=A0 nt!DifKeAcquireSpinLockRaiseToDpcWrapper+0xd2=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0 0c ffff9600`a38a76f0 fffff803`761f59ea=A0=A0=
=A0=A0 nt!VerifierKeAcquireSpinLockRaiseToDpc+0x28=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0 0d ffff9600`a38a7720 fffff803`78a1dcd0=A0=A0=
=A0=A0 xenbus!EvtchnUnmask(=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 struct _IN=
TERFACE * Interface =3D <Value unavailable error>,=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 struct _XE=
NBUS_EVTCHN_CHANNEL * Channel =3D 0xffffbe01`a45fcf80,=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 unsigned c=
har InUpcall =3D 0x00 '',=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 unsigned c=
har Force =3D 0x01 '')+0x3a [xenbus\src\xenbus\evtchn.c @ 824]=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0 0e ffff9600`a38a7760 fffff803`e3c95b42=A0=A0=
=A0=A0 xenvbd!BlkifRingDpc(=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 struct _KD=
PC * Dpc =3D 0xfffff803`74b29a00,=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 void * Con=
text =3D 0xffffbe01`a4116e50,=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 void * Arg=
ument1 =3D 0x00000000`00000000,=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 void * Arg=
ument2 =3D 0x00000000`00000000)+0x3c0 [xenvbd\src\xenvbd\ring.c @ 1627]=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0 0f ffff9600`a38a77d0 fffff803`e4006592=A0=A0=
=A0=A0 nt!KiExecuteAllDpcs+0x692=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0 10 ffff9600`a38a7a10 fffff803`e3ec7dca=A0=A0=
=A0=A0 nt!KiExecuteDpc+0xc2=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0 11 ffff9600`a38a7bf0 fffff803`e40e3c74=A0=A0=
=A0=A0 nt!PspSystemThreadStartup+0x5a=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0 12 ffff9600`a38a7c40 00000000`00000000=A0=A0=
=A0=A0 nt!KiStartSystemThread+0x34=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0 0: kd> dx -id 0,0,ffffbe019f6f5040 -r1 ((xenbu=
s!_XENBUS_EVTCHN_CHANNEL *)0xffffbe01a45fcf80)=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0 ((xenbus!_XENBUS_EVTCHN_CHANNEL *)0xffffbe01a4=
5fcf80)=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 : 0xffffbe01a45fcf8=
0 [Type: _XENBUS_EVTCHN_CHANNEL *]=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 [+0x000] Magic=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0 : 0x28 [Type: unsigned long]=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 [+0x008] Lock=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0 : 0xffffffff [Type: unsigned __int64]=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 [+0x010] ListEntry=A0=A0=A0=A0=A0=
=A0=A0 [Type: _LIST_ENTRY]=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 [+0x020] PendingListEntry [Type: _=
LIST_ENTRY]=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 [+0x030] Pending=A0=A0=A0=A0=A0=A0=
=A0=A0=A0 : -1542361520 [Type: long]=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 [+0x038] Caller=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 : 0xffffbe01a4cb9010 [Type: void *]=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 [+0x040] Callback=A0=A0=A0=A0=A0=
=A0=A0=A0 : 0xffffbe01a4cb9010 : 0xffffbe01a4cb9010 [Type: unsigned char (_=
_cdecl*)(_KINTERRUPT *,void *)]=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 [+0x048] Argument=A0=A0=A0=A0=A0=
=A0=A0=A0 : 0xffffbe01a4cb9010 [Type: void *]=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 [+0x050] Active=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 : 0x65 [Type: unsigned char]=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 [+0x054] Count=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0 : 0x0 [Type: unsigned long]=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 [+0x058] Type=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0 : -1527206080 [Type: _XENBUS_EVTCHN_TYPE]=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 [+0x05c] Parameters=A0=A0=A0=A0=A0=
=A0 [Type: _XENBUS_EVTCHN_PARAMETERS]=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 [+0x064] Mask=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0 : 0x1 [Type: unsigned char]=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 [+0x068] LocalPort=A0=A0=A0=A0=A0=
=A0=A0 : 0x1 [Type: unsigned long]=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 [+0x06c] Cpu=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0 : 0x0 [Type: unsigned long]=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 [+0x070] Closed=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0 : 0x2f [Type: unsigned char]=0A=
> =0A=
>=A0=A0=A0=A0=A0 Xencons may benefit from the same change.=0A=
> =0A=
>=A0=A0=A0=A0=A0 This patch will probably hurt performance in some way, but=
 calling=0A=
>=A0=A0=A0=A0=A0 EvtchnUnmask within the lock is needed to ensure that the =
channel is=0A=
>=A0=A0=A0=A0=A0 alive.=0A=
> =0A=
>=A0=A0=A0=A0=A0 Xencons tries to fix this problem by skipping the unmask c=
all when the=0A=
>=A0=A0=A0=A0=A0 ring is not enabled, but Enabled could have gone stale by =
the time it=0A=
>=A0=A0=A0=A0=A0 has reached the unmask, and so KeFlushQueuedDpcs is still =
needed to=0A=
>=A0=A0=A0=A0=A0 chase out any running DPCs before closing the channel.=0A=
> =0A=
>=A0=A0=A0=A0=A0 It might be possible to fix this by signaling the end of e=
ach DPC with=0A=
>=A0=A0=A0=A0=A0 an atomic, then synchronize with that in RingDisconnect, b=
ut I haven't=0A=
>=A0=A0=A0=A0=A0 investigated whether that'd help performance.=0A=
> =0A=
>=A0=A0 src/xenvbd/ring.c | 22 +++++++++++++++-------=0A=
>=A0=A0 1 file changed, 15 insertions(+), 7 deletions(-)=0A=
> =0A=
> diff --git a/src/xenvbd/ring.c b/src/xenvbd/ring.c=0A=
> index 50f8d58..409d6ab 100644=0A=
> --- a/src/xenvbd/ring.c=0A=
> +++ b/src/xenvbd/ring.c=0A=
> @@ -1611,19 +1611,27 @@ BlkifRingDpc(=0A=
> =0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 KeRaiseIrql(DISPATCH_LEVEL, &Irql);=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 __BlkifRingAcquireLock(BlkifRing);=0A=
> -=A0=A0=A0=A0=A0=A0=A0 Retry =3D BlkifRingPoll(BlkifRing);=0A=
> +=0A=
> +=A0=A0=A0=A0=A0=A0=A0 if (BlkifRing->Enabled) {=0A=
> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 Retry =3D BlkifRingPoll(BlkifRing);=0A=
> +=0A=
> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if (!Retry) {=0A=
> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 (VOID) XENBUS_EVTCHN(Unmas=
k,=0A=
> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 &Ring->EvtchnInterface,=0A=
> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 BlkifRing->Channel,=0A=
> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 FALSE,=0A=
> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 TRUE);=0A=
> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 }=0A=
> +=A0=A0=A0=A0=A0=A0=A0 } else {=0A=
> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 Retry =3D FALSE;=0A=
> +=A0=A0=A0=A0=A0=A0=A0 }=0A=
> +=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 __BlkifRingReleaseLock(BlkifRing);=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 KeLowerIrql(Irql);=0A=
> =0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if (!Retry)=0A=
>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 break;=0A=
>=A0=A0=A0=A0=A0=A0 }=0A=
> -=0A=
> -=A0=A0=A0 XENBUS_EVTCHN(Unmask,=0A=
> -=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 &Ring->EvtchnInterfa=
ce,=0A=
> -=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 BlkifRing->Channel,=
=0A=
> -=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 FALSE,=0A=
> -=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 TRUE);=0A=
>=A0=A0 }=0A=
> =0A=
>=A0=A0 #define TIME_US(_us)=A0=A0=A0=A0=A0=A0=A0 ((_us) * 10)=0A=
> --=0A=
> 2.53.0.windows.2=0A=
> =0A=
> =0A=
> =0A=
> --=0A=
> Ngoc Tu Dinh | Vates XCP-ng Developer=0A=
> =0A=
> XCP-ng & Xen Orchestra - Vates solutions=0A=
> =0A=
> web: https://vates.tech=0A=
> =0A=
=0A=
=0A=
=0A=
--=0A=
Ngoc Tu Dinh | Vates XCP-ng Developer=0A=
=0A=
XCP-ng & Xen Orchestra - Vates solutions=0A=
=0A=
web: https://vates.tech=0A=
=0A=
=0A=
=0A=


From win-pv-devel-bounces@lists.xenproject.org Fri Mar 27 15:21:15 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Fri, 27 Mar 2026 15:21:15 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1265873.1556620 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1w68zr-0005DZ-Gx; Fri, 27 Mar 2026 15:21:15 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1265873.1556620; Fri, 27 Mar 2026 15:21:15 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1w68zr-0005DS-EC; Fri, 27 Mar 2026 15:21:15 +0000
Received: by outflank-mailman (input) for mailman id 1265873;
 Fri, 27 Mar 2026 15:21:14 +0000
Received: from mx.expurgate.net ([195.190.135.10])
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <bounce-md_30504962.69c6a067.v1-021876cd02b34ef7a873a0f3132ec4c2@bounce.vates.tech>)
 id 1w68zq-0005Ch-65
 for win-pv-devel@lists.xenproject.org; Fri, 27 Mar 2026 15:21:14 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1w68zp-00DmtL-IS
 for win-pv-devel@lists.xenproject.org; Fri, 27 Mar 2026 16:21:13 +0100
Received: from [10.42.69.3] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from
 <bounce-md_30504962.69c6a067.v1-021876cd02b34ef7a873a0f3132ec4c2@bounce.vates.tech>)
 id 69c6a067-2eae-0a2a0a5409dd-0a2a4503b7a2-6
 for <win-pv-devel@lists.xenproject.org>; Fri, 27 Mar 2026 16:21:13 +0100
Received: from [198.2.132.14] (helo=mail132-14.atl131.mandrillapp.com)
 by tlsNG-33051d.mxtls.expurgate.net with ESMTPS (eXpurgate 4.55.2)
 (envelope-from
 <bounce-md_30504962.69c6a067.v1-021876cd02b34ef7a873a0f3132ec4c2@bounce.vates.tech>)
 id 69c6a068-1947-0a2a45030019-c602840e3c62-3
 for <win-pv-devel@lists.xenproject.org>; Fri, 27 Mar 2026 16:21:13 +0100
Received: from pmta09.mandrill.prod.atl01.rsglab.com (localhost [127.0.0.1])
 by mail132-14.atl131.mandrillapp.com (Mailchimp) with ESMTP id
 4fj49M6nYGz8XRyhM
 for <win-pv-devel@lists.xenproject.org>; Fri, 27 Mar 2026 15:21:11 +0000 (GMT)
Received: from [37.26.189.201] by mandrillapp.com id
 021876cd02b34ef7a873a0f3132ec4c2; Fri, 27 Mar 2026 15:21:11 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=mte1 header.d=mandrillapp.com header.i="@mandrillapp.com" header.h="From:Subject:Message-Id:To:References:In-Reply-To:Feedback-ID:Date:MIME-Version:Content-Type:Content-Transfer-Encoding"; dkim=pass header.s=mte1 header.d=vates.tech header.i="ngoc-tu.dinh@vates.tech" header.h="From:Subject:Message-Id:To:References:In-Reply-To:Feedback-ID:Date:MIME-Version:Content-Type:Content-Transfer-Encoding"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com;
	s=mte1; t=1774624871; x=1774894871;
	bh=A+47sFBaykALOHkKPC3U4v+eXEA3ft2tvLrbtIcGiew=;
	h=From:Subject:Message-Id:To:References:In-Reply-To:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=qZY3mNNNnCvT+me/4YR4IS3y40+CnfORhhKEyhhTfEvFHJeNj942UHzoswld6b3Hy
	 ZKQWja5EemoBikb9LxCZKrUN/mKqAMsF0LRRei4mT4zP3ervxeMdDSWN1QHz3gdc87
	 SP81dgdBYM4qOftUKUbN2jxz7vFTXjwnml1fsBYBUKMa7EqCMLTt2SOXGznmozZYTQ
	 iKNrpX8qVDB3PFxsBf/07rWFGdoU7AZedVbJ4v3OzULZ2YAJv0Rh4veyMBSH7/OjG1
	 n2sXgavKl1mo0Nm5pfJ/2wSdfaP/eMDeYcL/DuS8Nv35iojqWBiFjTsfwrJg49CHXY
	 lgfNX61tfvvsw==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1;
	t=1774624871; x=1774885371; i=ngoc-tu.dinh@vates.tech;
	bh=A+47sFBaykALOHkKPC3U4v+eXEA3ft2tvLrbtIcGiew=;
	h=From:Subject:Message-Id:To:References:In-Reply-To:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=jL0Pn1Kw6erIQfTeTUgMUiz0hyaTucsRvyZnqikbRepNc7kIB1FvEozxNrEr3dsPt
	 Pu1VG6H23CD7BIvG0fXe8NyKUpUbNo1xE/iVEjN8KzqVpF5lV37PHBWhtitQuolc5X
	 jHgbpoTt/zD55dTA+tG7z38BARFR0vO7FoHS+ibySnNlPhYGTPd/2LueuNQfhoQd2p
	 sGXQS2qKoBhPJkiYTCy314y8T1J1gJ14sgc6KaXyk43ycCjviMyRmoikIT+i6S4n4e
	 J1Coat27dwCINdiaIfXMH1uUSf01SabQT0jw5xJyKdrLSKaPjwpu5+qod8jlWNUvS5
	 GEIZOxJ5gTUEA==
From: "Tu Dinh" <ngoc-tu.dinh@vates.tech>
Subject: =?utf-8?Q?Re:=20[RFC=20PATCH]=20Call=20EvtchnUnmask=20within=20the=20BlkifRing=20lock?=
X-Bm-Disclaimer: Yes
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1774624871181
Message-Id: <14ad6043-82ee-4de7-9946-6886ae64ddfe@vates.tech>
To: "Owen Smith" <owen.smith@citrix.com>, win-pv-devel@lists.xenproject.org
References: <20260327093338.493-1-ngoc-tu.dinh@vates.tech> <SA6PR03MB77603FABB8FD375640EC9110FE57A@SA6PR03MB7760.namprd03.prod.outlook.com> <15f1992f-b96f-4859-897d-f431437b7107@vates.tech> <SA6PR03MB7760DBA263BC5C1361B89349FE57A@SA6PR03MB7760.namprd03.prod.outlook.com>
In-Reply-To: <SA6PR03MB7760DBA263BC5C1361B89349FE57A@SA6PR03MB7760.namprd03.prod.outlook.com>
X-Native-Encoded: 1
X-Report-Abuse: =?UTF-8?Q?Please=20forward=20a=20copy=20of=20this=20message,=20including=20all=20headers,=20to=20abuse@mandrill.com.=20You=20can=20also=20report=20abuse=20here:=20https://mandrillapp.com/contact/abuse=3Fid=3D30504962.021876cd02b34ef7a873a0f3132ec4c2?=
X-Mandrill-User: md_30504962
Feedback-ID: 30504962:30504962.20260327:md
Date: Fri, 27 Mar 2026 15:21:11 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-purgate-ID: tlsNG-33051d/1774624873-E949872C-95F65DAE/0/0
X-purgate-type: clean
X-purgate-size: 20094

On 27/03/2026 16:14, Owen Smith wrote:
> It may not need changes to BlkifRingPoll
> 
> Retry =3D BlkifRingPoll(BlkifRing);
> if (BlkifRing->Enabled)
>      (VOID) XENBUS_EVTCHN(Unmask,.....)
> 

Oh, as in flipping the condition. It should still require `if (!Retry && 
BlkifRing->Enabled)` to avoid unmasking in the middle of a retry cycle 
right?

> 
> Owen
> 
> ________________________________________
> From: Tu Dinh <ngoc-tu.dinh@vates.tech>
> Sent: Friday, March 27, 2026 3:07 PM
> To: Owen Smith <owen.smith@citrix.com>; win-pv-devel@lists.xenproject.org=
 <win-pv-devel@lists.xenproject.org>
> Subject: Re: [RFC PATCH] Call EvtchnUnmask within the BlkifRing lock
> 
> 
> On 27/03/2026 15:01, Owen Smith wrote:
>>
>> BlkifRingPoll already checks that BlkifRing->Enabled is TRUE, but in thi=
s
>> case the return value would be FALSE, which would need another check
>> to protect against Unmask being called on a Channel that has been closed=
.
>>
>> Owen
> 
> Do you mean something like this?
> 
> diff --git a/src/xenvbd/ring.c b/src/xenvbd/ring.c
> index 50f8d58..ddf12fc 100644
> --- a/src/xenvbd/ring.c
> +++ b/src/xenvbd/ring.c
> @@ -1211,7 +1211,8 @@ __BlkifRingCompleteResponse(
> 
>  =C2=A0 static FORCEINLINE BOOLEAN
>  =C2=A0 BlkifRingPoll(
> -=C2=A0=C2=A0=C2=A0 IN=C2=A0 PXENVBD_BLKIF_RING=C2=A0 BlkifRing
> +=C2=A0=C2=A0=C2=A0 IN=C2=A0 PXENVBD_BLKIF_RING=C2=A0 BlkifRing,
> +=C2=A0=C2=A0=C2=A0 IN=C2=A0 PBOOLEAN=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Enabled
>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 )
>  =C2=A0 {
>  =C2=A0 #define XENVBD_BATCH(_Ring) (RING_SIZE(&(_Ring)->Front) / 4)
> @@ -1222,8 +1223,12 @@ BlkifRingPoll(
>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Ring =3D BlkifRing->Ring;
>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Retry =3D FALSE;
> 
> -=C2=A0=C2=A0=C2=A0 if (!BlkifRing->Enabled)
> +=C2=A0=C2=A0=C2=A0 if (BlkifRing->Enabled) {
> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 *Enabled =3D TRUE;
> +=C2=A0=C2=A0=C2=A0 } else {
> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 *Enabled =3D FALSE;
>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 goto done;
> +=C2=A0=C2=A0=C2=A0 }
> 
>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 for (;;) {
>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 RING_IDX=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 rsp_prod;
> @@ -1607,23 +1612,26 @@ BlkifRingDpc(
> 
>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 for (;;) {
>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 BOOLEAN=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Retry;
> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 BOOLEAN=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 Enabled;
>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 KIRQL=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Irql;
> 
>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 KeRaiseIrql(DISPA=
TCH_LEVEL, &Irql);
>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 __BlkifRingAcquir=
eLock(BlkifRing);
> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Retry =3D BlkifRingPoll(Blkif=
Ring);
> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Retry =3D BlkifRingPoll(Blkif=
Ring, &Enabled);
> +
> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (Enabled)
> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 (VOID=
) XENBUS_EVTCHN(Unmask,
> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 &Ring->EvtchnInterface,
> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 BlkifRing->Channel,
> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 FALSE,
> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 TRUE);
> +
>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 __BlkifRingReleas=
eLock(BlkifRing);
>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 KeLowerIrql(Irql)=
;
> 
>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (!Retry)
>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 break;
>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }
> -
> -=C2=A0=C2=A0=C2=A0 XENBUS_EVTCHN(Unmask,
> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 &Ring->EvtchnInterface,
> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 BlkifRing->Channel,
> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 FALSE,
> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 TRUE);
>  =C2=A0 }
> 
>  =C2=A0 #define TIME_US(_us)=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ((=
_us) * 10)
> --
> 
>>
>> ________________________________________
>> From: Tu Dinh <ngoc-tu.dinh@vates.tech>
>> Sent: 27 March 2026 9:33 AM
>> To: win-pv-devel@lists.xenproject.org
>> Cc: Tu Dinh; Owen Smith
>> Subject: [RFC PATCH] Call EvtchnUnmask within the BlkifRing lock
>>
>> The call to EvtchnUnmask accesses Channel outside of the blkif ring
>> lock. Therefore, it can access a stale channel if the DPC is still
>> running after the channel has been closed in BlkifRingDisconnect. Since
>> BlkifRingDisconnect runs at DISPATCH_LEVEL, we cannot use
>> KeFlushQueuedDpcs and have to guard against the event channel's closure
>> via the Enabled flag instead.
>>
>> Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
>> ---
>>
>> Notes:
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 This issue is reliably reproducible by r=
epeatedly suspending/resuming or
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 migrating a VM, which at some point will=
 cause it to lock up when trying
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 to acquire a lock on the event channel. =
The failure will typically
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 happen within 100 resume cycles. Note th=
e corrupted event channel below:
>>
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 nt!KeBugCheckEx:
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 fffff803`e3f3ad2=
0 48894c2408=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 mov=C2=A0=C2=A0=C2=A0=C2=A0 qwor=
d ptr [rsp+8],rcx ss:0018:fffff803`79b9eb50=3D0000000000000080
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 0: kd> kP
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 # Child-SP=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 RetAddr=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Ca=
ll Site
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 00 fffff803`79b9=
eb48 fffff803`e3f832e2=C2=A0=C2=A0=C2=A0=C2=A0 nt!KeBugCheckEx
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 01 fffff803`79b9=
eb50 fffff803`e3f7d8d9=C2=A0=C2=A0=C2=A0=C2=A0 nt!HalpNMIHalt+0x2e
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 02 fffff803`79b9=
eb90 fffff803`750a129b=C2=A0=C2=A0=C2=A0=C2=A0 nt!HalBugCheckSystem+0x69
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 03 fffff803`79b9=
ebd0 fffff803`e411f632=C2=A0=C2=A0=C2=A0=C2=A0 PSHED!PshedBugCheckSystem+0x=
b
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 04 fffff803`79b9=
ec00 fffff803`e3f830bb=C2=A0=C2=A0=C2=A0=C2=A0 nt!WheaReportHwError+0x2b575=
2
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 05 fffff803`79b9=
ecc0 fffff803`e3ff6daf=C2=A0=C2=A0=C2=A0=C2=A0 nt!HalHandleNMI+0x14b
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 06 fffff803`79b9=
ecf0 fffff803`e40eeac2=C2=A0=C2=A0=C2=A0=C2=A0 nt!KiProcessNMI+0xff
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 07 fffff803`79b9=
ed30 fffff803`e40ee82e=C2=A0=C2=A0=C2=A0=C2=A0 nt!KxNmiInterrupt+0x82
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 08 fffff803`79b9=
ee70 fffff803`e3c94e6c=C2=A0=C2=A0=C2=A0=C2=A0 nt!KiNmiInterrupt+0x26e
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 09 ffff9600`a38a=
7640 fffff803`e3c94d5e=C2=A0=C2=A0=C2=A0=C2=A0 nt!KxWaitForSpinLockAndAcqui=
re+0x1c
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 0a ffff9600`a38a=
7670 fffff803`e4064a62=C2=A0=C2=A0=C2=A0=C2=A0 nt!KeAcquireSpinLockRaiseToD=
pc+0x5e
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 0b ffff9600`a38a=
76a0 fffff803`e45df368=C2=A0=C2=A0=C2=A0=C2=A0 nt!DifKeAcquireSpinLockRaise=
ToDpcWrapper+0xd2
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 0c ffff9600`a38a=
76f0 fffff803`761f59ea=C2=A0=C2=A0=C2=A0=C2=A0 nt!VerifierKeAcquireSpinLock=
RaiseToDpc+0x28
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 0d ffff9600`a38a=
7720 fffff803`78a1dcd0=C2=A0=C2=A0=C2=A0=C2=A0 xenbus!EvtchnUnmask(
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 struct _INTERFACE=
 * Interface =3D <Value unavailable error>,
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 struct _XENBUS_EV=
TCHN_CHANNEL * Channel =3D 0xffffbe01`a45fcf80,
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 unsigned char InU=
pcall =3D 0x00 '',
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 unsigned char For=
ce =3D 0x01 '')+0x3a [xenbus\src\xenbus\evtchn.c @ 824]
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 0e ffff9600`a38a=
7760 fffff803`e3c95b42=C2=A0=C2=A0=C2=A0=C2=A0 xenvbd!BlkifRingDpc(
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 struct _KDPC * Dp=
c =3D 0xfffff803`74b29a00,
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 void * Context =
=3D 0xffffbe01`a4116e50,
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 void * Argument1 =
=3D 0x00000000`00000000,
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 void * Argument2 =
=3D 0x00000000`00000000)+0x3c0 [xenvbd\src\xenvbd\ring.c @ 1627]
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 0f ffff9600`a38a=
77d0 fffff803`e4006592=C2=A0=C2=A0=C2=A0=C2=A0 nt!KiExecuteAllDpcs+0x692
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 10 ffff9600`a38a=
7a10 fffff803`e3ec7dca=C2=A0=C2=A0=C2=A0=C2=A0 nt!KiExecuteDpc+0xc2
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 11 ffff9600`a38a=
7bf0 fffff803`e40e3c74=C2=A0=C2=A0=C2=A0=C2=A0 nt!PspSystemThreadStartup+0x=
5a
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 12 ffff9600`a38a=
7c40 00000000`00000000=C2=A0=C2=A0=C2=A0=C2=A0 nt!KiStartSystemThread+0x34
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 0: kd> dx -id 0,=
0,ffffbe019f6f5040 -r1 ((xenbus!_XENBUS_EVTCHN_CHANNEL *)0xffffbe01a45fcf80=
)
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ((xenbus!_XENBUS=
_EVTCHN_CHANNEL *)0xffffbe01a45fcf80)=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 : 0xffffbe01a4=
5fcf80 [Type: _XENBUS_EVTCHN_CHANNEL *]
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 [+0x000] Magic=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 : 0x28 [Type: unsigned long]
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 [+0x008] Lock=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 : 0xffffffff [Type: unsigned __int64]
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 [+0x010] ListEntry=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [Typ=
e: _LIST_ENTRY]
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 [+0x020] PendingListEntry [Type: _LIST_ENTRY]
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 [+0x030] Pending=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 : -1542361520 [Type: long]
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 [+0x038] Caller=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 : 0xffffbe01a4cb9010 [Type: void *]
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 [+0x040] Callback=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 : 0xffffbe01a4cb9010 : 0xffffbe01a4cb9010 [Type: unsigned char (__cdecl*)(=
_KINTERRUPT *,void *)]
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 [+0x048] Argument=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
 : 0xffffbe01a4cb9010 [Type: void *]
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 [+0x050] Active=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 : 0x65 [Type: unsigned char]
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 [+0x054] Count=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 : 0x0 [Type: unsigned long]
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 [+0x058] Type=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 : -1527206080 [Type: _XENBUS_EVTCHN_TYPE]
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 [+0x05c] Parameters=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [Type: _X=
ENBUS_EVTCHN_PARAMETERS]
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 [+0x064] Mask=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 : 0x1 [Type: unsigned char]
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 [+0x068] LocalPort=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 : 0x=
1 [Type: unsigned long]
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 [+0x06c] Cpu=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 : 0x0 [Type: unsigned long]
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 [+0x070] Closed=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 : 0x2f [Type: unsigned char]
>>
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Xencons may benefit from the same change=
.
>>
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 This patch will probably hurt performanc=
e in some way, but calling
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 EvtchnUnmask within the lock is needed t=
o ensure that the channel is
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 alive.
>>
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Xencons tries to fix this problem by ski=
pping the unmask call when the
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ring is not enabled, but Enabled could h=
ave gone stale by the time it
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 has reached the unmask, and so KeFlushQu=
euedDpcs is still needed to
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 chase out any running DPCs before closin=
g the channel.
>>
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 It might be possible to fix this by sign=
aling the end of each DPC with
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 an atomic, then synchronize with that in=
 RingDisconnect, but I haven't
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 investigated whether that'd help perform=
ance.
>>
>>  =C2=A0=C2=A0 src/xenvbd/ring.c | 22 +++++++++++++++-------
>>  =C2=A0=C2=A0 1 file changed, 15 insertions(+), 7 deletions(-)
>>
>> diff --git a/src/xenvbd/ring.c b/src/xenvbd/ring.c
>> index 50f8d58..409d6ab 100644
>> --- a/src/xenvbd/ring.c
>> +++ b/src/xenvbd/ring.c
>> @@ -1611,19 +1611,27 @@ BlkifRingDpc(
>>
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 KeRaiseIrq=
l(DISPATCH_LEVEL, &Irql);
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 __BlkifRin=
gAcquireLock(BlkifRing);
>> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Retry =3D BlkifRingPoll(Blki=
fRing);
>> +
>> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (BlkifRing->Enabled) {
>> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Retr=
y =3D BlkifRingPoll(BlkifRing);
>> +
>> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (=
!Retry) {
>> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 (VOID) XENBUS_EVTCHN(Unmask,
>> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 &R=
ing->EvtchnInterface,
>> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Bl=
kifRing->Channel,
>> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 FA=
LSE,
>> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 TR=
UE);
>> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }
>> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } else {
>> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Retr=
y =3D FALSE;
>> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }
>> +
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 __BlkifRin=
gReleaseLock(BlkifRing);
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 KeLowerIrq=
l(Irql);
>>
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (!Retry=
)
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 break;
>>  =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }
>> -
>> -=C2=A0=C2=A0=C2=A0 XENBUS_EVTCHN(Unmask,
>> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 &Ring->EvtchnInterface,
>> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 BlkifRing->Channel,
>> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 FALSE,
>> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 TRUE);
>>  =C2=A0=C2=A0 }
>>
>>  =C2=A0=C2=A0 #define TIME_US(_us)=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 ((_us) * 10)
>> --
>> 2.53.0.windows.2
>>
>>
>>
>> --
>> Ngoc Tu Dinh | Vates XCP-ng Developer
>>
>> XCP-ng & Xen Orchestra - Vates solutions
>>
>> web: https://vates.tech
>>
> 
> 
> 
> --
> Ngoc Tu Dinh | Vates XCP-ng Developer
> 
> XCP-ng & Xen Orchestra - Vates solutions
> 
> web: https://vates.tech
> 
> 
> 



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech




From win-pv-devel-bounces@lists.xenproject.org Fri Mar 27 15:26:20 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Fri, 27 Mar 2026 15:26:20 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1265905.1556634 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1w694l-00069m-4o; Fri, 27 Mar 2026 15:26:19 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1265905.1556634; Fri, 27 Mar 2026 15:26:19 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1w694l-00069f-1g; Fri, 27 Mar 2026 15:26:19 +0000
Received: by outflank-mailman (input) for mailman id 1265905;
 Fri, 27 Mar 2026 15:26:17 +0000
Received: from mx.expurgate.net ([195.190.135.10])
 by lists.xenproject.org with esmtp (Exim 4.92)
 (envelope-from <owen.smith@citrix.com>) id 1w694j-00069X-1X
 for win-pv-devel@lists.xenproject.org; Fri, 27 Mar 2026 15:26:17 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1w694i-007CmE-7V
 for win-pv-devel@lists.xenproject.org; Fri, 27 Mar 2026 16:26:16 +0100
Received: from [10.42.69.7] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1)
 (envelope-from <owen.smith@citrix.com>)
 id 69c6a195-5cb7-0a2a0a5109dd-0a2a4507bf18-2
 for <win-pv-devel@lists.xenproject.org>; Fri, 27 Mar 2026 16:26:16 +0100
Received: from [52.101.61.14]
 (helo=DM1PR04CU001.outbound.protection.outlook.com)
 by tlsNG-ef75cf.mxtls.expurgate.net with ESMTPS (eXpurgate 4.55.2)
 (envelope-from <owen.smith@citrix.com>)
 id 69c6a196-fd74-0a2a45070019-34653d0e5e1b-4
 for <win-pv-devel@lists.xenproject.org>; Fri, 27 Mar 2026 16:26:15 +0100
Received: from SA6PR03MB7760.namprd03.prod.outlook.com (2603:10b6:806:43c::5)
 by PH7PR03MB6919.namprd03.prod.outlook.com (2603:10b6:510:150::13)
 with Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9745.20; Fri, 27 Mar
 2026 15:26:11 +0000
Received: from SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38]) by SA6PR03MB7760.namprd03.prod.outlook.com
 ([fe80::4d5b:a91f:46a3:4b38%7]) with mapi id 15.20.9745.023; Fri, 27 Mar 2026
 15:26:11 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=citrix.com header.i="@citrix.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:x-ms-exchange-senderadcheck"
ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;
 b=Mi2vpg3xmtL0UEKmgXD1NmemT3FvjY2VMwKeiB6OB9egnCZzVtuYx5XVfaUc95FslVIJk7ixfp1ZW9oNoTX3pGiypp6E27seVjhd5Z/KopAJCjfDjJOz+dbOEFYPOo6e9/ggblwZKWE9ZA7VXRQ3RHGLU5WSFUJHWKAZ8S8b9b0cMtV8Oyta9WxlGYqAEWX4KoTMXUPCytF1Cm/0iMxRS8CvIQ5Lv4aM7i+2/+tawTFvCXY0LKV7vl5Wgc7Hi/H64zeaUAlzGrDjU/RaOfrKT37aq/73v87OXIdjDxzg/EwX3ofpgH9lb1jVngEoJxWGIm1IAk8FbYLw+thoXhPq6Q==
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=bOOcPzZ5T/zjQNQsVawxWY1VvPc0ioW92i2L4g+IbVc=;
 b=YTn8K98R/GfS2nL1rDLYGeYJDvxBv6RGlJ3SZbiRyGGkCftZatfCgWFjH7ktyxnFYJWtyD43QDRRKbEmJnq6Wt5e9Im5yeY1H238rBDh61gDRexU8dPluPBK2yRww0ZAm953thakSZXuJuGuOjdSoKSkn1CF5ndcIM71PBANsuyqAWAxk+KjbKleXoIlI6nNj8s4C/0Ta9PjqtwC3dtQJa9Pc0eVBJKXFsMLBhQwWk3Y3PnembXwbXAmVGdgHg0ng9YejDBHLB9SV6w+DODQJbvs+zBUKYbDjeNK7Dc/a0XCHj97bohahqlX5OCsNrjKCobDqc4Ux17tdm06hf5P2Q==
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
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com;
 s=selector1;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=bOOcPzZ5T/zjQNQsVawxWY1VvPc0ioW92i2L4g+IbVc=;
 b=rgf5DdNqzKIDkvpJwh1EoS6pQuy03ej+LCrAGGo/ZGIswbJ18oW+7+WBkcHNCMegt5OctGsNbkzla2CP4JGk6vlLu3PBcXMiQOiVXB0+AqT75ZM8Caz/+6Wfhqqsg+RE3L0twrMp712QDwV0SAzq+9kKW1Hed+j7YsLH1RRMSVA=
From: Owen Smith <owen.smith@citrix.com>
To: Tu Dinh <ngoc-tu.dinh@vates.tech>, "win-pv-devel@lists.xenproject.org"
	<win-pv-devel@lists.xenproject.org>
Subject: Re: [RFC PATCH] Call EvtchnUnmask within the BlkifRing lock
Thread-Topic: [RFC PATCH] Call EvtchnUnmask within the BlkifRing lock
Thread-Index: AQHcvczPQtA3BJsBtk6irODhNC6JUbXCZuLbgAAUcoCAAAFMNoAAAnWAgAABPoQ=
Date: Fri, 27 Mar 2026 15:26:11 +0000
Message-ID:
 <SA6PR03MB776014DCA2A8234A9B7E6E5CFE57A@SA6PR03MB7760.namprd03.prod.outlook.com>
References: <20260327093338.493-1-ngoc-tu.dinh@vates.tech>
 <SA6PR03MB77603FABB8FD375640EC9110FE57A@SA6PR03MB7760.namprd03.prod.outlook.com>
 <15f1992f-b96f-4859-897d-f431437b7107@vates.tech>
 <SA6PR03MB7760DBA263BC5C1361B89349FE57A@SA6PR03MB7760.namprd03.prod.outlook.com>
 <14ad6043-82ee-4de7-9946-6886ae64ddfe@vates.tech>
In-Reply-To: <14ad6043-82ee-4de7-9946-6886ae64ddfe@vates.tech>
Accept-Language: en-GB, en-US
Content-Language: en-GB
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
msip_labels:
authentication-results: dkim=none (message not signed)
 header.d=none;dmarc=none action=none header.from=citrix.com;
x-ms-publictraffictype: Email
x-ms-traffictypediagnostic: SA6PR03MB7760:EE_|PH7PR03MB6919:EE_
x-ms-office365-filtering-correlation-id: 5dd8b883-3a8e-4d46-0bd5-08de8c152d73
x-ms-exchange-senderadcheck: 1
x-ms-exchange-antispam-relay: 0
x-microsoft-antispam:
 BCL:0;ARA:13230040|366016|1800799024|376014|13003099007|38070700021|56012099003|22082099003|18002099003;
x-microsoft-antispam-message-info:
 zP1IkNBK961vAdjTPHx75cPSzV7iaDiaUbxRESgk72/vLcEy+KcW4er3fhDFqUPpVBm3ha9WAYFkb3PUgj90mpfKDJaGGk9bDieGWdGzIoyn7J3Jo5DbBPjCvXsIneQ1hyB5mv1zJKY9v3It7oVbFCdry537j0DrwbzRa9gDjSX/rK/Veas0Y7Fs5OvzrGc+z3Bm7yjKLLRU+a2UDcRx9ok34ll3V/HjYDnD4fIOYGRKPOdOwaLAg2/8bUfN0OQm1qNuwq17we4htLiazYMdzLI38f9ekLRju5j4PAvlUuVLxLktJSCFpWGv2eV9FeZcSRVRTomhTcEK++2v5BjKIryggQK+omtBjZ2vunaS78ZqwDEGbsj0TRn4D0Bu8zA9RzkJA7aWoRcfZtj6hPzFhXFhz/LPi3W6UXYwpNH8ODWopOJ7DWHp7bsmBrB43THGK/S3UCHdqajkRNaSfQPCEB6agsWD0hOZQUKHgFZNzl6pchO+YOU21E8Y33DCQ1g0vRy2CCtleWQ1CrEUqir815AHDWficBtv1vWkJs6xC875Q12pGjVXmWEd4xpAvxJzw9k2L9VoYaBPBcsD3SDoG0JPY4Ac0Ec7xgMJ0KBWAQZ34g7RHUxru2drtarPuXk/lQQrGZuvxUiKxNjZglu1QUHmmx8QB/YPJl26TgduP6Vs1w8D4GOiGbZlunR/5Ql1ia/r8dB4l/FaekyapNcmRVGwEc7betkMUUtGQEhKxo0=
x-forefront-antispam-report:
 CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SA6PR03MB7760.namprd03.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(366016)(1800799024)(376014)(13003099007)(38070700021)(56012099003)(22082099003)(18002099003);DIR:OUT;SFP:1101;
x-ms-exchange-antispam-messagedata-chunkcount: 1
x-ms-exchange-antispam-messagedata-0:
 =?us-ascii?Q?VTIjYaptz2kHHN/Fb4Tu/pSju0cIa/XscXCnh5RYHbI/QXUEFZ/FUc1YVzA6?=
 =?us-ascii?Q?MIHmUaTo4KWtEqAWTpHn+JK6XKjT73oqM05vR8KxcTuuVqFUgTB0IY3tZ789?=
 =?us-ascii?Q?Rh60D8ynKTrd2gMTkzpjcKQt3FKbsVsYWQFgGdFd1XG1fNIkIWwP41QHp8IQ?=
 =?us-ascii?Q?TpgEktrUIIZbXRx/WPtRtGpukZI2YwQrwwRYxVgaTgo6Q/ybS+z9ypmBXSCI?=
 =?us-ascii?Q?Roiyo9F85J4DwSvvR2/6FKWzVwQA2v7QXO+C3EDfC47fxhD3x/EpWPlFCpQa?=
 =?us-ascii?Q?WvP373nPyMjm8b5diO5IiXWCAQIBnxb8aqerXuIYBP8s9aeSPydlyUMc7BK/?=
 =?us-ascii?Q?Gd4Yx8tpSUc7FH6u8qWKou8VUhadZlDZJgc0C3c03WceuN+Yxj0xUYFAronT?=
 =?us-ascii?Q?XN/RS2z2CYeRG2Y2LjDQ6rA7wm0ykjB+Tzrvc9WCt3KqjcHtQ4BRjBeqpxR8?=
 =?us-ascii?Q?F6abS4SCFhJRNCJzl3Mon9npccpMl7pFHkP9BVK7+X2H1C8iP6GNFnsSmQkl?=
 =?us-ascii?Q?irk8qyXZINnm9dpDaWii+LCx8Ec6H2A4cfpNwx22IOTh9IRaS6icIUkVTXqz?=
 =?us-ascii?Q?apemrw/1ZRm1S+UOIgZqxH1oqKF48DCf4hCQ4V9JQbM35uPovIFHqfmr+tUz?=
 =?us-ascii?Q?EIoC4fbIfsnxZrJbgC9zJIIEoZvIPMRX+23b1xa2lJJKpy7FRoHj3XVts+R1?=
 =?us-ascii?Q?GfaS62gh9OWbrFpOFIlRJ7ZVAwDlKjR9woyWP1ZbdsF5XZpC9orpDJKU3Azr?=
 =?us-ascii?Q?qPBicwB2lKpbpTWv6xq+aqDupoDAiaoTIoUF/SUByHm72SZ6Tstt+Lw+b9Zk?=
 =?us-ascii?Q?8P/n3yaMLowUlBQHpNn+uemTD6v9nADjymKgTnBElWNXoFLTZiNqckhhEHEC?=
 =?us-ascii?Q?deoeOLRMFL0uOA8nu9YwBlz3Eldn+wu2sF8A7HHVY/ISsTRv49IXaoeOwVdi?=
 =?us-ascii?Q?1BIf9iqz71Py6BTFf7F/Qqmn3oyXbY0/MDXHQQRC0REibZBqQDJ2qsVbgDoP?=
 =?us-ascii?Q?uFtdpsxqaLb8IpfhnaPTAJwlqiuH3xTC6ogBONiIycyT6b0r+bxqAH1s4cll?=
 =?us-ascii?Q?hlUNKAnlGXmRsidN4jvaD29JDQI8Q+5NM6RdqWp6Tkt2GGJaq8qWE0yNZRLu?=
 =?us-ascii?Q?1fKm0aO+goARp4ypSZV0qCaZ9LFgkRAUfVTNOlLf2MAX+zexFX3Na5VkcRqH?=
 =?us-ascii?Q?y4vA/+jatuukVrcEiRc7LD+Rkt2tS67nOTD/WOB9vbc/iwe/Qb9uVqDPJFAN?=
 =?us-ascii?Q?eGUhNK3joASFzMUDIuqoRLzVi14BGep9Ki8LW4CC33ftUvUQchaYAlsSyLUR?=
 =?us-ascii?Q?HV4MPpzxF9yG3uDl9UrC5AinF8V2vei26jeA03H3IO6vZ8silI5/2RhdQnPs?=
 =?us-ascii?Q?HD6O1Oy1qcBHl+dQKqq1V/5wt/Kzc982s8jNONjNJKNQ+W8gqxwMzWboCbvO?=
 =?us-ascii?Q?CZ9ChFyybAd+yV6u5ubuFCcsnAaDGHeQR9++DQX74Ww8ab8Eo5R97SMjT1/M?=
 =?us-ascii?Q?PYYy8nm3EAWyKELN3DAtLfsXegiBFbDvmo1nedIGusCSmoTdQKAP0jRRogyV?=
 =?us-ascii?Q?/tH71Fk3RWWDgjSyxRAHdaINyv8p8TVy9V+DtkL9tVKva4xtB52smsx3bTPr?=
 =?us-ascii?Q?lPfGTRlOE7kNyBV/Y1U4K9WFvR9egLyLR5RFs9m2jf01GRBVvHNo1ltpFfqJ?=
 =?us-ascii?Q?e3Vq0LLPaOef6ROS+eV4OlmB+cPF+yZkL6C26UZc7bSf/ts0qfySvB2aYcJ1?=
 =?us-ascii?Q?iezN4GGgwg=3D=3D?=
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
X-OriginatorOrg: citrix.com
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-AuthSource: SA6PR03MB7760.namprd03.prod.outlook.com
X-MS-Exchange-CrossTenant-Network-Message-Id: 5dd8b883-3a8e-4d46-0bd5-08de8c152d73
X-MS-Exchange-CrossTenant-originalarrivaltime: 27 Mar 2026 15:26:11.7534
 (UTC)
X-MS-Exchange-CrossTenant-fromentityheader: Hosted
X-MS-Exchange-CrossTenant-id: 335836de-42ef-43a2-b145-348c2ee9ca5b
X-MS-Exchange-CrossTenant-mailboxtype: HOSTED
X-MS-Exchange-CrossTenant-userprincipalname: xkZ6tJpJwdGDCoqHN0QoLRTf1tl+2Z6bNXis941edf9DjqMIt32qly75sRahLFtvv0q3VqxLIxirUIxa6QFkqw==
X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR03MB6919
X-purgate-ID: tlsNG-ef75cf/1774625176-4FEA3303-D810CDBC/0/0
X-purgate-type: clean
X-purgate-size: 11416

Yes, looking back at the code again,

        Retry =3D BlkifRingPoll(BlkifRing);
        if (!Retry && BlkifRing->Enabled) {
                (VOID) XENBUS_EVTCHN(Unmask,
                                     &Ring->EvtchnInterface,
                                     BlkifRing->Channel,
                                     FALSE,
                                     TRUE);
        }

would be needed


Owen

________________________________________
From: Tu Dinh <ngoc-tu.dinh@vates.tech>
Sent: 27 March 2026 3:21 PM
To: Owen Smith; win-pv-devel@lists.xenproject.org
Subject: Re: [RFC PATCH] Call EvtchnUnmask within the BlkifRing lock

On 27/03/2026 16:14, Owen Smith wrote:
> It may not need changes to BlkifRingPoll
>
> Retry =3D BlkifRingPoll(BlkifRing);
> if (BlkifRing->Enabled)
>      (VOID) XENBUS_EVTCHN(Unmask,.....)
>

Oh, as in flipping the condition. It should still require `if (!Retry &&
BlkifRing->Enabled)` to avoid unmasking in the middle of a retry cycle
right?

>
> Owen
>
> ________________________________________
> From: Tu Dinh <ngoc-tu.dinh@vates.tech>
> Sent: Friday, March 27, 2026 3:07 PM
> To: Owen Smith <owen.smith@citrix.com>; win-pv-devel@lists.xenproject.org=
 <win-pv-devel@lists.xenproject.org>
> Subject: Re: [RFC PATCH] Call EvtchnUnmask within the BlkifRing lock
>
>
> On 27/03/2026 15:01, Owen Smith wrote:
>>
>> BlkifRingPoll already checks that BlkifRing->Enabled is TRUE, but in thi=
s
>> case the return value would be FALSE, which would need another check
>> to protect against Unmask being called on a Channel that has been closed=
.
>>
>> Owen
>
> Do you mean something like this?
>
> diff --git a/src/xenvbd/ring.c b/src/xenvbd/ring.c
> index 50f8d58..ddf12fc 100644
> --- a/src/xenvbd/ring.c
> +++ b/src/xenvbd/ring.c
> @@ -1211,7 +1211,8 @@ __BlkifRingCompleteResponse(
>
>    static FORCEINLINE BOOLEAN
>    BlkifRingPoll(
> -    IN  PXENVBD_BLKIF_RING  BlkifRing
> +    IN  PXENVBD_BLKIF_RING  BlkifRing,
> +    IN  PBOOLEAN            Enabled
>        )
>    {
>    #define XENVBD_BATCH(_Ring) (RING_SIZE(&(_Ring)->Front) / 4)
> @@ -1222,8 +1223,12 @@ BlkifRingPoll(
>        Ring =3D BlkifRing->Ring;
>        Retry =3D FALSE;
>
> -    if (!BlkifRing->Enabled)
> +    if (BlkifRing->Enabled) {
> +        *Enabled =3D TRUE;
> +    } else {
> +        *Enabled =3D FALSE;
>            goto done;
> +    }
>
>        for (;;) {
>            RING_IDX            rsp_prod;
> @@ -1607,23 +1612,26 @@ BlkifRingDpc(
>
>        for (;;) {
>            BOOLEAN         Retry;
> +        BOOLEAN         Enabled;
>            KIRQL           Irql;
>
>            KeRaiseIrql(DISPATCH_LEVEL, &Irql);
>            __BlkifRingAcquireLock(BlkifRing);
> -        Retry =3D BlkifRingPoll(BlkifRing);
> +        Retry =3D BlkifRingPoll(BlkifRing, &Enabled);
> +
> +        if (Enabled)
> +            (VOID) XENBUS_EVTCHN(Unmask,
> +                                 &Ring->EvtchnInterface,
> +                                 BlkifRing->Channel,
> +                                 FALSE,
> +                                 TRUE);
> +
>            __BlkifRingReleaseLock(BlkifRing);
>            KeLowerIrql(Irql);
>
>            if (!Retry)
>                break;
>        }
> -
> -    XENBUS_EVTCHN(Unmask,
> -                  &Ring->EvtchnInterface,
> -                  BlkifRing->Channel,
> -                  FALSE,
> -                  TRUE);
>    }
>
>    #define TIME_US(_us)        ((_us) * 10)
> --
>
>>
>> ________________________________________
>> From: Tu Dinh <ngoc-tu.dinh@vates.tech>
>> Sent: 27 March 2026 9:33 AM
>> To: win-pv-devel@lists.xenproject.org
>> Cc: Tu Dinh; Owen Smith
>> Subject: [RFC PATCH] Call EvtchnUnmask within the BlkifRing lock
>>
>> The call to EvtchnUnmask accesses Channel outside of the blkif ring
>> lock. Therefore, it can access a stale channel if the DPC is still
>> running after the channel has been closed in BlkifRingDisconnect. Since
>> BlkifRingDisconnect runs at DISPATCH_LEVEL, we cannot use
>> KeFlushQueuedDpcs and have to guard against the event channel's closure
>> via the Enabled flag instead.
>>
>> Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
>> ---
>>
>> Notes:
>>        This issue is reliably reproducible by repeatedly suspending/resu=
ming or
>>        migrating a VM, which at some point will cause it to lock up when=
 trying
>>        to acquire a lock on the event channel. The failure will typicall=
y
>>        happen within 100 resume cycles. Note the corrupted event channel=
 below:
>>
>>            nt!KeBugCheckEx:
>>            fffff803`e3f3ad20 48894c2408      mov     qword ptr [rsp+8],r=
cx ss:0018:fffff803`79b9eb50=3D0000000000000080
>>            0: kd> kP
>>             # Child-SP          RetAddr               Call Site
>>            00 fffff803`79b9eb48 fffff803`e3f832e2     nt!KeBugCheckEx
>>            01 fffff803`79b9eb50 fffff803`e3f7d8d9     nt!HalpNMIHalt+0x2=
e
>>            02 fffff803`79b9eb90 fffff803`750a129b     nt!HalBugCheckSyst=
em+0x69
>>            03 fffff803`79b9ebd0 fffff803`e411f632     PSHED!PshedBugChec=
kSystem+0xb
>>            04 fffff803`79b9ec00 fffff803`e3f830bb     nt!WheaReportHwErr=
or+0x2b5752
>>            05 fffff803`79b9ecc0 fffff803`e3ff6daf     nt!HalHandleNMI+0x=
14b
>>            06 fffff803`79b9ecf0 fffff803`e40eeac2     nt!KiProcessNMI+0x=
ff
>>            07 fffff803`79b9ed30 fffff803`e40ee82e     nt!KxNmiInterrupt+=
0x82
>>            08 fffff803`79b9ee70 fffff803`e3c94e6c     nt!KiNmiInterrupt+=
0x26e
>>            09 ffff9600`a38a7640 fffff803`e3c94d5e     nt!KxWaitForSpinLo=
ckAndAcquire+0x1c
>>            0a ffff9600`a38a7670 fffff803`e4064a62     nt!KeAcquireSpinLo=
ckRaiseToDpc+0x5e
>>            0b ffff9600`a38a76a0 fffff803`e45df368     nt!DifKeAcquireSpi=
nLockRaiseToDpcWrapper+0xd2
>>            0c ffff9600`a38a76f0 fffff803`761f59ea     nt!VerifierKeAcqui=
reSpinLockRaiseToDpc+0x28
>>            0d ffff9600`a38a7720 fffff803`78a1dcd0     xenbus!EvtchnUnmas=
k(
>>                        struct _INTERFACE * Interface =3D <Value unavaila=
ble error>,
>>                        struct _XENBUS_EVTCHN_CHANNEL * Channel =3D 0xfff=
fbe01`a45fcf80,
>>                        unsigned char InUpcall =3D 0x00 '',
>>                        unsigned char Force =3D 0x01 '')+0x3a [xenbus\src=
\xenbus\evtchn.c @ 824]
>>            0e ffff9600`a38a7760 fffff803`e3c95b42     xenvbd!BlkifRingDp=
c(
>>                        struct _KDPC * Dpc =3D 0xfffff803`74b29a00,
>>                        void * Context =3D 0xffffbe01`a4116e50,
>>                        void * Argument1 =3D 0x00000000`00000000,
>>                        void * Argument2 =3D 0x00000000`00000000)+0x3c0 [=
xenvbd\src\xenvbd\ring.c @ 1627]
>>            0f ffff9600`a38a77d0 fffff803`e4006592     nt!KiExecuteAllDpc=
s+0x692
>>            10 ffff9600`a38a7a10 fffff803`e3ec7dca     nt!KiExecuteDpc+0x=
c2
>>            11 ffff9600`a38a7bf0 fffff803`e40e3c74     nt!PspSystemThread=
Startup+0x5a
>>            12 ffff9600`a38a7c40 00000000`00000000     nt!KiStartSystemTh=
read+0x34
>>            0: kd> dx -id 0,0,ffffbe019f6f5040 -r1 ((xenbus!_XENBUS_EVTCH=
N_CHANNEL *)0xffffbe01a45fcf80)
>>            ((xenbus!_XENBUS_EVTCHN_CHANNEL *)0xffffbe01a45fcf80)        =
         : 0xffffbe01a45fcf80 [Type: _XENBUS_EVTCHN_CHANNEL *]
>>                [+0x000] Magic            : 0x28 [Type: unsigned long]
>>                [+0x008] Lock             : 0xffffffff [Type: unsigned __=
int64]
>>                [+0x010] ListEntry        [Type: _LIST_ENTRY]
>>                [+0x020] PendingListEntry [Type: _LIST_ENTRY]
>>                [+0x030] Pending          : -1542361520 [Type: long]
>>                [+0x038] Caller           : 0xffffbe01a4cb9010 [Type: voi=
d *]
>>                [+0x040] Callback         : 0xffffbe01a4cb9010 : 0xffffbe=
01a4cb9010 [Type: unsigned char (__cdecl*)(_KINTERRUPT *,void *)]
>>                [+0x048] Argument         : 0xffffbe01a4cb9010 [Type: voi=
d *]
>>                [+0x050] Active           : 0x65 [Type: unsigned char]
>>                [+0x054] Count            : 0x0 [Type: unsigned long]
>>                [+0x058] Type             : -1527206080 [Type: _XENBUS_EV=
TCHN_TYPE]
>>                [+0x05c] Parameters       [Type: _XENBUS_EVTCHN_PARAMETER=
S]
>>                [+0x064] Mask             : 0x1 [Type: unsigned char]
>>                [+0x068] LocalPort        : 0x1 [Type: unsigned long]
>>                [+0x06c] Cpu              : 0x0 [Type: unsigned long]
>>                [+0x070] Closed           : 0x2f [Type: unsigned char]
>>
>>        Xencons may benefit from the same change.
>>
>>        This patch will probably hurt performance in some way, but callin=
g
>>        EvtchnUnmask within the lock is needed to ensure that the channel=
 is
>>        alive.
>>
>>        Xencons tries to fix this problem by skipping the unmask call whe=
n the
>>        ring is not enabled, but Enabled could have gone stale by the tim=
e it
>>        has reached the unmask, and so KeFlushQueuedDpcs is still needed =
to
>>        chase out any running DPCs before closing the channel.
>>
>>        It might be possible to fix this by signaling the end of each DPC=
 with
>>        an atomic, then synchronize with that in RingDisconnect, but I ha=
ven't
>>        investigated whether that'd help performance.
>>
>>     src/xenvbd/ring.c | 22 +++++++++++++++-------
>>     1 file changed, 15 insertions(+), 7 deletions(-)
>>
>> diff --git a/src/xenvbd/ring.c b/src/xenvbd/ring.c
>> index 50f8d58..409d6ab 100644
>> --- a/src/xenvbd/ring.c
>> +++ b/src/xenvbd/ring.c
>> @@ -1611,19 +1611,27 @@ BlkifRingDpc(
>>
>>             KeRaiseIrql(DISPATCH_LEVEL, &Irql);
>>             __BlkifRingAcquireLock(BlkifRing);
>> -        Retry =3D BlkifRingPoll(BlkifRing);
>> +
>> +        if (BlkifRing->Enabled) {
>> +            Retry =3D BlkifRingPoll(BlkifRing);
>> +
>> +            if (!Retry) {
>> +                (VOID) XENBUS_EVTCHN(Unmask,
>> +                                     &Ring->EvtchnInterface,
>> +                                     BlkifRing->Channel,
>> +                                     FALSE,
>> +                                     TRUE);
>> +            }
>> +        } else {
>> +            Retry =3D FALSE;
>> +        }
>> +
>>             __BlkifRingReleaseLock(BlkifRing);
>>             KeLowerIrql(Irql);
>>
>>             if (!Retry)
>>                 break;
>>         }
>> -
>> -    XENBUS_EVTCHN(Unmask,
>> -                  &Ring->EvtchnInterface,
>> -                  BlkifRing->Channel,
>> -                  FALSE,
>> -                  TRUE);
>>     }
>>
>>     #define TIME_US(_us)        ((_us) * 10)
>> --
>> 2.53.0.windows.2
>>
>>
>>
>> --
>> Ngoc Tu Dinh | Vates XCP-ng Developer
>>
>> XCP-ng & Xen Orchestra - Vates solutions
>>
>> web: https://vates.tech
>>
>
>
>
> --
> Ngoc Tu Dinh | Vates XCP-ng Developer
>
> XCP-ng & Xen Orchestra - Vates solutions
>
> web: https://vates.tech
>
>
>



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech




From win-pv-devel-bounces@lists.xenproject.org Mon Mar 30 08:31:55 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Mon, 30 Mar 2026 08:31:55 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1267324.1556838 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1w782M-00089X-46; Mon, 30 Mar 2026 08:31:54 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1267324.1556838; Mon, 30 Mar 2026 08:31:54 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1w782M-00089Q-1f; Mon, 30 Mar 2026 08:31:54 +0000
Received: by outflank-mailman (input) for mailman id 1267324;
 Mon, 30 Mar 2026 08:31:53 +0000
Received: from mx.expurgate.net ([195.190.135.10])
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <bounce-md_30504962.69ca34f5.v1-5472ba63bfd943199e23f9d25babfcba@bounce.vates.tech>)
 id 1w782K-00089K-SH
 for win-pv-devel@lists.xenproject.org; Mon, 30 Mar 2026 08:31:53 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1w782J-002dnV-K1
 for win-pv-devel@lists.xenproject.org; Mon, 30 Mar 2026 10:31:51 +0200
Received: from [10.42.69.7] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from
 <bounce-md_30504962.69ca34f5.v1-5472ba63bfd943199e23f9d25babfcba@bounce.vates.tech>)
 id 69ca34ea-bab6-0a2a0a5309dd-0a2a4507ee04-48
 for <win-pv-devel@lists.xenproject.org>; Mon, 30 Mar 2026 10:31:51 +0200
Received: from [198.2.132.14] (helo=mail132-14.atl131.mandrillapp.com)
 by tlsNG-ef75cf.mxtls.expurgate.net with ESMTPS (eXpurgate 4.55.2)
 (envelope-from
 <bounce-md_30504962.69ca34f5.v1-5472ba63bfd943199e23f9d25babfcba@bounce.vates.tech>)
 id 69ca34f6-fd74-0a2a45070019-c602840e0585-3
 for <win-pv-devel@lists.xenproject.org>; Mon, 30 Mar 2026 10:31:51 +0200
Received: from pmta09.mandrill.prod.atl01.rsglab.com (localhost [127.0.0.1])
 by mail132-14.atl131.mandrillapp.com (Mailchimp) with ESMTP id
 4fkkxf09Zvz8XS0V2
 for <win-pv-devel@lists.xenproject.org>; Mon, 30 Mar 2026 08:31:50 +0000 (GMT)
Received: from [37.26.189.201] by mandrillapp.com id
 5472ba63bfd943199e23f9d25babfcba; Mon, 30 Mar 2026 08:31:49 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=mte1 header.d=mandrillapp.com header.i="@mandrillapp.com" header.h="From:Subject:To:Cc:Message-Id:Feedback-ID:Date:MIME-Version:Content-Type:Content-Transfer-Encoding"; dkim=pass header.s=mte1 header.d=vates.tech header.i="ngoc-tu.dinh@vates.tech" header.h="From:Subject:To:Cc:Message-Id:Feedback-ID:Date:MIME-Version:Content-Type:Content-Transfer-Encoding"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com;
	s=mte1; t=1774859510; x=1775129510;
	bh=/SpUDi5nMvk9TzY2tE/uM7GrunCoKQfKFDBffj2EPIE=;
	h=From:Subject:To:Cc:Message-Id:Feedback-ID:Date:MIME-Version:
	 Content-Type:Content-Transfer-Encoding:CC:Date:Subject:From;
	b=i5t+nDffYC5vwMU/ItsVHo9dwm9Y3XnQ17S497UDQ9FnE0PE5OYbqtb+KR5t8ea0W
	 SJwnL5dGnBWr/WVx7ywSGmR1Z99zLcTpBysHNW0TtBWjl0TaruYilajU7T50FelJSZ
	 zjEdfPZ4ratCPMjfN4t1n1QYEg5OQjsMlSEQ4V0NgFTX5G60e98YlCye+ACe7BjKFn
	 5DSwhYwYV2QHb+rmUJ0wKSF2cOjyihTXiPP3AlbOkkZFL9MGi4aCPW4Za7DIf5OAHF
	 MQcF2LQg+sHhQfL362BjOsK4pvAScXaM81uU2DpzFgQV6s6a/U7Eqi1FQHioRz+MFD
	 eyzeam4WAAuZw==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1;
	t=1774859510; x=1775120010; i=ngoc-tu.dinh@vates.tech;
	bh=/SpUDi5nMvk9TzY2tE/uM7GrunCoKQfKFDBffj2EPIE=;
	h=From:Subject:To:Cc:Message-Id:Feedback-ID:Date:MIME-Version:
	 Content-Type:Content-Transfer-Encoding:CC:Date:Subject:From;
	b=A/xAG4mu9M0ZIQa2P3qN0GHIWDnks+fbt5w7PfzsyK2DWODDF+hiY4pVDfD7G27JO
	 CkQXQwhsd5pwDZTy+7OUa2oQhZQbUh3BtElqNAHrLIGcDqT6gG7NZMck4nFzCvm5yH
	 qOz95l7yc4BIMKgVUdPrDRNmBngVRfIc8CmKd+FE/UMC9TGMNyQIAn7aVGo48T3M+j
	 hXVHh8v9SXIhvJvJf2HFUvA6i0uLVD504uJiGQuInFIMjWqdsVz+s7dmt/AiCX+JEn
	 fIQhnItQ3cBw0sdOxIsUHqDXoZTj2msKeZCQk7MzGFPT9sSOtWM6f8QA4bAECy6o5a
	 ILW+QSFLW5LUA==
From: "Tu Dinh" <ngoc-tu.dinh@vates.tech>
Subject: =?utf-8?Q?[PATCH]=20Add=20missing=20return=20type=20for=20=5F=5FTransmitterGet/PutNetBufferList?=
X-Mailer: git-send-email 2.53.0.windows.2
X-Bm-Disclaimer: Yes
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1774859509134
To: win-pv-devel@lists.xenproject.org
Cc: "Tu Dinh" <ngoc-tu.dinh@vates.tech>, "Owen Smith" <owen.smith@cloud.com>
Message-Id: <20260330083145.217-1-ngoc-tu.dinh@vates.tech>
X-Native-Encoded: 1
X-Report-Abuse: =?UTF-8?Q?Please=20forward=20a=20copy=20of=20this=20message,=20including=20all=20headers,=20to=20abuse@mandrill.com.=20You=20can=20also=20report=20abuse=20here:=20https://mandrillapp.com/contact/abuse=3Fid=3D30504962.5472ba63bfd943199e23f9d25babfcba?=
X-Mandrill-User: md_30504962
Feedback-ID: 30504962:30504962.20260330:md
Date: Mon, 30 Mar 2026 08:31:49 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit
X-purgate-ID: tlsNG-ef75cf/1774859511-4F0A8303-3C04A9E9/0/0
X-purgate-type: clean
X-purgate-size: 972

Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
---
 src/xennet/transmitter.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/xennet/transmitter.c b/src/xennet/transmitter.c
index 5507a1a..4bb82bc 100644
--- a/src/xennet/transmitter.c
+++ b/src/xennet/transmitter.c
@@ -123,6 +123,7 @@ __TransmitterCompleteNetBufferList(
                                     NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);
 }
 
+static VOID
 __TransmitterGetNetBufferList(
     IN  PXENNET_TRANSMITTER     Transmitter,
     IN  PNET_BUFFER_LIST        NetBufferList
@@ -138,6 +139,7 @@ __TransmitterGetNetBufferList(
         ListReserved->Status = NDIS_STATUS_PENDING;
 }
 
+static VOID
 __TransmitterPutNetBufferList(
     IN  PXENNET_TRANSMITTER     Transmitter,
     IN  PNET_BUFFER_LIST        NetBufferList
-- 
2.53.0.windows.2



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Mon Mar 30 08:32:33 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Mon, 30 Mar 2026 08:32:33 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1267325.1556843 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1w782z-0008ER-6t; Mon, 30 Mar 2026 08:32:33 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1267325.1556843; Mon, 30 Mar 2026 08:32:33 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1w782z-0008EK-4B; Mon, 30 Mar 2026 08:32:33 +0000
Received: by outflank-mailman (input) for mailman id 1267325;
 Mon, 30 Mar 2026 08:32:31 +0000
Received: from mx.expurgate.net ([195.190.135.10])
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <bounce-md_30504962.69ca351d.v1-04f24423ac7e463ba0d13f540bc0f6f1@bounce.vates.tech>)
 id 1w782x-0008EE-GO
 for win-pv-devel@lists.xenproject.org; Mon, 30 Mar 2026 08:32:31 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1w782w-007DkT-Rt
 for win-pv-devel@lists.xenproject.org; Mon, 30 Mar 2026 10:32:30 +0200
Received: from [10.42.69.5] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from
 <bounce-md_30504962.69ca351d.v1-04f24423ac7e463ba0d13f540bc0f6f1@bounce.vates.tech>)
 id 69ca351c-2eae-0a2a0a5409dd-0a2a4505b1a2-14
 for <win-pv-devel@lists.xenproject.org>; Mon, 30 Mar 2026 10:32:30 +0200
Received: from [198.2.132.14] (helo=mail132-14.atl131.mandrillapp.com)
 by tlsNG-c201ff.mxtls.expurgate.net with ESMTPS (eXpurgate 4.55.2)
 (envelope-from
 <bounce-md_30504962.69ca351d.v1-04f24423ac7e463ba0d13f540bc0f6f1@bounce.vates.tech>)
 id 69ca351d-5aeb-0a2a45050019-c602840e66d7-3
 for <win-pv-devel@lists.xenproject.org>; Mon, 30 Mar 2026 10:32:30 +0200
Received: from pmta09.mandrill.prod.atl01.rsglab.com (localhost [127.0.0.1])
 by mail132-14.atl131.mandrillapp.com (Mailchimp) with ESMTP id
 4fkkyP2ygsz8XS0V6
 for <win-pv-devel@lists.xenproject.org>; Mon, 30 Mar 2026 08:32:29 +0000 (GMT)
Received: from [37.26.189.201] by mandrillapp.com id
 04f24423ac7e463ba0d13f540bc0f6f1; Mon, 30 Mar 2026 08:32:29 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=mte1 header.d=mandrillapp.com header.i="@mandrillapp.com" header.h="From:Subject:To:Cc:Message-Id:Feedback-ID:Date:MIME-Version:Content-Type:Content-Transfer-Encoding"; dkim=pass header.s=mte1 header.d=vates.tech header.i="ngoc-tu.dinh@vates.tech" header.h="From:Subject:To:Cc:Message-Id:Feedback-ID:Date:MIME-Version:Content-Type:Content-Transfer-Encoding"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com;
	s=mte1; t=1774859549; x=1775129549;
	bh=EoM8TflkK9wX8YewbHSmtDIb8xlEEVCO5VIRrrAqLFQ=;
	h=From:Subject:To:Cc:Message-Id:Feedback-ID:Date:MIME-Version:
	 Content-Type:Content-Transfer-Encoding:CC:Date:Subject:From;
	b=yXHtpNlGzU2+T4rE3PTSZRC10Z1tA68tSwte8wA/a36psOWuVNgY/7xG8wTGTfXDl
	 DKRLfzhdkT7G+NsRIsmkLwHKUkxdTHmDSduRPREEp1ns+ibiLGZmxHUE992It5mtQv
	 KYmiRB0qHIGEZYvAdvF1Z1C60V53ewrkVnFJ1he+OtIWTfMq12uf6eT0dyHiAo4euL
	 JiDzQiCTv8Moje6GhFg1py1ZxHo/MNHt/ZfPQyY6X8dUSooNa/gMI3iVcl/lsh4Yn4
	 bWeatS3KLNNDxALv8REsCEpdUefHaZNqmo5nfRuemWEU88HnizkxGTE3TyTzjjb2C2
	 BWDx4JK/whX+w==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1;
	t=1774859549; x=1775120049; i=ngoc-tu.dinh@vates.tech;
	bh=EoM8TflkK9wX8YewbHSmtDIb8xlEEVCO5VIRrrAqLFQ=;
	h=From:Subject:To:Cc:Message-Id:Feedback-ID:Date:MIME-Version:
	 Content-Type:Content-Transfer-Encoding:CC:Date:Subject:From;
	b=h7JjoZDZZcgmbCMuCT/lIpnn+3sQu9gsg1l7UOPCOwUSxrP0+fyGiPgT0dF0dXeve
	 qfqBs5Qa5FW0h5bF0+cgUFMt8o3dm/WxWkCcCB2kUAkXXSCkUZYzW6AQ0Iec7nYWJb
	 FLe0foZId6wLco6XdQb0yDJtMGbL2Nqld9ByC6JMNKG2v6vgLOUNBhT4sHSL1sJRio
	 bgl+Dp7IkmGOqPUR1RGj6dSPa/F1n2KRGruXE1Sqkfqx7hN6g5veMAq/MqFmvQ4SwW
	 tTqhJIoK1K3kI7kNh31QWBH78kYJbhBSuWKik4hNswvX1O10wzLGQBLozkqPZEMXTz
	 pT3xPvL8AcjZQ==
From: "Tu Dinh" <ngoc-tu.dinh@vates.tech>
Subject: =?utf-8?Q?[PATCH=20v2]=20Call=20EvtchnUnmask=20within=20the=20BlkifRing=20lock?=
X-Mailer: git-send-email 2.53.0.windows.2
X-Bm-Disclaimer: Yes
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1774859548628
To: win-pv-devel@lists.xenproject.org
Cc: "Tu Dinh" <ngoc-tu.dinh@vates.tech>, "Owen Smith" <owen.smith@citrix.com>
Message-Id: <20260330083227.1353-1-ngoc-tu.dinh@vates.tech>
X-Native-Encoded: 1
X-Report-Abuse: =?UTF-8?Q?Please=20forward=20a=20copy=20of=20this=20message,=20including=20all=20headers,=20to=20abuse@mandrill.com.=20You=20can=20also=20report=20abuse=20here:=20https://mandrillapp.com/contact/abuse=3Fid=3D30504962.04f24423ac7e463ba0d13f540bc0f6f1?=
X-Mandrill-User: md_30504962
Feedback-ID: 30504962:30504962.20260330:md
Date: Mon, 30 Mar 2026 08:32:29 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit
X-purgate-ID: tlsNG-c201ff/1774859550-22685488-4616F64A/0/0
X-purgate-type: clean
X-purgate-size: 1688

The call to EvtchnUnmask accesses Channel outside of the blkif ring
lock. Therefore, it can access a stale channel if the DPC is still
running after the channel has been closed in BlkifRingDisconnect. Since
BlkifRingDisconnect runs at DISPATCH_LEVEL, we cannot use
KeFlushQueuedDpcs and have to guard against the event channel's closure
via the Enabled flag instead.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
---
v2: Invert the check conditions before calling EvtchnUnmask
---
 src/xenvbd/ring.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/src/xenvbd/ring.c b/src/xenvbd/ring.c
index 50f8d58..af8a2fc 100644
--- a/src/xenvbd/ring.c
+++ b/src/xenvbd/ring.c
@@ -1612,18 +1612,21 @@ BlkifRingDpc(
         KeRaiseIrql(DISPATCH_LEVEL, &Irql);
         __BlkifRingAcquireLock(BlkifRing);
         Retry = BlkifRingPoll(BlkifRing);
+
+        if (!Retry && BlkifRing->Enabled) {
+            (VOID) XENBUS_EVTCHN(Unmask,
+                                 &Ring->EvtchnInterface,
+                                 BlkifRing->Channel,
+                                 FALSE,
+                                 TRUE);
+        }
+
         __BlkifRingReleaseLock(BlkifRing);
         KeLowerIrql(Irql);

         if (!Retry)
             break;
     }
-
-    XENBUS_EVTCHN(Unmask,
-                  &Ring->EvtchnInterface,
-                  BlkifRing->Channel,
-                  FALSE,
-                  TRUE);
 }

 #define TIME_US(_us)        ((_us) * 10)
--
2.53.0.windows.2


--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



From win-pv-devel-bounces@lists.xenproject.org Mon Mar 30 08:33:08 2026
Return-path: <win-pv-devel-bounces@lists.xenproject.org>
Envelope-to: archives@lists.xenproject.org
Delivery-date: Mon, 30 Mar 2026 08:33:08 +0000
Received: from list by lists.xenproject.org with outflank-mailman.1267328.1556847 (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1w783Y-0008Hw-9q; Mon, 30 Mar 2026 08:33:08 +0000
X-Outflank-Mailman: Message body and most headers restored to incoming version
Received: by outflank-mailman (output) from mailman id 1267328.1556847; Mon, 30 Mar 2026 08:33:08 +0000
Received: from localhost ([127.0.0.1] helo=lists.xenproject.org)
	by lists.xenproject.org with esmtp (Exim 4.92)
	(envelope-from <win-pv-devel-bounces@lists.xenproject.org>)
	id 1w783Y-0008Hp-74; Mon, 30 Mar 2026 08:33:08 +0000
Received: by outflank-mailman (input) for mailman id 1267328;
 Mon, 30 Mar 2026 08:33:06 +0000
Received: from mx.expurgate.net ([195.190.135.10])
 by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from
 <bounce-md_30504962.69ca3540.v1-b9a5e83c573d442b8ce13ac3ef0b1d10@bounce.vates.tech>)
 id 1w783W-0008HH-JN
 for win-pv-devel@lists.xenproject.org; Mon, 30 Mar 2026 08:33:06 +0000
Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp
 id 1w783V-00EJq3-VQ
 for win-pv-devel@lists.xenproject.org; Mon, 30 Mar 2026 10:33:05 +0200
Received: from [10.42.69.9] (helo=localhost)
 by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from
 <bounce-md_30504962.69ca3540.v1-b9a5e83c573d442b8ce13ac3ef0b1d10@bounce.vates.tech>)
 id 69ca3541-5cb7-0a2a0a5109dd-0a2a450988fe-4
 for <win-pv-devel@lists.xenproject.org>; Mon, 30 Mar 2026 10:33:05 +0200
Received: from [198.2.132.14] (helo=mail132-14.atl131.mandrillapp.com)
 by tlsNG-bad1c0.mxtls.expurgate.net with ESMTPS (eXpurgate 4.55.2)
 (envelope-from
 <bounce-md_30504962.69ca3540.v1-b9a5e83c573d442b8ce13ac3ef0b1d10@bounce.vates.tech>)
 id 69ca3540-e484-0a2a45090019-c602840e0c97-3
 for <win-pv-devel@lists.xenproject.org>; Mon, 30 Mar 2026 10:33:05 +0200
Received: from pmta09.mandrill.prod.atl01.rsglab.com (localhost [127.0.0.1])
 by mail132-14.atl131.mandrillapp.com (Mailchimp) with ESMTP id
 4fkkz43h2Nz8XS0Tw
 for <win-pv-devel@lists.xenproject.org>; Mon, 30 Mar 2026 08:33:04 +0000 (GMT)
Received: from [37.26.189.201] by mandrillapp.com id
 b9a5e83c573d442b8ce13ac3ef0b1d10; Mon, 30 Mar 2026 08:33:04 +0000
X-BeenThere: win-pv-devel@lists.xenproject.org
List-Id: Developer list for the Windows PV Drivers subproject
 <win-pv-devel.lists.xenproject.org>
List-Unsubscribe: <https://lists.xenproject.org/mailman/options/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=unsubscribe>
List-Post: <mailto:win-pv-devel@lists.xenproject.org>
List-Help: <mailto:win-pv-devel-request@lists.xenproject.org?subject=help>
List-Subscribe: <https://lists.xenproject.org/mailman/listinfo/win-pv-devel>, 
 <mailto:win-pv-devel-request@lists.xenproject.org?subject=subscribe>
Errors-To: win-pv-devel-bounces@lists.xenproject.org
Precedence: list
Sender: "win-pv-devel" <win-pv-devel-bounces@lists.xenproject.org>
Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=mte1 header.d=mandrillapp.com header.i="@mandrillapp.com" header.h="From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID:Date:MIME-Version:Content-Type:Content-Transfer-Encoding"; dkim=pass header.s=mte1 header.d=vates.tech header.i="ngoc-tu.dinh@vates.tech" header.h="From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID:Date:MIME-Version:Content-Type:Content-Transfer-Encoding"
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com;
	s=mte1; t=1774859584; x=1775129584;
	bh=H9FJ9EH0m6MuoP633UPTGhfISoSyxSb0DECQLKNOLqI=;
	h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=IEOcG+Mz0XI0ShjZFHANuIAUycKKF/9Nkse+btkJdXmW+hQRlknqWU5bw3/9d9tnd
	 Pz9KKp4hL35mEnLaAcWoMqmzYRtzNe12ZHim9EpBZ1p3lx3EQD6QJ81EqVQUZz4KNc
	 Pojzon0RWMGCtnsQwtXWPNcAYZ05rbQ5OLiGueRi8MqplbtPNJxPpTeB7my6RE8mac
	 8qqZX12Guk4d8CRm1DLVgRsmwDfpvheKDLH75ajZFyZxz9oLw28jKXvwxg1Z/5lgV0
	 y4yx/czxaQeWwyV8heDAoEqa1cg1FeCyBrrdDAVkCy7lF6PdRFAQzzX4FQoLbGEqLA
	 xhx1Rqe2t2aoA==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1;
	t=1774859584; x=1775120084; i=ngoc-tu.dinh@vates.tech;
	bh=H9FJ9EH0m6MuoP633UPTGhfISoSyxSb0DECQLKNOLqI=;
	h=From:Subject:To:Cc:Message-Id:In-Reply-To:References:Feedback-ID:
	 Date:MIME-Version:Content-Type:Content-Transfer-Encoding:CC:Date:
	 Subject:From;
	b=a1P2ijODZAzNCIWsDZV2BxjMqUWG6LiJaWUI6OyptiOhh7K8oqceCZkl/A9KhHUQG
	 AZyMJXS9zQKlf2Eh+/8Z/qQ3dHpCSXzasehmNBcS5AC0NcmzvwM2ZZ8y9jQzPLURua
	 L824A57niWUAuoGr4M384WgkDp3INgFW8TARcukE8xwfyA5PYQSzaFd7CUBEgUHsdP
	 haWQSUmO06dnGRLQDww/NlUurbJuBVDk03UdNLMpqf4WRahOjgBFNPpQGhG5qpTy/7
	 kXhmkNlt7tH8ka/dPULfRgArnombV0g3znPE4teR4mj/Ul9lhtfbNhr+hgvk30dQuz
	 i0/GSN9IHeVQA==
From: "Tu Dinh" <ngoc-tu.dinh@vates.tech>
Subject: =?utf-8?Q?[PATCH=20v2]=20Call=20RingPoll/EvtchnUnmask=20within=20the=20ring=20lock?=
X-Mailer: git-send-email 2.53.0.windows.2
X-Bm-Disclaimer: Yes
X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2
X-Bm-Transport-Timestamp: 1774859583768
To: win-pv-devel@lists.xenproject.org
Cc: "Tu Dinh" <ngoc-tu.dinh@vates.tech>, "Owen Smith" <owen.smith@citrix.com>
Message-Id: <20260330083300.472-1-ngoc-tu.dinh@vates.tech>
In-Reply-To: <20260330083227.1353-1-ngoc-tu.dinh@vates.tech>
References: <20260330083227.1353-1-ngoc-tu.dinh@vates.tech>
X-Native-Encoded: 1
X-Report-Abuse: =?UTF-8?Q?Please=20forward=20a=20copy=20of=20this=20message,=20including=20all=20headers,=20to=20abuse@mandrill.com.=20You=20can=20also=20report=20abuse=20here:=20https://mandrillapp.com/contact/abuse=3Fid=3D30504962.b9a5e83c573d442b8ce13ac3ef0b1d10?=
X-Mandrill-User: md_30504962
Feedback-ID: 30504962:30504962.20260330:md
Date: Mon, 30 Mar 2026 08:33:04 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit
X-purgate-ID: tlsNG-bad1c0/1774859585-608BDA73-45A9080B/0/0
X-purgate-type: clean
X-purgate-size: 2435

The call to EvtchnUnmask accesses Channel outside of the ring lock.
Therefore, it can access a stale channel if the DPC is still running
after the channel has been closed in RingDisconnect. Since
RingDisconnect runs at DISPATCH_LEVEL, we cannot use KeFlushQueuedDpcs
and have to guard against the event channel's closure via the Enabled
flag instead.

Note that RingPoll is now also called within the ring lock, since it's
also vulnerable to teardown of the shared ring area. It also gains a
check to Ring->Enabled following the structure of XenVbd.

Signed-off-by: Tu Dinh <ngoc-tu.dinh@vates.tech>
---
v2: Invert conditions. Call RingPoll within the lock too. Add a check
    for Ring->Enabled in RingPoll.
---
 src/xencons/ring.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/src/xencons/ring.c b/src/xencons/ring.c
index afa9311..866dc74 100644
--- a/src/xencons/ring.c
+++ b/src/xencons/ring.c
@@ -471,6 +471,9 @@ RingPoll(
     PCHAR               Buffer;
     NTSTATUS            status;

+    if (!Ring->Enabled)
+        return FALSE;
+
     for (;;) {
         ULONG           Read;

@@ -567,30 +570,25 @@ RingDpc(
     ASSERT(Ring != NULL);

     for (;;) {
-        BOOLEAN Enabled;
         BOOLEAN Retry;
         KIRQL   Irql;

         KeAcquireSpinLock(&Ring->Lock, &Irql);
-        Enabled = Ring->Enabled;
-        KeReleaseSpinLock(&Ring->Lock, Irql);
+        Retry = RingPoll(Ring);

-        if (!Enabled)
-            break;
+        if (!Retry && Ring->Enabled) {
+            (VOID) XENBUS_EVTCHN(Unmask,
+                                 &Ring->EvtchnInterface,
+                                 Ring->Channel,
+                                 FALSE,
+                                 FALSE);
+        }

-        KeRaiseIrql(DISPATCH_LEVEL, &Irql);
-        Retry = RingPoll(Ring);
-        KeLowerIrql(Irql);
+        KeReleaseSpinLock(&Ring->Lock, Irql);

         if (!Retry)
             break;
     }
-
-    (VOID) XENBUS_EVTCHN(Unmask,
-                         &Ring->EvtchnInterface,
-                         Ring->Channel,
-                         FALSE,
-                         FALSE);
 }

 _Function_class_(KSERVICE_ROUTINE)
--
2.53.0.windows.2


--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



