va_list va;
ASSERT(IdBuffer->Count < MAX_ANSI_STRINGS);
-
+
/* Do the actual string formatting into the character buffer */
va_start(va, Format);
vsprintf(IdBuffer->CharBuffer, Format, va);
/* Initialize the ANSI_STRING that will hold this string buffer */
AnsiString = &IdBuffer->Strings[IdBuffer->Count];
RtlInitAnsiString(AnsiString, IdBuffer->CharBuffer);
-
+
/* Calculate the final size of the string, in Unicode */
Size = RtlAnsiStringToUnicodeSize(AnsiString);
-
+
/* Update hte buffer with the size,and update the character pointer */
IdBuffer->StringSize[IdBuffer->Count] = Size;
IdBuffer->TotalLength += Size;
Length = AnsiString->Length + sizeof(ANSI_NULL);
IdBuffer->CharBuffer += Length;
-
+
/* Move to the next string for next time */
IdBuffer->Count++;
-
+
/* Return the length */
return Length;
}
va_list va;
ASSERT(IdBuffer->Count);
-
+
/* Choose the next static ANSI_STRING to use */
NextId = IdBuffer->Count - 1;
-
+
/* Max length is from the end of the buffer up until the current pointer */
- MaxLength = (PCHAR)(IdBuffer + 1) - IdBuffer->CharBuffer;
-
+ MaxLength = (PCHAR)(IdBuffer + 1) - IdBuffer->CharBuffer;
+
/* Do the actual append, and return the length this string took */
va_start(va, Format);
Length = vsprintf(IdBuffer->CharBuffer - 1, Format, va);
AnsiString = &IdBuffer->Strings[NextId];
AnsiString->Length += Length;
AnsiString->MaximumLength += Length;
-
+
/* Calculate the final size of the string, in Unicode */
Size = RtlAnsiStringToUnicodeSize(AnsiString);
-
+
/* Update the buffer with the size, and update the character pointer */
IdBuffer->StringSize[NextId] = Size;
IdBuffer->TotalLength += Size;
IdBuffer->CharBuffer += Length;
-
+
/* Return the size */
return Size;
}
UNICODE_STRING DestinationString;
PCI_ID_BUFFER IdBuffer;
PAGED_CODE();
-
+
/* Assume failure */
Status = STATUS_SUCCESS;
*Buffer = NULL;
-
+
/* Start with the genric vendor string, which is the vendor ID + device ID */
sprintf(VendorString,
"PCI\\VEN_%04X&DEV_%04X",
DeviceExtension->VendorId,
DeviceExtension->DeviceId);
-
+
/* Initialize the PCI ID Buffer */
PciInitIdBuffer(&IdBuffer);
-
+
/* Build the subsystem ID as shown in PCI ID Strings */
SubsysId = DeviceExtension->SubsystemVendorId | (DeviceExtension->SubsystemId << 16);
-
+
/* Check what the caller is requesting */
switch (QueryType)
{
case BusQueryDeviceID:
-
+
/* A single ID, the vendor string + the revision ID */
PciIdPrintf(&IdBuffer,
"%s&SUBSYS_%08X&REV_%02X",
SubsysId,
DeviceExtension->RevisionId);
break;
-
+
case BusQueryHardwareIDs:
-
+
/* First the vendor string + the subsystem ID + the revision ID */
PciIdPrintf(&IdBuffer,
"%s&SUBSYS_%08X&REV_%02X",
VendorString,
SubsysId,
DeviceExtension->RevisionId);
-
+
/* Next, without the revision */
PciIdPrintf(&IdBuffer,
"%s&SUBSYS_%08X",
VendorString,
SubsysId);
-
+
/* Next, the vendor string + the base class + sub class + progif */
PciIdPrintf(&IdBuffer,
"%s&CC_%02X%02X%02X",
VendorString,
DeviceExtension->BaseClass,
DeviceExtension->SubClass);
-
+
/* And finally, a terminator */
PciIdPrintf(&IdBuffer, "\0");
break;
-
+
case BusQueryCompatibleIDs:
-
+
/* First, the vendor + revision ID only */
PciIdPrintf(&IdBuffer,
"%s&REV_%02X",
/* Next, the vendor string alone */
PciIdPrintf(&IdBuffer, "%s", VendorString);
-
+
/* Next, the vendor ID + the base class + the sub class + progif */
PciIdPrintf(&IdBuffer,
"PCI\\VEN_%04X&CC_%02X%02X%02X",
"PCI\\CC_%02X%02X",
DeviceExtension->BaseClass,
DeviceExtension->SubClass);
-
+
/* And finally, a terminator */
PciIdPrintf(&IdBuffer, "\0");
break;
-
+
case BusQueryInstanceID:
-
+
/* Start with a terminator */
PciIdPrintf(&IdBuffer, "\0");
-
+
/* And then encode the device and function number */
PciIdPrintfAppend(&IdBuffer,
"%02X",
(DeviceExtension->Slot.u.bits.DeviceNumber << 3) |
DeviceExtension->Slot.u.bits.FunctionNumber);
-
+
/* Loop every parent until the root */
ParentExtension = DeviceExtension->ParentFdoExtension;
while (!PCI_IS_ROOT_FDO(ParentExtension))
PdoExtension->Slot.u.bits.FunctionNumber);
}
break;
-
+
default:
-
+
/* Unknown query type */
DPRINT1("PciQueryId expected ID type = %d\n", QueryType);
return STATUS_NOT_SUPPORTED;
}
-
+
/* Something should've been generated if this has been reached */
ASSERT(IdBuffer.Count > 0);
-
+
/* Allocate the final string buffer to hold the ID */
StringBuffer = ExAllocatePoolWithTag(PagedPool, IdBuffer.TotalLength, 'BicP');
if (!StringBuffer) return STATUS_INSUFFICIENT_RESOURCES;
-
+
/* Build the UNICODE_STRING structure for it */
DPRINT1("PciQueryId(%d)\n", QueryType);
DestinationString.Buffer = StringBuffer;
DestinationString.MaximumLength = IdBuffer.TotalLength;
-
+
/* Loop every ID in the buffer */
for (i = 0; i < IdBuffer.Count; i++)
{
/* Select the ANSI_STRING for the ID */
NextString = &IdBuffer.Strings[i];
DPRINT1(" <- \"%s\"\n", NextString->Buffer);
-
+
/* Convert it to a UNICODE_STRING */
Status = RtlAnsiStringToUnicodeString(&DestinationString, NextString, FALSE);
ASSERT(NT_SUCCESS(Status));
-
+
/* Add it into the final destination buffer */
Size = IdBuffer.StringSize[i];
DestinationString.MaximumLength -= Size;
PWCHAR MessageBuffer, LocationBuffer;
ULONG Length;
NTSTATUS Status;
-
+
UNREFERENCED_PARAMETER(Locale);
/* Check what the caller is requesting */
switch (QueryType)
{
case DeviceTextDescription:
-
+
/* Get the message from the resource section */
MessageBuffer = PciGetDeviceDescriptionMessage(PdoExtension->BaseClass,
PdoExtension->SubClass);
-
+
/* Return it to the caller, and select proper status code */
*Buffer = MessageBuffer;
Status = MessageBuffer ? STATUS_SUCCESS : STATUS_NOT_SUPPORTED;
break;
-
+
case DeviceTextLocationInformation:
-
+
/* Get the message from the resource section */
MessageBuffer = PciGetDescriptionMessage(0x10000, &Length);
if (!MessageBuffer)
Status = STATUS_NOT_SUPPORTED;
break;
}
-
+
/* Add space for a null-terminator, and allocate the buffer */
Length += 2 * sizeof(UNICODE_NULL);
LocationBuffer = ExAllocatePoolWithTag(PagedPool,
Length * sizeof(WCHAR),
'BicP');
*Buffer = LocationBuffer;
-
+
/* Check if the allocation succeeded */
if (LocationBuffer)
{
PdoExtension->Slot.u.bits.FunctionNumber,
PdoExtension->Slot.u.bits.DeviceNumber);
}
-
+
/* Free the original string from the resource section */
ExFreePoolWithTag(MessageBuffer, 0);
-
+
/* Select the correct status */
Status = LocationBuffer ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
break;
-
+
default:
-
+
/* Anything else is unsupported */
Status = STATUS_NOT_SUPPORTED;
break;
}
-
+
/* Return whether or not a device text string was indeed found */
return Status;
}