NT4/private/ntos/nthals/extender/pnpbios/i386/misc.c
2020-09-30 17:12:29 +02:00

472 lines
11 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
misc.c
Abstract:
This file contains pnp bios bus extender support routines.
Author:
Shie-Lin Tzong (shielint) 20-Apr-1995
Environment:
Kernel mode only.
Revision History:
--*/
#include "busp.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE,MbCreateClose)
#pragma alloc_text(PAGE,PbGetRegistryValue)
#pragma alloc_text(PAGE,PbDecompressEisaId)
#endif
NTSTATUS
MbCreateClose (
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp
)
/*++
Routine Description:
This routine handles open and close requests such that our device objects
can be opened. All it does it to complete the Irp with success.
Arguments:
DeviceObject - Supplies a pointer to the device object to be opened or closed.
Irp - supplies a pointer to I/O request packet.
Return Value:
Always returns STATUS_SUCCESS, since this is a null operation.
--*/
{
UNREFERENCED_PARAMETER( DeviceObject );
PAGED_CODE();
//
// Null operation. Do not give an I/O boost since no I/O was
// actually done. IoStatus.Information should be
// FILE_OPENED for an open; it's undefined for a close.
//
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = FILE_OPENED;
IoCompleteRequest( Irp, 0);
return STATUS_SUCCESS;
}
VOID
PbDecompressEisaId(
IN ULONG CompressedId,
IN PUCHAR EisaId
)
/*++
Routine Description:
This routine decompressed compressed Eisa Id and returns the Id to caller
specified character buffer.
Arguments:
CompressedId - supplies the compressed Eisa Id.
EisaId - supplies a 8-char buffer to receive the decompressed Eisa Id.
Return Value:
None.
--*/
{
USHORT c1, c2;
LONG i;
PAGED_CODE();
CompressedId &= 0xffffff7f; // remove the reserved bit (bit 7 of byte 0)
c1 = c2 = (USHORT)CompressedId;
c1 = (c1 & 0xff) << 8;
c2 = (c2 & 0xff00) >> 8;
c1 |= c2;
for (i = 2; i >= 0; i--) {
*(EisaId + i) = (UCHAR)(c1 & 0x1f) + 0x40;
c1 >>= 5;
}
EisaId += 3;
c1 = c2 = (USHORT)(CompressedId >> 16);
c1 = (c1 & 0xff) << 8;
c2 = (c2 & 0xff00) >> 8;
c1 |= c2;
sprintf (EisaId, "%04x", c1);
}
NTSTATUS
PbGetRegistryValue(
IN HANDLE KeyHandle,
IN PWSTR ValueName,
OUT PKEY_VALUE_FULL_INFORMATION *Information
)
/*++
Routine Description:
This routine is invoked to retrieve the data for a registry key's value.
This is done by querying the value of the key with a zero-length buffer
to determine the size of the value, and then allocating a buffer and
actually querying the value into the buffer.
It is the responsibility of the caller to free the buffer.
Arguments:
KeyHandle - Supplies the key handle whose value is to be queried
ValueName - Supplies the null-terminated Unicode name of the value.
Information - Returns a pointer to the allocated data buffer.
Return Value:
The function value is the final status of the query operation.
--*/
{
UNICODE_STRING unicodeString;
NTSTATUS status;
PKEY_VALUE_FULL_INFORMATION infoBuffer;
ULONG keyValueLength;
PAGED_CODE();
RtlInitUnicodeString( &unicodeString, ValueName );
//
// Figure out how big the data value is so that a buffer of the
// appropriate size can be allocated.
//
status = ZwQueryValueKey( KeyHandle,
&unicodeString,
KeyValueFullInformation,
(PVOID) NULL,
0,
&keyValueLength );
if (status != STATUS_BUFFER_OVERFLOW &&
status != STATUS_BUFFER_TOO_SMALL) {
return status;
}
//
// Allocate a buffer large enough to contain the entire key data value.
//
infoBuffer = ExAllocatePool( NonPagedPool, keyValueLength );
if (!infoBuffer) {
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// Query the data for the key value.
//
status = ZwQueryValueKey( KeyHandle,
&unicodeString,
KeyValueFullInformation,
infoBuffer,
keyValueLength,
&keyValueLength );
if (!NT_SUCCESS( status )) {
ExFreePool( infoBuffer );
return status;
}
//
// Everything worked, so simply return the address of the allocated
// buffer to the caller, who is now responsible for freeing it.
//
*Information = infoBuffer;
return STATUS_SUCCESS;
}
#if DBG
VOID
PbDebugPrint (
ULONG Level,
PCCHAR DebugMessage,
...
)
/*++
Routine Description:
This routine displays debugging message or causes a break.
Arguments:
Level - supplies debugging levelcode. DEBUG_MESSAGE - displays message only.
DEBUG_BREAK - displays message and break.
DebugMessage - supplies a pointer to the debugging message.
Return Value:
None.
--*/
{
UCHAR Buffer[256];
va_list ap;
va_start(ap, DebugMessage);
vsprintf(Buffer, DebugMessage, ap);
DbgPrint(Buffer);
if (Level == DEBUG_BREAK) {
DbgBreakPoint();
}
va_end(ap);
}
VOID
MbpDumpIoResourceDescriptor (
IN PUCHAR Indent,
IN PIO_RESOURCE_DESCRIPTOR Desc
)
/*++
Routine Description:
This routine processes a IO_RESOURCE_DESCRIPTOR and displays it.
Arguments:
Indent - # char of indentation.
Desc - supplies a pointer to the IO_RESOURCE_DESCRIPTOR to be displayed.
Return Value:
None.
--*/
{
UCHAR c = ' ';
if (Desc->Option == IO_RESOURCE_ALTERNATIVE) {
c = 'A';
} else if (Desc->Option == IO_RESOURCE_PREFERRED) {
c = 'P';
}
switch (Desc->Type) {
case CmResourceTypePort:
DbgPrint ("%sIO %c Min: %x:%08x, Max: %x:%08x, Algn: %x, Len %x\n",
Indent, c,
Desc->u.Port.MinimumAddress.HighPart, Desc->u.Port.MinimumAddress.LowPart,
Desc->u.Port.MaximumAddress.HighPart, Desc->u.Port.MaximumAddress.LowPart,
Desc->u.Port.Alignment,
Desc->u.Port.Length
);
break;
case CmResourceTypeMemory:
DbgPrint ("%sMEM %c Min: %x:%08x, Max: %x:%08x, Algn: %x, Len %x\n",
Indent, c,
Desc->u.Memory.MinimumAddress.HighPart, Desc->u.Memory.MinimumAddress.LowPart,
Desc->u.Memory.MaximumAddress.HighPart, Desc->u.Memory.MaximumAddress.LowPart,
Desc->u.Memory.Alignment,
Desc->u.Memory.Length
);
break;
case CmResourceTypeInterrupt:
DbgPrint ("%sINT %c Min: %x, Max: %x\n",
Indent, c,
Desc->u.Interrupt.MinimumVector,
Desc->u.Interrupt.MaximumVector
);
break;
case CmResourceTypeDma:
DbgPrint ("%sDMA %c Min: %x, Max: %x\n",
Indent, c,
Desc->u.Dma.MinimumChannel,
Desc->u.Dma.MaximumChannel
);
break;
}
}
VOID
MbpDumpIoResourceList (
IN PIO_RESOURCE_REQUIREMENTS_LIST IoList
)
/*++
Routine Description:
This routine displays Io resource requirements list.
Arguments:
IoList - supplies a pointer to the Io resource requirements list to be displayed.
Return Value:
None.
--*/
{
PIO_RESOURCE_LIST resList;
PIO_RESOURCE_DESCRIPTOR resDesc;
ULONG listCount, count, i, j;
DbgPrint("Pnp Bios IO Resource Requirements List for Slot %x -\n", IoList->SlotNumber);
DbgPrint(" List Count = %x, Bus Number = %x\n", IoList->AlternativeLists, IoList->BusNumber);
listCount = IoList->AlternativeLists;
resList = &IoList->List[0];
for (i = 0; i < listCount; i++) {
DbgPrint(" Version = %x, Revision = %x, Desc count = %x\n", resList->Version,
resList->Revision, resList->Count);
resDesc = &resList->Descriptors[0];
count = resList->Count;
for (j = 0; j < count; j++) {
MbpDumpIoResourceDescriptor(" ", resDesc);
resDesc++;
}
resList = (PIO_RESOURCE_LIST) resDesc;
}
}
VOID
MbpDumpCmResourceDescriptor (
IN PUCHAR Indent,
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Desc
)
/*++
Routine Description:
This routine processes a IO_RESOURCE_DESCRIPTOR and displays it.
Arguments:
Indent - # char of indentation.
Desc - supplies a pointer to the IO_RESOURCE_DESCRIPTOR to be displayed.
Return Value:
None.
--*/
{
switch (Desc->Type) {
case CmResourceTypePort:
DbgPrint ("%sIO Start: %x:%08x, Length: %x\n",
Indent,
Desc->u.Port.Start.HighPart, Desc->u.Port.Start.LowPart,
Desc->u.Port.Length
);
break;
case CmResourceTypeMemory:
DbgPrint ("%sMEM Start: %x:%08x, Length: %x\n",
Indent,
Desc->u.Memory.Start.HighPart, Desc->u.Memory.Start.LowPart,
Desc->u.Memory.Length
);
break;
case CmResourceTypeInterrupt:
DbgPrint ("%sINT Level: %x, Vector: %x, Affinity: %x\n",
Indent,
Desc->u.Interrupt.Level,
Desc->u.Interrupt.Vector,
Desc->u.Interrupt.Affinity
);
break;
case CmResourceTypeDma:
DbgPrint ("%sDMA Channel: %x, Port: %x\n",
Indent,
Desc->u.Dma.Channel,
Desc->u.Dma.Port
);
break;
}
}
VOID
MbpDumpCmResourceList (
IN PCM_RESOURCE_LIST CmList,
IN ULONG SlotNumber
)
/*++
Routine Description:
This routine displays CM resource list.
Arguments:
CmList - supplies a pointer to CM resource list
SlotNumber - slot number of the resources
Return Value:
None.
--*/
{
PCM_FULL_RESOURCE_DESCRIPTOR fullDesc;
PCM_PARTIAL_RESOURCE_LIST partialDesc;
PCM_PARTIAL_RESOURCE_DESCRIPTOR desc;
ULONG count, i;
fullDesc = &CmList->List[0];
DbgPrint("Pnp Bios Cm Resource List for Slot %x -\n", SlotNumber);
DbgPrint(" List Count = %x, Bus Number = %x\n", CmList->Count, fullDesc->BusNumber);
partialDesc = &fullDesc->PartialResourceList;
DbgPrint(" Version = %x, Revision = %x, Desc count = %x\n", partialDesc->Version,
partialDesc->Revision, partialDesc->Count);
count = partialDesc->Count;
desc = &partialDesc->PartialDescriptors[0];
for (i = 0; i < count; i++) {
MbpDumpCmResourceDescriptor(" ", desc);
desc++;
}
}
#endif