https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e0607fcebf0f93ed2b5be…
commit e0607fcebf0f93ed2b5be062771ca2300cc73196
Author: Hervé Poussineau <hpoussin(a)reactos.org>
AuthorDate: Mon Mar 16 19:00:00 2020 +0100
Commit: Hervé Poussineau <hpoussin(a)reactos.org>
CommitDate: Fri Mar 20 22:40:11 2020 +0100
[ISAPNP] Create PDO identifiers ahead of IRP_MN_QUERY_ID
---
drivers/bus/isapnp/isapnp.c | 134 ++++++++++++++++++++++++++++++++++++++++++++
drivers/bus/isapnp/isapnp.h | 13 +++++
drivers/bus/isapnp/pdo.c | 68 ++++++----------------
3 files changed, 163 insertions(+), 52 deletions(-)
diff --git a/drivers/bus/isapnp/isapnp.c b/drivers/bus/isapnp/isapnp.c
index 6fc29e9e70c..0382f8c843d 100644
--- a/drivers/bus/isapnp/isapnp.c
+++ b/drivers/bus/isapnp/isapnp.c
@@ -10,6 +10,132 @@
#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 = (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 = (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 = (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;
+}
+
NTSTATUS
NTAPI
IsaPnpFillDeviceRelations(
@@ -61,6 +187,14 @@ IsaPnpFillDeviceRelations(
PdoExt->Common.Self = IsaDevice->Pdo;
PdoExt->Common.State = dsStopped;
PdoExt->IsaPnpDevice = IsaDevice;
+
+ Status = IsaFdoCreateDeviceIDs(PdoExt);
+ if (!NT_SUCCESS(Status))
+ {
+ IoDeleteDevice(IsaDevice->Pdo);
+ IsaDevice->Pdo = NULL;
+ break;
+ }
}
DeviceRelations->Objects[i++] = IsaDevice->Pdo;
diff --git a/drivers/bus/isapnp/isapnp.h b/drivers/bus/isapnp/isapnp.h
index e247643112c..3321ff8b9ec 100644
--- a/drivers/bus/isapnp/isapnp.h
+++ b/drivers/bus/isapnp/isapnp.h
@@ -47,10 +47,23 @@ typedef struct _ISAPNP_FDO_EXTENSION {
typedef struct _ISAPNP_PDO_EXTENSION {
ISAPNP_COMMON_EXTENSION Common;
PISAPNP_LOGICAL_DEVICE IsaPnpDevice;
+ UNICODE_STRING DeviceID;
+ UNICODE_STRING HardwareIDs;
+ UNICODE_STRING InstanceID;
} ISAPNP_PDO_EXTENSION, *PISAPNP_PDO_EXTENSION;
/* 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);
+
NTSTATUS
NTAPI
IsaPnpFillDeviceRelations(
diff --git a/drivers/bus/isapnp/pdo.c b/drivers/bus/isapnp/pdo.c
index 4a674a05e0f..78026a3b40a 100644
--- a/drivers/bus/isapnp/pdo.c
+++ b/drivers/bus/isapnp/pdo.c
@@ -62,79 +62,43 @@ IsaPdoQueryId(
IN PIRP Irp,
IN PIO_STACK_LOCATION IrpSp)
{
- PISAPNP_LOGICAL_DEVICE LogDev = PdoExt->IsaPnpDevice;
- WCHAR Temp[256];
- PWCHAR Buffer, End;
- ULONG Length;
- NTSTATUS Status;
+ UNICODE_STRING EmptyString = RTL_CONSTANT_STRING(L"");
+ PUNICODE_STRING Source;
+ PWCHAR Buffer;
switch (IrpSp->Parameters.QueryId.IdType)
{
case BusQueryDeviceID:
- {
DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
- Status = RtlStringCbPrintfExW(Temp, sizeof(Temp),
- &End,
- NULL, 0,
- L"ISAPNP\\%3S%04X",
- LogDev->VendorId,
- LogDev->ProdId);
- if (!NT_SUCCESS(Status))
- return Status;
- Length = End - Temp;
- Temp[Length++] = UNICODE_NULL;
+ Source = &PdoExt->DeviceID;
break;
- }
case BusQueryHardwareIDs:
DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
- Status = RtlStringCbPrintfExW(Temp, sizeof(Temp),
- &End,
- NULL, 0,
- L"ISAPNP\\%3S%04X",
- LogDev->VendorId,
- LogDev->ProdId);
- if (!NT_SUCCESS(Status))
- return Status;
- Length = End - Temp;
- Temp[Length++] = UNICODE_NULL;
- Status = RtlStringCbPrintfExW(Temp + Length, sizeof(Temp) - Length,
- &End,
- NULL, 0,
- L"*%3S%04X",
- LogDev->VendorId,
- LogDev->ProdId);
- if (!NT_SUCCESS(Status))
- return Status;
- Length = End - Temp;
- Temp[Length++] = UNICODE_NULL;
- Temp[Length++] = UNICODE_NULL;
+ Source = &PdoExt->HardwareIDs;
+ break;
+
+ case BusQueryCompatibleIDs:
+ DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
+ Source = &EmptyString;
break;
case BusQueryInstanceID:
DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
- Status = RtlStringCbPrintfExW(Temp, sizeof(Temp),
- &End,
- NULL, 0,
- L"%X",
- LogDev->SerialNumber);
- if (!NT_SUCCESS(Status))
- return Status;
- Length = End - Temp;
- Temp[Length++] = UNICODE_NULL;
+ Source = &PdoExt->InstanceID;
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;
+ DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type
0x%lx\n",
+ IrpSp->Parameters.QueryId.IdType);
+ return Irp->IoStatus.Status;
}
- Buffer = ExAllocatePool(PagedPool, Length * sizeof(WCHAR));
+ Buffer = ExAllocatePool(PagedPool, Source->MaximumLength);
if (!Buffer)
return STATUS_NO_MEMORY;
- RtlCopyMemory(Buffer, Temp, Length * sizeof(WCHAR));
+ RtlCopyMemory(Buffer, Source->Buffer, Source->MaximumLength);
Irp->IoStatus.Information = (ULONG_PTR)Buffer;
return STATUS_SUCCESS;
}