475 lines
15 KiB
ObjectPascal
475 lines
15 KiB
ObjectPascal
{*******************************************************}
|
|
{ MiTeC Common Routines }
|
|
{ NT DDK Header }
|
|
{ }
|
|
{ Copyright (c) 1997-2021 Michal Mutl }
|
|
{ }
|
|
{*******************************************************}
|
|
|
|
{$INCLUDE Compilers.inc}
|
|
|
|
unit MiTeC_NTDDK;
|
|
|
|
interface
|
|
|
|
uses {$IFDEF RAD9PLUS}
|
|
WinAPI.Windows, System.SysUtils;
|
|
{$ELSE}
|
|
Windows, SysUtils;
|
|
{$ENDIF}
|
|
|
|
|
|
type UCHAR = Byte;
|
|
type USHORT = Word;
|
|
type ULONG = LongInt;
|
|
|
|
type
|
|
CM_RESOURCE_TYPE = integer;
|
|
|
|
const
|
|
CmResourceTypeNull = 0; { ResType_All or ResType_None (0x0000)}
|
|
CmResourceTypePort = 1; { ResType_IO (0x0002)}
|
|
CmResourceTypeInterrupt = 2; { ResType_IRQ (0x0004)}
|
|
CmResourceTypeMemory = 3; { ResType_Mem (0x0001)}
|
|
CmResourceTypeDma = 4; { ResType_DMA (0x0003)}
|
|
CmResourceTypeDeviceSpecific = 5; { ResType_ClassSpecific (0xFFFF)}
|
|
CmResourceTypeBusNumber = 6; { ResType_BusNumber (0x0006)}
|
|
CmResourceTypeMaximum = 7;
|
|
CmResourceTypeAssignedResource = 8; { BUGBUG--remove}
|
|
CmResourceTypeSubAllocateFrom = 9; { BUGBUG--remove}
|
|
CmResourceTypeNonArbitrated = 128; { Not arbitrated if 0x80 bit set}
|
|
CmResourceTypeConfigData = 128; { ResType_Reserved (0x8000) }
|
|
CmResourceTypeDevicePrivate = 129; { ResType_DevicePrivate (0x8001) }
|
|
CmResourceTypePcCardConfig = 130; { ResType_PcCardConfig (0x8002) }
|
|
|
|
{ Defines the ShareDisposition in the RESOURCE_DESCRIPTOR }
|
|
type
|
|
CM_SHARE_DISPOSITION = (
|
|
CmResourceShareUndetermined,
|
|
CmResourceShareDeviceExclusive,{ Reserved }
|
|
CmResourceShareDriverExclusive);
|
|
|
|
|
|
{ Define the bit masks for Flags common for all CM_RESOURCE_TYPE }
|
|
const
|
|
CM_RESOURCE_COMMON_COMPUTE_LENGTH_FROM_DEPENDENTS = $8000;
|
|
CM_RESOURCE_COMMON_NOT_REASSIGNED = $4000;
|
|
CM_RESOURCE_COMMON_SUBSTRACTIVE = $2000;
|
|
|
|
{ Define the bit masks for Flags when type is CmResourceTypeInterrupt }
|
|
CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE = 0;
|
|
CM_RESOURCE_INTERRUPT_LATCHED = 1;
|
|
|
|
{ Define the bit masks for Flags when type is CmResourceTypeMemory }
|
|
CM_RESOURCE_MEMORY_READ_WRITE = $0000;
|
|
CM_RESOURCE_MEMORY_READ_ONLY = $0001;
|
|
CM_RESOURCE_MEMORY_WRITE_ONLY = $0002;
|
|
CM_RESOURCE_MEMORY_PREFETCHABLE = $0004;
|
|
CM_RESOURCE_MEMORY_COMBINEDWRITE = $0008;
|
|
CM_RESOURCE_MEMORY_24 = $0010;
|
|
|
|
{ Define the bit masks for Flags when type is CmResourceTypePort }
|
|
CM_RESOURCE_PORT_MEMORY = $0000;
|
|
CM_RESOURCE_PORT_IO = $0001;
|
|
CM_RESOURCE_PORT_FORWARD_FIRST_256_OF_EACH_1024 = $0002; { BUGBUG--remove }
|
|
CM_RESOURCE_PORT_10_BIT_DECODE = $0004;
|
|
CM_RESOURCE_PORT_12_BIT_DECODE = $0008;
|
|
CM_RESOURCE_PORT_16_BIT_DECODE = $0010;
|
|
CM_RESOURCE_PORT_POSITIVE_DECODE = $0020;
|
|
|
|
{ Define the bit masks for Flags when type is CmResourceTypeDma }
|
|
CM_RESOURCE_DMA_8 = $0000;
|
|
CM_RESOURCE_DMA_16 = $0001;
|
|
CM_RESOURCE_DMA_32 = $0002;
|
|
|
|
{ Define the bit masks for Flags when type is CmResourceTypeBusNumber }
|
|
CM_RESOURCE_BUSNUMBER_SUBALLOCATE_FIRST_VALUE = $0001; { BUGBUG--remove }
|
|
|
|
{ Define the bit masks for Flags when type is CmResourceTypeSubAllocateFrom }
|
|
CM_RESOURCE_SUBALLOCATEFROM_FIXED_TRANSLATION = $0001; { BUGBUG--remove }
|
|
CM_RESOURCE_SUBALLOCATEFROM_WIRED_TRANSLATION = $0002; { BUGBUG--remove }
|
|
|
|
type
|
|
PHYSICAL_ADDRESS = LARGE_INTEGER;
|
|
|
|
{ Range of resources, inclusive. These are physical, bus relative. }
|
|
{ It is known that Port and Memory below have the exact same layout }
|
|
{ as Generic. }
|
|
PRDD_Generic = ^RDD_Generic;
|
|
RDD_Generic = record
|
|
Start: PHYSICAL_ADDRESS;
|
|
Length: Cardinal;
|
|
end;
|
|
|
|
{ Range of port numbers, inclusive. These are physical, bus }
|
|
{ relative. The value should be the same as the one passed to }
|
|
{ HalTranslateBusAddress(). }
|
|
PRDD_Port = ^RDD_Port;
|
|
RDD_Port = record
|
|
Start: PHYSICAL_ADDRESS;
|
|
Length: Cardinal;
|
|
end;
|
|
|
|
{ IRQL and vector. Should be same values as were passed to }
|
|
{ HalGetInterruptVector(). }
|
|
PRDD_Interrupt = ^RDD_Interrupt;
|
|
RDD_Interrupt = record
|
|
Level: cardinal;
|
|
Vector: cardinal;
|
|
Affinity: cardinal;
|
|
end;
|
|
|
|
{ Range of memory addresses, inclusive. These are physical, bus }
|
|
{ relative. The value should be the same as the one passed to }
|
|
{ HalTranslateBusAddress(). }
|
|
PRDD_Memory = ^RDD_Memory;
|
|
RDD_Memory = record
|
|
Start: PHYSICAL_ADDRESS;
|
|
Length: Cardinal;
|
|
end;
|
|
|
|
{ Physical DMA channel. }
|
|
PRDD_DMA = ^RDD_DMA;
|
|
RDD_DMA = record
|
|
Channel: cardinal;
|
|
Port: cardinal;
|
|
Reserved1: cardinal;
|
|
end;
|
|
|
|
{ Device driver private data, usually used to help it figure }
|
|
{ what the resource assignments decisions that were made. }
|
|
PRDD_DevicePrivate = ^RDD_DevicePrivate;
|
|
RDD_DevicePrivate = record
|
|
Data: array [0..2] of cardinal;
|
|
end;
|
|
|
|
{ Bus Number information. }
|
|
PRDD_BusNumber = ^RDD_BusNumber;
|
|
RDD_BusNumber = record
|
|
Start: cardinal;
|
|
Length: cardinal;
|
|
Reserved: cardinal;
|
|
end;
|
|
|
|
{ Device Specific information defined by the driver. }
|
|
{ The DataSize field indicates the size of the data in bytes. The }
|
|
{ data is located immediately after the DeviceSpecificData field in }
|
|
{ the structure. }
|
|
PRDD_DeviceSpecificData = ^RDD_DeviceSpecificData;
|
|
RDD_DeviceSpecificData = record
|
|
DataSize: cardinal;
|
|
Reserved1: cardinal;
|
|
Reserved2: cardinal;
|
|
end;
|
|
|
|
_CM_PARTIAL_RESOURCE_DESCRIPTOR = record
|
|
Typ: Byte;
|
|
ShareDisposition: CM_SHARE_DISPOSITION;
|
|
Flags: smallint;
|
|
case integer of
|
|
0: (Generic: RDD_Generic);
|
|
1: (Port: RDD_Port);
|
|
2: (Interrupt: RDD_Interrupt);
|
|
3: (Memory: RDD_Memory);
|
|
4: (Dma: RDD_DMA);
|
|
5: (DevicePrivate: RDD_DevicePrivate);
|
|
6: (BusNumber: RDD_BusNumber);
|
|
7: (DeviceSpecificData: RDD_DeviceSpecificData);
|
|
end;
|
|
CM_PARTIAL_RESOURCE_DESCRIPTOR = _CM_PARTIAL_RESOURCE_DESCRIPTOR;
|
|
|
|
PCM_PARTIAL_RESOURCE_DESCRIPTOR = _CM_PARTIAL_RESOURCE_DESCRIPTOR;
|
|
|
|
_CM_PARTIAL_RESOURCE_LIST = record
|
|
Version: USHORT;
|
|
Revision: USHORT;
|
|
Count: ULONG;
|
|
PartialDescriptors: CM_PARTIAL_RESOURCE_DESCRIPTOR;
|
|
end;
|
|
CM_PARTIAL_RESOURCE_LIST = _CM_PARTIAL_RESOURCE_LIST;
|
|
PCM_PARTIAL_RESOURCE_LIST = ^_CM_PARTIAL_RESOURCE_LIST;
|
|
|
|
{ Define the I/O bus interface types. }
|
|
INTERFACE_TYPE = (
|
|
InterfaceTypeUndefined, //-1
|
|
Internal,
|
|
Isa,
|
|
Eisa,
|
|
MicroChannel,
|
|
TurboChannel,
|
|
PCIBus,
|
|
VMEBus,
|
|
NuBus,
|
|
PCMCIABus,
|
|
CBus,
|
|
MPIBus,
|
|
MPSABus,
|
|
ProcessorInternal,
|
|
InternalPowerBus,
|
|
PNPISABus,
|
|
PNPBus);
|
|
|
|
{ Define the DMA transfer widths. }
|
|
DMA_WIDTH = (
|
|
Width8Bits,
|
|
Width16Bits,
|
|
Width32Bits);
|
|
|
|
{ Define DMA transfer speeds. }
|
|
DMA_SPEED = (
|
|
Compatible,
|
|
TypeA,
|
|
TypeB,
|
|
TypeC);
|
|
|
|
{ Define types of bus information. }
|
|
BUS_DATA_TYPE = (
|
|
ConfigurationSpaceUndefined, //-1
|
|
Cmos,
|
|
EisaConfiguration,
|
|
Pos1,
|
|
CbusConfiguration,
|
|
PCIConfiguration,
|
|
VMEConfiguration,
|
|
NuBusConfiguration,
|
|
PCMCIAConfiguration,
|
|
MPIConfiguration,
|
|
MPSAConfiguration,
|
|
PNPISAConfiguration);
|
|
|
|
_CM_FULL_RESOURCE_DESCRIPTOR = record
|
|
InterfaceType: INTERFACE_TYPE;
|
|
BusNumber: ULONG;
|
|
PartialResourceList: CM_PARTIAL_RESOURCE_LIST;
|
|
end;
|
|
CM_FULL_RESOURCE_DESCRIPTOR = _CM_FULL_RESOURCE_DESCRIPTOR;
|
|
PCM_FULL_RESOURCE_DESCRIPTOR = ^_CM_FULL_RESOURCE_DESCRIPTOR;
|
|
|
|
_CM_RESOURCE_LIST = record
|
|
Count: ULONG;
|
|
List: CM_FULL_RESOURCE_DESCRIPTOR;
|
|
end;
|
|
CM_RESOURCE_LIST = _CM_RESOURCE_LIST;
|
|
PCM_RESOURCE_LIST = ^_CM_RESOURCE_LIST;
|
|
|
|
{ my implementation of structures above to read from registry }
|
|
type
|
|
PResourceListHeader = ^TResourceListHeader;
|
|
TResourceListHeader = record
|
|
Count: Cardinal;
|
|
end;
|
|
|
|
PFullResourceDescriptorHeader = ^TFullResourceDescriptorHeader;
|
|
TFullResourceDescriptorHeader = record
|
|
InterfaceType: INTERFACE_TYPE;
|
|
BusNumber: Cardinal;
|
|
end;
|
|
|
|
PPartialResourceListHeader = ^TPartialResourceListHeader;
|
|
TPartialResourceListHeader = record
|
|
Version: WORD;
|
|
Revision: WORD;
|
|
Count: Cardinal;
|
|
end;
|
|
|
|
PPartialResourceDescriptorHeader = ^TPartialResourceDescriptorHeader;
|
|
TPartialResourceDescriptorHeader = record
|
|
Typ: Byte;
|
|
ShareDisposition: CM_SHARE_DISPOSITION;
|
|
Flags: WORD;
|
|
end;
|
|
|
|
TDeviceResources = record
|
|
InterfaceType: INTERFACE_TYPE;
|
|
BusNumber: Cardinal;
|
|
Version: WORD;
|
|
Revision: WORD;
|
|
Resources: array of CM_PARTIAL_RESOURCE_DESCRIPTOR;
|
|
end;
|
|
|
|
procedure ReadDeviceResourcesFromRegistry(AKey: HKEY; Avalue: string; var DeviceResources: TDeviceResources);
|
|
procedure BufferToResourceList(Buffer: PAnsiChar; DataSize: integer; var DeviceResources: TDeviceResources);
|
|
|
|
function DeviceResourceTypeStr(AType: Cardinal): string;
|
|
function DeviceIntfTypeStr(AIntf: INTERFACE_TYPE): string;
|
|
function ResourceShareStr(AType: CM_SHARE_DISPOSITION): string;
|
|
function InterruptTypeStr(AType: Cardinal): string;
|
|
function MemoryAccessStr(AType: Cardinal): string;
|
|
function PortTypeStr(AType: Cardinal): string;
|
|
|
|
implementation
|
|
|
|
procedure ReadDeviceResourcesFromRegistry;
|
|
var
|
|
Data: PAnsiChar;
|
|
DataSize, DataType: Integer;
|
|
begin
|
|
try
|
|
RegQueryValueEx(AKey,PChar(AValue),nil,PDWORD(@DataType),nil,PDWORD(@DataSize));
|
|
Data:=AllocMem(DataSize);
|
|
try
|
|
RegQueryValueEx(AKey,PChar(AValue),nil,PDWORD(@DataType),PByte(Data),PDWORD(@DataSize));
|
|
BufferToResourceList(Data,DataSize,DeviceResources);
|
|
finally
|
|
Freemem(Data);
|
|
end;
|
|
finally
|
|
end;
|
|
end;
|
|
|
|
procedure BufferToResourceList;
|
|
var
|
|
p, ResType: Integer; //_W_ DataType
|
|
prd: CM_PARTIAL_RESOURCE_DESCRIPTOR;
|
|
begin
|
|
SetLength(DeviceResources.Resources,0);
|
|
try
|
|
p:=0;
|
|
p:=p+SizeOf(TResourceListHeader);
|
|
DeviceResources.InterfaceType:=INTERFACE_TYPE(Integer(PFullResourceDescriptorHeader(Buffer+p)^.InterfaceType)+1);
|
|
DeviceResources.BusNumber:=PFullResourceDescriptorHeader(Buffer+p)^.BusNumber;
|
|
p:=p+SizeOf(TFullResourceDescriptorHeader);
|
|
DeviceResources.Version:=PPartialResourceListHeader(Buffer+p)^.Version;
|
|
DeviceResources.Revision:=PPartialResourceListHeader(Buffer+p)^.Revision;
|
|
p:=p+sizeof(TPartialResourceListHeader);
|
|
while p<DataSize-sizeof(TPartialResourceListHeader) do begin
|
|
ResType:=PPartialResourceDescriptorHeader(Buffer+p)^.Typ;
|
|
prd.Typ:=ResType;
|
|
prd.ShareDisposition:=PPartialResourceDescriptorHeader(Buffer+p)^.ShareDisposition;
|
|
prd.Flags:=PPartialResourceDescriptorHeader(Buffer+p)^.Flags;
|
|
p:=p+sizeof(TPartialResourceDescriptorHeader);
|
|
case ResType of
|
|
CmResourceTypeNull: begin
|
|
prd.Generic:=PRDD_Generic(Buffer+p)^;
|
|
p:=p+sizeof(RDD_Generic)-4;
|
|
end;
|
|
CmResourceTypePort: begin
|
|
prd.Port:=PRDD_Port(Buffer+p)^;
|
|
p:=p+sizeof(RDD_Port)-4;
|
|
end;
|
|
CmResourceTypeInterrupt: begin
|
|
prd.Interrupt:=PRDD_Interrupt(Buffer+p)^;
|
|
p:=p+sizeof(RDD_Interrupt);
|
|
end;
|
|
CmResourceTypeMemory: begin
|
|
prd.Memory:=PRDD_Memory(Buffer+p)^;
|
|
p:=p+sizeof(RDD_Memory)-4;
|
|
end;
|
|
CmResourceTypeDma: begin
|
|
prd.DMA:=PRDD_DMA(Buffer+p)^;
|
|
p:=p+SizeOf(RDD_DMA);
|
|
end;
|
|
CmResourceTypeDeviceSpecific: begin
|
|
prd.DevicePrivate:=PRDD_DevicePrivate(Buffer+p)^;
|
|
p:=p+sizeof(RDD_DeviceSpecificData);
|
|
end;
|
|
CmResourceTypeBusNumber: begin
|
|
prd.BusNumber:=PRDD_BusNumber(Buffer+p)^;
|
|
p:=p+sizeof(RDD_BusNumber);
|
|
end;
|
|
CmResourceTypeMaximum: begin
|
|
prd.DeviceSpecificData:=PRDD_DeviceSpecificData(Buffer+p)^;
|
|
p:=p+sizeof(RDD_DeviceSpecificData);
|
|
end;
|
|
else
|
|
p:=p+SizeOf(RDD_BusNumber);
|
|
end;
|
|
if ResType in [CmResourceTypeNull..CmResourceTypeMaximum] then begin
|
|
SetLength(DeviceResources.Resources,Length(DeviceResources.Resources)+1);
|
|
DeviceResources.Resources[High(DeviceResources.Resources)]:=prd;
|
|
end;
|
|
end;
|
|
finally
|
|
end;
|
|
end;
|
|
|
|
function DeviceResourceTypeStr;
|
|
begin
|
|
case AType of
|
|
CmResourceTypeNull: Result:='None';
|
|
CmResourceTypePort: Result:='Port';
|
|
CmResourceTypeInterrupt: Result:='IRQ';
|
|
CmResourceTypeMemory: Result:='Memory';
|
|
CmResourceTypeDma: Result:='DMA';
|
|
CmResourceTypeDeviceSpecific: Result:='DeviceSpecific';
|
|
CmResourceTypeBusNumber: Result:='BusNumber';
|
|
CmResourceTypeMaximum: Result:='Maximum';
|
|
CmResourceTypeAssignedResource: Result:='AssignedResource';
|
|
CmResourceTypeSubAllocateFrom: Result:='SubAllocateFrom';
|
|
//CmResourceTypeNonArbitrated: Result:='NonArbitrared';
|
|
CmResourceTypeConfigData: Result:='ConfigData';
|
|
CmResourceTypeDevicePrivate: Result:='DevicePrivate';
|
|
CmResourceTypePcCardConfig: Result:='PCCardConfig';
|
|
end;
|
|
end;
|
|
|
|
function DeviceIntfTypeStr;
|
|
begin
|
|
case AIntf of
|
|
InterfaceTypeUndefined: Result:='Invalid';
|
|
Internal: Result:='Internal';
|
|
Isa: Result:='ISA';
|
|
Eisa: Result:='EISA';
|
|
MicroChannel: Result:='MCA';
|
|
TurboChannel: Result:='TurboChannel';
|
|
PCIBus: Result:='PCI';
|
|
VMEBus: Result:='VME';
|
|
NuBus: Result:='NuBus';
|
|
PCMCIABus: Result:='PCMCIA';
|
|
CBus: Result:='CBus';
|
|
MPIBus: Result:='MPI';
|
|
MPSABus: Result:='MPSA';
|
|
ProcessorInternal: Result:='ProcessorInternal';
|
|
InternalPowerBus: Result:='InternalPowerBus';
|
|
PNPISABus: Result:='PnP-ISA';
|
|
PNPBus: Result:='PnP';
|
|
end;
|
|
end;
|
|
|
|
function ResourceShareStr;
|
|
begin
|
|
case AType of
|
|
CmResourceShareUndetermined: Result:='Undetermined';
|
|
CmResourceShareDeviceExclusive: Result:='Device Exclusive';
|
|
CmResourceShareDriverExclusive: Result:='Driver Exclusive';
|
|
else Result:='Shared';
|
|
end;
|
|
end;
|
|
|
|
function InterruptTypeStr;
|
|
begin
|
|
case AType of
|
|
CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE: Result:='Level Sensitive';
|
|
CM_RESOURCE_INTERRUPT_LATCHED: Result:='Latched';
|
|
else Result:=Format('0x%x',[AType]);
|
|
end;
|
|
end;
|
|
|
|
function MemoryAccessStr;
|
|
begin
|
|
case AType of
|
|
CM_RESOURCE_MEMORY_READ_WRITE: Result:='Read / Write';
|
|
CM_RESOURCE_MEMORY_READ_ONLY: Result:='Read Only';
|
|
CM_RESOURCE_MEMORY_WRITE_ONLY: Result:='Write Only';
|
|
CM_RESOURCE_MEMORY_PREFETCHABLE: Result:='Prefetchable';
|
|
CM_RESOURCE_MEMORY_COMBINEDWRITE: Result:='Combined Write';
|
|
CM_RESOURCE_MEMORY_24: Result:='24';
|
|
else Result:=Format('0x%x',[AType]);end;
|
|
end;
|
|
|
|
function PortTypeStr;
|
|
begin
|
|
case AType of
|
|
CM_RESOURCE_PORT_MEMORY: Result:='Memory';
|
|
CM_RESOURCE_PORT_IO: Result:='Port';
|
|
CM_RESOURCE_PORT_10_BIT_DECODE: Result:='10-bit decode';
|
|
CM_RESOURCE_PORT_12_BIT_DECODE: Result:='12-bit decode';
|
|
CM_RESOURCE_PORT_16_BIT_DECODE: Result:='16-bit decode';
|
|
CM_RESOURCE_PORT_POSITIVE_DECODE: Result:='Positive decode';
|
|
else Result:=Format('0x%x',[AType]);
|
|
end;
|
|
end;
|
|
|
|
end.
|
|
|