mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
[ISAPNP] Refactor string handling
- Don't allocate string buffers twice.
This commit is contained in:
parent
70ba96f164
commit
c92bec609b
3 changed files with 182 additions and 193 deletions
|
@ -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;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue