mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[ISAPNP] Create PDO identifiers ahead of IRP_MN_QUERY_ID
This commit is contained in:
parent
89aff07a67
commit
e0607fcebf
3 changed files with 163 additions and 52 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue