https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c92bec609b5acd2dc1ff1…
commit c92bec609b5acd2dc1ff17344a3ed5549d92f65d
Author: Dmitry Borisov <di.sean(a)protonmail.com>
AuthorDate: Thu Mar 4 18:44:20 2021 +0600
Commit: Dmitry Borisov <di.sean(a)protonmail.com>
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: