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