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

[PATCH 02/11] registry: sync with xenbus


  • To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Césaire Mounah <cesaire.mounah@xxxxxxxxxx>
  • Date: Mon, 19 Oct 2026 15:14:28 +0200
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=vates.tech header.i="@vates.tech" header.h="From:Subject:Date:Message-ID:To:Cc:MIME-Version:Content-Type:In-Reply-To:References:Feedback-ID"
  • Cc: Césaire Mounah <cesaire.mounah@xxxxxxxxxx>
  • Delivery-date: Mon, 19 Oct 2026 13:14:58 +0000
  • Feedback-id: default:8631fc262581453bbf619ec5b2062170:Sweego
  • List-id: Developer list for the Windows PV Drivers subproject <win-pv-devel.lists.xenproject.org>

Sync registry.c,h with xenbus latest version.

Signed-off-by: Césaire Mounah <cesaire.mounah@xxxxxxxxxx>
---
 src/xenvkbd/registry.c | 282 ++++++++++++++++++++++++++++++-----------
 src/xenvkbd/registry.h |   8 +-
 2 files changed, 212 insertions(+), 78 deletions(-)

diff --git a/src/xenvkbd/registry.c b/src/xenvkbd/registry.c
index e498497..90a2bbe 100644
--- a/src/xenvkbd/registry.c
+++ b/src/xenvkbd/registry.c
@@ -1,32 +1,32 @@
 /* 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 
+ *
+ * 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.
  */
 
@@ -38,8 +38,13 @@
 
 #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
@@ -82,11 +87,63 @@ RegistryTeardown(
     VOID
     )
 {
+    __IoOpenDriverRegistryKey = NULL;
+
+    RegistryDriverObject = NULL;
+
     RtlFreeUnicodeString(&RegistryPath);
     RegistryPath.Buffer = NULL;
     RegistryPath.MaximumLength = RegistryPath.Length = 0;
 }
 
+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
 RegistryOpenKey(
     IN  HANDLE          Parent,
@@ -118,15 +175,15 @@ fail1:
 
 static NTSTATUS
 RegistryOpenRoot(
-    IN  PWCHAR          Path,
-    OUT PHANDLE         Parent,
-    OUT PWCHAR          *ChildPath
+    _In_ PWSTR              Path,
+    _Out_ PHANDLE           Parent,
+    _Outptr_result_z_ PWSTR *ChildPath
     )
 {
-    const WCHAR         Prefix[] = L"\\Registry\\Machine\\";
-    ULONG               Length;
-    UNICODE_STRING      Unicode;
-    NTSTATUS            status;
+    PCWSTR                  Prefix = L"\\Registry\\Machine\\";
+    ULONG                   Length;
+    UNICODE_STRING          Unicode;
+    NTSTATUS                status;
 
     Length = (ULONG)wcslen(Prefix);
 
@@ -157,11 +214,11 @@ RegistryCreateKey(
     OUT PHANDLE         Key
     )
 {
-    PWCHAR              Buffer;
+    PWSTR               Buffer;
     HANDLE              Root;
-    PWCHAR              ChildPath;
-    PWCHAR              ChildName;
-    PWCHAR              Context;
+    PWSTR               ChildPath;
+    PWSTR               ChildName;
+    PWSTR               Context;
     HANDLE              Child;
     NTSTATUS            status;
 
@@ -260,7 +317,7 @@ RegistryOpenServiceKey(
 
 NTSTATUS
 RegistryCreateServiceKey(
-    OUT PHANDLE         Key
+    _Out_ PHANDLE       Key
     )
 {
     return RegistryCreateKey(NULL, &RegistryPath, REG_OPTION_NON_VOLATILE, 
Key);
@@ -298,7 +355,7 @@ RegistryOpenHardwareKey(
     HANDLE                  SubKey;
     ULONG                   Length;
     PKEY_NAME_INFORMATION   Info;
-    PWCHAR                  Cursor;
+    PWSTR                   Cursor;
     UNICODE_STRING          Unicode;
     NTSTATUS                status;
 
@@ -315,11 +372,11 @@ RegistryOpenHardwareKey(
                         NULL,
                         0,
                         &Length);
-    if (status != STATUS_BUFFER_OVERFLOW &&
+    if (!NT_SUCCESS(status) &&
+        status != STATUS_BUFFER_OVERFLOW &&
         status != STATUS_BUFFER_TOO_SMALL)
         goto fail2;
 
-#pragma prefast(suppress:6102)
     Info = __RegistryAllocate(Length + sizeof (WCHAR));
 
     status = STATUS_NO_MEMORY;
@@ -340,7 +397,7 @@ RegistryOpenHardwareKey(
     ASSERT(Cursor != NULL);
 
     *Cursor = L'\0';
-    
+
     RtlInitUnicodeString(&Unicode, Info->Name);
 
     status = RegistryOpenKey(NULL, &Unicode, DesiredAccess, Key);
@@ -367,10 +424,10 @@ fail1:
 
 NTSTATUS
 RegistryOpenSubKey(
-    IN  PHANDLE         Key,
-    IN  PCHAR           Name,
-    IN  ACCESS_MASK     DesiredAccess,
-    OUT PHANDLE         SubKey
+    _In_opt_ PHANDLE    Key,
+    _In_ PSTR           Name,
+    _In_ ACCESS_MASK    DesiredAccess,
+    _Out_ PHANDLE       SubKey
     )
 {
     ANSI_STRING         Ansi;
@@ -400,10 +457,10 @@ fail1:
 
 NTSTATUS
 RegistryCreateSubKey(
-    IN  PHANDLE         Key,
-    IN  PCHAR           Name,
-    IN  ULONG           Options,
-    OUT PHANDLE         SubKey
+    _In_opt_ HANDLE     Key,
+    _In_ PSTR           Name,
+    _In_ ULONG          Options,
+    _Out_ PHANDLE       SubKey
     )
 {
     ANSI_STRING         Ansi;
@@ -494,7 +551,6 @@ RegistryEnumerateSubKeys(
         status != STATUS_BUFFER_TOO_SMALL)
         goto fail1;
 
-#pragma prefast(suppress:6102)
     Full = __RegistryAllocate(Size);
 
     status = STATUS_NO_MEMORY;
@@ -545,7 +601,7 @@ RegistryEnumerateSubKeys(
         status = RtlUnicodeStringToAnsiString(&Ansi, &Unicode, FALSE);
         ASSERT(NT_SUCCESS(status));
 
-        Ansi.Length = (USHORT)(strlen(Ansi.Buffer) * sizeof (CHAR));        
+        Ansi.Length = (USHORT)(strlen(Ansi.Buffer) * sizeof (CHAR));
 
         status = Callback(Context, Key, &Ansi);
 
@@ -570,7 +626,7 @@ fail5:
 fail4:
 fail3:
     __RegistryFree(Full);
-    
+
 fail2:
 fail1:
     return status;
@@ -598,7 +654,6 @@ RegistryEnumerateValues(
         status != STATUS_BUFFER_TOO_SMALL)
         goto fail1;
 
-#pragma prefast(suppress:6102)
     Full = __RegistryAllocate(Size);
 
     status = STATUS_NO_MEMORY;
@@ -642,17 +697,24 @@ RegistryEnumerateValues(
         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));
+        if (!NT_SUCCESS(status)) {
+            __RegistryFree(Ansi.Buffer);
+            goto fail7;
+        }
 
-        Ansi.Length = (USHORT)(strlen(Ansi.Buffer) * sizeof (CHAR));        
+        Ansi.Length = (USHORT)(strlen(Ansi.Buffer) * sizeof (CHAR));
 
         status = Callback(Context, Key, &Ansi, Basic->Type);
 
         __RegistryFree(Ansi.Buffer);
 
         if (!NT_SUCCESS(status))
-            goto fail6;
+            goto fail8;
     }
 
     __RegistryFree(Basic);
@@ -661,6 +723,8 @@ RegistryEnumerateValues(
 
     return STATUS_SUCCESS;
 
+fail8:
+fail7:
 fail6:
 fail5:
     __RegistryFree(Basic);
@@ -668,7 +732,7 @@ fail5:
 fail4:
 fail3:
     __RegistryFree(Full);
-    
+
 fail2:
 fail1:
     return status;
@@ -723,18 +787,18 @@ RegistryQueryDwordValue(
     status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
     if (!NT_SUCCESS(status))
         goto fail1;
-        
+
     status = ZwQueryValueKey(Key,
                              &Unicode,
                              KeyValuePartialInformation,
                              NULL,
                              0,
                              &Size);
-    if (status != STATUS_BUFFER_OVERFLOW &&
+    if (!NT_SUCCESS(status) &&
+        status != STATUS_BUFFER_OVERFLOW &&
         status != STATUS_BUFFER_TOO_SMALL)
         goto fail2;
 
-#pragma prefast(suppress:6102)
     Partial = __RegistryAllocate(Size);
 
     status = STATUS_NO_MEMORY;
@@ -755,7 +819,77 @@ RegistryQueryDwordValue(
         Partial->DataLength != sizeof (ULONG))
         goto fail5;
 
-    *Value = *(PULONG)Partial->Data;            
+    *Value = *(PULONG)Partial->Data;
+
+    __RegistryFree(Partial);
+
+    RtlFreeUnicodeString(&Unicode);
+
+    return STATUS_SUCCESS;
+
+fail5:
+fail4:
+    __RegistryFree(Partial);
+
+fail3:
+fail2:
+    RtlFreeUnicodeString(&Unicode);
+
+fail1:
+    return status;
+}
+
+NTSTATUS
+RegistryQueryQwordValue(
+    _In_ HANDLE                     Key,
+    _In_ PSTR                       Name,
+    _Out_ PULONGLONG                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 (!NT_SUCCESS(status) &&
+        status != STATUS_BUFFER_OVERFLOW &&
+        status != STATUS_BUFFER_TOO_SMALL)
+        goto fail2;
+
+    Partial = __RegistryAllocate(Size);
+
+    status = STATUS_NO_MEMORY;
+    if (Partial == NULL)
+        goto fail3;
+
+    status = ZwQueryValueKey(Key,
+                             &Unicode,
+                             KeyValuePartialInformation,
+                             Partial,
+                             Size,
+                             &Size);
+    if (!NT_SUCCESS(status))
+        goto fail4;
+
+    status = STATUS_INVALID_PARAMETER;
+    if (Partial->Type != REG_QWORD ||
+        Partial->DataLength != sizeof (ULONGLONG))
+        goto fail5;
+
+    *Value = *(PULONGLONG)Partial->Data;
 
     __RegistryFree(Partial);
 
@@ -792,7 +926,7 @@ RegistryUpdateDwordValue(
     status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
     if (!NT_SUCCESS(status))
         goto fail1;
-        
+
     Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, 
Data) +
                                  sizeof (ULONG));
 
@@ -803,7 +937,7 @@ RegistryUpdateDwordValue(
     Partial->TitleIndex = 0;
     Partial->Type = REG_DWORD;
     Partial->DataLength = sizeof (ULONG);
-    *(PULONG)Partial->Data = Value;            
+    *(PULONG)Partial->Data = Value;
 
     status = ZwSetValueKey(Key,
                            &Unicode,
@@ -951,18 +1085,18 @@ RegistryQuerySzValue(
     status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
     if (!NT_SUCCESS(status))
         goto fail1;
-        
+
     status = ZwQueryValueKey(Key,
                              &Unicode,
                              KeyValuePartialInformation,
                              NULL,
                              0,
                              &Size);
-    if (status != STATUS_BUFFER_OVERFLOW &&
+    if (!NT_SUCCESS(status) &&
+        status != STATUS_BUFFER_OVERFLOW &&
         status != STATUS_BUFFER_TOO_SMALL)
         goto fail2;
 
-#pragma prefast(suppress:6102)
     Value = __RegistryAllocate(Size);
 
     status = STATUS_NO_MEMORY;
@@ -981,12 +1115,12 @@ RegistryQuerySzValue(
     switch (Value->Type) {
     case REG_SZ:
         status = STATUS_NO_MEMORY;
-        *Array = RegistrySzToAnsi((PWCHAR)Value->Data);
+        *Array = RegistrySzToAnsi((PWSTR)Value->Data);
         break;
 
     case REG_MULTI_SZ:
         status = STATUS_NO_MEMORY;
-        *Array = RegistryMultiSzToAnsi((PWCHAR)Value->Data);
+        *Array = RegistryMultiSzToAnsi((PWSTR)Value->Data);
         break;
 
     default:
@@ -1045,11 +1179,11 @@ RegistryQueryBinaryValue(
                              NULL,
                              0,
                              &Size);
-    if (status != STATUS_BUFFER_OVERFLOW &&
+    if (!NT_SUCCESS(status) &&
+        status != STATUS_BUFFER_OVERFLOW &&
         status != STATUS_BUFFER_TOO_SMALL)
         goto fail2;
 
-#pragma prefast(suppress:6102)
     Partial = __RegistryAllocate(Size);
 
     status = STATUS_NO_MEMORY;
@@ -1176,12 +1310,12 @@ RegistryQueryKeyName(
                         NULL,
                         0,
                         &Size);
-    if (status != STATUS_BUFFER_OVERFLOW &&
+    if (!NT_SUCCESS(status) &&
+        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;
@@ -1197,7 +1331,7 @@ RegistryQueryKeyName(
         goto fail3;
 
     Value->Name[Value->NameLength / sizeof (WCHAR)] = L'\0';
-    *Array = RegistrySzToAnsi((PWCHAR)Value->Name);
+    *Array = RegistrySzToAnsi((PWSTR)Value->Name);
 
     status = STATUS_NO_MEMORY;
     if (*Array == NULL)
@@ -1226,12 +1360,12 @@ RegistryQuerySystemStartOption(
     HANDLE                          Key;
     PANSI_STRING                    Ansi;
     ULONG                           Length;
-    PCHAR                           Option;
-    PCHAR                           Context;
+    PSTR                            Option;
+    PSTR                            Context;
     NTSTATUS                        status;
 
     RtlInitUnicodeString(&Unicode, 
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control");
-    
+
     status = RegistryOpenKey(NULL, &Unicode, KEY_READ, &Key);
     if (!NT_SUCCESS(status))
         goto fail1;
diff --git a/src/xenvkbd/registry.h b/src/xenvkbd/registry.h
index 904ff10..08f0def 100644
--- a/src/xenvkbd/registry.h
+++ b/src/xenvkbd/registry.h
@@ -88,10 +88,10 @@ RegistryOpenHardwareKey(
 
 extern NTSTATUS
 RegistryOpenSubKey(
-    IN  HANDLE      Key,
-    IN  PCHAR       Name,
-    IN  ACCESS_MASK DesiredAccess,
-    OUT PHANDLE     SubKey
+    _In_opt_ HANDLE     Key,
+    _In_ PSTR           Name,
+    _In_ ACCESS_MASK    DesiredAccess,
+    _Out_ PHANDLE       SubKey
     );
 
 extern NTSTATUS
-- 
2.55.0.windows.5



--
Césaire Mounah | Vates Windows Guest Tools Engineer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech

 


Rackspace

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