https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c92bec609b5acd2dc1ff17344a3ed5549d92f65d

commit c92bec609b5acd2dc1ff17344a3ed5549d92f65d
Author:     Dmitry Borisov <[email protected]>
AuthorDate: Thu Mar 4 18:44:20 2021 +0600
Commit:     Dmitry Borisov <[email protected]>
CommitDate: Sun Jun 20 19:22:32 2021 +0600

    [ISAPNP] Refactor string handling
    
    - Don't allocate string buffers twice.
---
 drivers/bus/isapnp/isapnp.c | 159 +---------------------------------
 drivers/bus/isapnp/isapnp.h |  14 ---
 drivers/bus/isapnp/pdo.c    | 202 +++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 182 insertions(+), 193 deletions(-)

diff --git a/drivers/bus/isapnp/isapnp.c b/drivers/bus/isapnp/isapnp.c
index 8342e191d69..d5aea3de39e 100644
--- a/drivers/bus/isapnp/isapnp.c
+++ b/drivers/bus/isapnp/isapnp.c
@@ -11,132 +11,6 @@
 #define NDEBUG
 #include <debug.h>
 
-NTSTATUS
-NTAPI
-IsaPnpDuplicateUnicodeString(
-    IN ULONG Flags,
-    IN PCUNICODE_STRING SourceString,
-    OUT PUNICODE_STRING DestinationString)
-{
-    if (SourceString == NULL ||
-        DestinationString == NULL ||
-        SourceString->Length > SourceString->MaximumLength ||
-        (SourceString->Length == 0 && SourceString->MaximumLength > 0 && 
SourceString->Buffer == NULL) ||
-        Flags == RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING ||
-        Flags >= 4)
-    {
-        return STATUS_INVALID_PARAMETER;
-    }
-
-    if ((SourceString->Length == 0) &&
-        (Flags != (RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE |
-                   RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING)))
-    {
-        DestinationString->Length = 0;
-        DestinationString->MaximumLength = 0;
-        DestinationString->Buffer = NULL;
-    }
-    else
-    {
-        USHORT DestMaxLength = SourceString->Length;
-
-        if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
-            DestMaxLength += sizeof(UNICODE_NULL);
-
-        DestinationString->Buffer = ExAllocatePool(PagedPool, DestMaxLength);
-        if (DestinationString->Buffer == NULL)
-            return STATUS_NO_MEMORY;
-
-        RtlCopyMemory(DestinationString->Buffer, SourceString->Buffer, 
SourceString->Length);
-        DestinationString->Length = SourceString->Length;
-        DestinationString->MaximumLength = DestMaxLength;
-
-        if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
-            DestinationString->Buffer[DestinationString->Length / 
sizeof(WCHAR)] = 0;
-    }
-
-    return STATUS_SUCCESS;
-}
-
-static
-NTSTATUS
-NTAPI
-IsaFdoCreateDeviceIDs(
-    IN PISAPNP_PDO_EXTENSION PdoExt)
-{
-    PISAPNP_LOGICAL_DEVICE LogDev = PdoExt->IsaPnpDevice;
-    UNICODE_STRING TempString;
-    WCHAR TempBuffer[256];
-    PWCHAR End;
-    NTSTATUS Status;
-    USHORT i;
-
-    TempString.Buffer = TempBuffer;
-    TempString.MaximumLength = sizeof(TempBuffer);
-    TempString.Length = 0;
-
-    /* Device ID */
-    Status = RtlStringCbPrintfExW(TempString.Buffer,
-                                  TempString.MaximumLength / sizeof(WCHAR),
-                                  &End,
-                                  NULL, 0,
-                                  L"ISAPNP\\%.3S%04x",
-                                  LogDev->VendorId,
-                                  LogDev->ProdId);
-    if (!NT_SUCCESS(Status))
-        return Status;
-    TempString.Length = (USHORT)((End - TempString.Buffer) * sizeof(WCHAR));
-    Status = IsaPnpDuplicateUnicodeString(
-        RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
-        &TempString,
-        &PdoExt->DeviceID);
-    if (!NT_SUCCESS(Status))
-        return Status;
-
-    /* HardwareIDs */
-    Status = RtlStringCbPrintfExW(TempString.Buffer,
-                                  TempString.MaximumLength / sizeof(WCHAR),
-                                  &End,
-                                  NULL, 0,
-                                  L"ISAPNP\\%.3S%04x@"
-                                  L"*%.3S%04x@",
-                                  LogDev->VendorId,
-                                  LogDev->ProdId,
-                                  LogDev->VendorId,
-                                  LogDev->ProdId);
-    if (!NT_SUCCESS(Status))
-        return Status;
-    TempString.Length = (USHORT)((End - TempString.Buffer) * sizeof(WCHAR));
-    Status = IsaPnpDuplicateUnicodeString(
-        RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
-        &TempString,
-        &PdoExt->HardwareIDs);
-    if (!NT_SUCCESS(Status))
-        return Status;
-    for (i = 0; i < PdoExt->HardwareIDs.Length / sizeof(WCHAR); i++)
-        if (PdoExt->HardwareIDs.Buffer[i] == '@')
-            PdoExt->HardwareIDs.Buffer[i] = UNICODE_NULL;
-
-    /* InstanceID */
-    Status = RtlStringCbPrintfExW(TempString.Buffer,
-                                  TempString.MaximumLength / sizeof(WCHAR),
-                                  &End,
-                                  NULL, 0,
-                                  L"%X",
-                                  LogDev->SerialNumber);
-    if (!NT_SUCCESS(Status))
-        return Status;
-    TempString.Length = (USHORT)((End - TempString.Buffer) * sizeof(WCHAR));
-    Status = IsaPnpDuplicateUnicodeString(
-        RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
-        &TempString,
-        &PdoExt->InstanceID);
-    if (!NT_SUCCESS(Status))
-        return Status;
-
-    return STATUS_SUCCESS;
-}
-
 static
 CODE_SEG("PAGE")
 NTSTATUS
@@ -487,10 +361,7 @@ IsaPnpFillDeviceRelations(
             PdoExt->IsaPnpDevice = IsaDevice;
             PdoExt->FdoExt = FdoExt;
 
-            Status = IsaFdoCreateDeviceIDs(PdoExt);
-
-            if (NT_SUCCESS(Status))
-                Status = IsaPnpCreateLogicalDeviceRequirements(PdoExt);
+            Status = IsaPnpCreateLogicalDeviceRequirements(PdoExt);
 
             if (NT_SUCCESS(Status))
                 Status = IsaPnpCreateLogicalDeviceResources(PdoExt);
@@ -728,10 +599,6 @@ NTSTATUS
 IsaPnpCreateReadPortDO(
     _In_ PISAPNP_FDO_EXTENSION FdoExt)
 {
-    UNICODE_STRING DeviceID = RTL_CONSTANT_STRING(L"ISAPNP\\ReadDataPort\0");
-    UNICODE_STRING HardwareIDs = 
RTL_CONSTANT_STRING(L"ISAPNP\\ReadDataPort\0\0");
-    UNICODE_STRING CompatibleIDs = RTL_CONSTANT_STRING(L"\0\0");
-    UNICODE_STRING InstanceID = RTL_CONSTANT_STRING(L"0\0");
     PISAPNP_PDO_EXTENSION PdoExt;
     NTSTATUS Status;
 
@@ -754,30 +621,6 @@ IsaPnpCreateReadPortDO(
     PdoExt->Common.State = dsStopped;
     PdoExt->FdoExt = FdoExt;
 
-    Status = IsaPnpDuplicateUnicodeString(0,
-                                          &DeviceID,
-                                          &PdoExt->DeviceID);
-    if (!NT_SUCCESS(Status))
-        return Status;
-
-    Status = IsaPnpDuplicateUnicodeString(0,
-                                          &HardwareIDs,
-                                          &PdoExt->HardwareIDs);
-    if (!NT_SUCCESS(Status))
-        return Status;
-
-    Status = IsaPnpDuplicateUnicodeString(0,
-                                          &CompatibleIDs,
-                                          &PdoExt->CompatibleIDs);
-    if (!NT_SUCCESS(Status))
-        return Status;
-
-    Status = IsaPnpDuplicateUnicodeString(0,
-                                          &InstanceID,
-                                          &PdoExt->InstanceID);
-    if (!NT_SUCCESS(Status))
-        return Status;
-
     Status = IsaPnpCreateReadPortDORequirements(PdoExt);
     if (!NT_SUCCESS(Status))
         return Status;
diff --git a/drivers/bus/isapnp/isapnp.h b/drivers/bus/isapnp/isapnp.h
index 8e872a0e506..d22037bbb90 100644
--- a/drivers/bus/isapnp/isapnp.h
+++ b/drivers/bus/isapnp/isapnp.h
@@ -85,10 +85,6 @@ typedef struct _ISAPNP_PDO_EXTENSION
     ISAPNP_COMMON_EXTENSION Common;
     PISAPNP_LOGICAL_DEVICE IsaPnpDevice;
     PISAPNP_FDO_EXTENSION FdoExt;
-    UNICODE_STRING DeviceID;
-    UNICODE_STRING HardwareIDs;
-    UNICODE_STRING CompatibleIDs;
-    UNICODE_STRING InstanceID;
     PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
     PCM_RESOURCE_LIST ResourceList;
     ULONG ResourceListSize;
@@ -115,16 +111,6 @@ IsaPnpReleaseDeviceDataLock(
 
 /* isapnp.c */
 
-#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE         1
-#define RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING   2
-
-NTSTATUS
-NTAPI
-IsaPnpDuplicateUnicodeString(
-    IN ULONG Flags,
-    IN PCUNICODE_STRING SourceString,
-    OUT PUNICODE_STRING DestinationString);
-
 CODE_SEG("PAGE")
 NTSTATUS
 IsaPnpFillDeviceRelations(
diff --git a/drivers/bus/isapnp/pdo.c b/drivers/bus/isapnp/pdo.c
index 402f62609cd..3e2256b4b68 100644
--- a/drivers/bus/isapnp/pdo.c
+++ b/drivers/bus/isapnp/pdo.c
@@ -103,47 +103,204 @@ IsaPdoQueryId(
     _Inout_ PIRP Irp,
     _In_ PIO_STACK_LOCATION IrpSp)
 {
-    PUNICODE_STRING Source;
-    PWCHAR Buffer;
+    PISAPNP_LOGICAL_DEVICE LogDev = PdoExt->IsaPnpDevice;
+    NTSTATUS Status;
+    PWCHAR Buffer, End, IdStart;
+    size_t CharCount, Remaining;
 
     PAGED_CODE();
 
     switch (IrpSp->Parameters.QueryId.IdType)
     {
         case BusQueryDeviceID:
-            DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
-            Source = &PdoExt->DeviceID;
+        {
+            CharCount = sizeof("ISAPNP\\XXXFFFF");
+
+            Buffer = ExAllocatePoolWithTag(PagedPool,
+                                           CharCount * sizeof(WCHAR),
+                                           TAG_ISAPNP);
+            if (!Buffer)
+                return STATUS_INSUFFICIENT_RESOURCES;
+
+            Status = RtlStringCchPrintfExW(Buffer,
+                                           CharCount,
+                                           &End,
+                                           &Remaining,
+                                           0,
+                                           L"ISAPNP\\%.3S%04x",
+                                           LogDev->VendorId,
+                                           LogDev->ProdId);
+            if (!NT_VERIFY(NT_SUCCESS(Status)))
+                goto Failure;
+
+            DPRINT("Device ID: '%S'\n", Buffer);
             break;
+        }
 
         case BusQueryHardwareIDs:
-            DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
-            Source = &PdoExt->HardwareIDs;
+        {
+            CharCount = sizeof("ISAPNP\\XXXFFFF") +
+                        sizeof("*PNPxxxx") +
+                        sizeof(ANSI_NULL); /* multi-string */
+
+            Buffer = ExAllocatePoolWithTag(PagedPool,
+                                           CharCount * sizeof(WCHAR),
+                                           TAG_ISAPNP);
+            if (!Buffer)
+                return STATUS_INSUFFICIENT_RESOURCES;
+
+            DPRINT("Hardware IDs:\n");
+
+            /* 1 */
+            Status = RtlStringCchPrintfExW(Buffer,
+                                           CharCount,
+                                           &End,
+                                           &Remaining,
+                                           0,
+                                           L"ISAPNP\\%.3S%04x",
+                                           LogDev->VendorId,
+                                           LogDev->ProdId);
+            if (!NT_VERIFY(NT_SUCCESS(Status)))
+                goto Failure;
+
+            DPRINT("  '%S'\n", Buffer);
+
+            ++End;
+            --Remaining;
+
+            /* 2 */
+            IdStart = End;
+            Status = RtlStringCchPrintfExW(End,
+                                           Remaining,
+                                           &End,
+                                           &Remaining,
+                                           0,
+                                           L"*%.3S%04x",
+                                           LogDev->VendorId,
+                                           LogDev->ProdId);
+            if (!NT_VERIFY(NT_SUCCESS(Status)))
+                goto Failure;
+
+            DPRINT("  '%S'\n", IdStart);
+
+            *++End = UNICODE_NULL;
+            --Remaining;
+
             break;
+        }
 
         case BusQueryCompatibleIDs:
-            DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
-            Source = &PdoExt->CompatibleIDs;
-            break;
+            return STATUS_NOT_IMPLEMENTED;
 
         case BusQueryInstanceID:
-            DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
-            Source = &PdoExt->InstanceID;
+        {
+            CharCount = sizeof(LogDev->SerialNumber) * 2 + sizeof(ANSI_NULL);
+
+            Buffer = ExAllocatePoolWithTag(PagedPool,
+                                           CharCount * sizeof(WCHAR),
+                                           TAG_ISAPNP);
+            if (!Buffer)
+                return STATUS_INSUFFICIENT_RESOURCES;
+
+            Status = RtlStringCchPrintfExW(Buffer,
+                                           CharCount,
+                                           NULL,
+                                           NULL,
+                                           0,
+                                           L"%X",
+                                           LogDev->SerialNumber);
+            if (!NT_VERIFY(NT_SUCCESS(Status)))
+                goto Failure;
+
+            DPRINT("Instance ID: '%S'\n", Buffer);
             break;
+        }
 
         default:
-          DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 
0x%lx\n",
-                  IrpSp->Parameters.QueryId.IdType);
-          return Irp->IoStatus.Status;
+            return Irp->IoStatus.Status;
     }
 
-    if (!Source->Buffer)
-        return Irp->IoStatus.Status;
+    Irp->IoStatus.Information = (ULONG_PTR)Buffer;
+    return STATUS_SUCCESS;
 
-    Buffer = ExAllocatePoolWithTag(PagedPool, Source->MaximumLength, 
TAG_ISAPNP);
-    if (!Buffer)
-        return STATUS_NO_MEMORY;
+Failure:
+    ExFreePoolWithTag(Buffer, TAG_ISAPNP);
+
+    return Status;
+}
+
+static
+CODE_SEG("PAGE")
+NTSTATUS
+IsaReadPortQueryId(
+    _Inout_ PIRP Irp,
+    _In_ PIO_STACK_LOCATION IrpSp)
+{
+    PWCHAR Buffer;
+    static const WCHAR ReadPortId[] = L"ISAPNP\\ReadDataPort";
+
+    PAGED_CODE();
+
+    switch (IrpSp->Parameters.QueryId.IdType)
+    {
+        case BusQueryDeviceID:
+        {
+            Buffer = ExAllocatePoolWithTag(PagedPool, sizeof(ReadPortId), 
TAG_ISAPNP);
+            if (!Buffer)
+                return STATUS_INSUFFICIENT_RESOURCES;
+
+            RtlCopyMemory(Buffer, ReadPortId, sizeof(ReadPortId));
+
+            DPRINT("Device ID: '%S'\n", Buffer);
+            break;
+        }
+
+        case BusQueryHardwareIDs:
+        {
+            Buffer = ExAllocatePoolWithTag(PagedPool,
+                                           sizeof(ReadPortId) + 
sizeof(UNICODE_NULL),
+                                           TAG_ISAPNP);
+            if (!Buffer)
+                return STATUS_INSUFFICIENT_RESOURCES;
+
+            RtlCopyMemory(Buffer, ReadPortId, sizeof(ReadPortId));
+
+            Buffer[sizeof(ReadPortId) / sizeof(WCHAR)] = UNICODE_NULL; /* 
multi-string */
+
+            DPRINT("Hardware ID: '%S'\n", Buffer);
+            break;
+        }
+
+        case BusQueryCompatibleIDs:
+        {
+            /* Empty multi-string */
+            Buffer = ExAllocatePoolZero(PagedPool, sizeof(UNICODE_NULL) * 2, 
TAG_ISAPNP);
+            if (!Buffer)
+                return STATUS_INSUFFICIENT_RESOURCES;
+
+            DPRINT("Compatible ID: '%S'\n", Buffer);
+            break;
+        }
+
+        case BusQueryInstanceID:
+        {
+            /* Even if there are multiple ISA buses, the driver has only one 
Read Port */
+            static const WCHAR InstanceId[] = L"0";
+
+            Buffer = ExAllocatePoolWithTag(PagedPool, sizeof(InstanceId), 
TAG_ISAPNP);
+            if (!Buffer)
+                return STATUS_INSUFFICIENT_RESOURCES;
+
+            RtlCopyMemory(Buffer, InstanceId, sizeof(InstanceId));
+
+            DPRINT("Instance ID: '%S'\n", Buffer);
+            break;
+        }
+
+        default:
+            return Irp->IoStatus.Status;
+    }
 
-    RtlCopyMemory(Buffer, Source->Buffer, Source->MaximumLength);
     Irp->IoStatus.Information = (ULONG_PTR)Buffer;
     return STATUS_SUCCESS;
 }
@@ -378,7 +535,10 @@ IsaPdoPnp(
             break;
 
         case IRP_MN_QUERY_ID:
-            Status = IsaPdoQueryId(PdoExt, Irp, IrpSp);
+            if (PdoExt->IsaPnpDevice)
+                Status = IsaPdoQueryId(PdoExt, Irp, IrpSp);
+            else
+                Status = IsaReadPortQueryId(Irp, IrpSp);
             break;
 
         case IRP_MN_QUERY_REMOVE_DEVICE:

Reply via email to