247 lines
4.7 KiB
C
247 lines
4.7 KiB
C
/*++
|
||
|
||
Copyright (c) 1996-2000 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
utils.c
|
||
|
||
Abstract:
|
||
|
||
This module contains assorted utility functions for PCI.SYS.
|
||
|
||
Author:
|
||
|
||
Peter Johnston (peterj) 20-Nov-1996
|
||
|
||
Revision History:
|
||
|
||
Eric Nelson (enelson) 20-Mar-2000 - kidnap registry function
|
||
|
||
--*/
|
||
|
||
#include "agplib.h"
|
||
|
||
#ifdef ALLOC_PRAGMA
|
||
#pragma alloc_text(PAGE, AgpOpenKey)
|
||
#pragma alloc_text(PAGE, AgpStringToUSHORT)
|
||
#endif
|
||
|
||
|
||
ULONGLONG
|
||
AgpGetDeviceFlags(
|
||
IN PAGP_HACK_TABLE_ENTRY AgpHackTable,
|
||
IN USHORT VendorID,
|
||
IN USHORT DeviceID,
|
||
IN USHORT SubVendorID,
|
||
IN USHORT SubSystemID,
|
||
IN UCHAR RevisionID
|
||
)
|
||
/*++
|
||
|
||
Description:
|
||
|
||
Look in the registry for any flags for this VendorId/DeviceId.
|
||
|
||
Arguments:
|
||
|
||
VendorId PCI Vendor ID (16 bits) of the manufacturer of the
|
||
device.
|
||
|
||
DeviceId PCI Device ID (16 bits) of the device.
|
||
|
||
SubVendorID PCI SubVendorID representing the manufacturer of the
|
||
subsystem
|
||
|
||
SubSystemID PCI SubSystemID representing subsystem
|
||
|
||
RevisionID PCI Revision denoting the revision of the device
|
||
|
||
Return Value:
|
||
|
||
64 bit flags value or 0 if not found.
|
||
|
||
--*/
|
||
{
|
||
PAGP_HACK_TABLE_ENTRY current;
|
||
ULONGLONG hackFlags = 0;
|
||
ULONG match, bestMatch = 0;
|
||
|
||
if (AgpHackTable == NULL) {
|
||
return hackFlags;
|
||
}
|
||
|
||
//
|
||
// We want to do a best-case match:
|
||
// VVVVDDDDSSSSssssRR
|
||
// VVVVDDDDSSSSssss
|
||
// VVVVDDDDRR
|
||
// VVVVDDDD
|
||
//
|
||
// List is currently unsorted, so keep updating current best match.
|
||
//
|
||
|
||
for (current = AgpHackTable; current->VendorID != 0xFFFF; current++) {
|
||
match = 0;
|
||
|
||
//
|
||
// Must at least match vendor/dev
|
||
//
|
||
|
||
if ((current->DeviceID != DeviceID) ||
|
||
(current->VendorID != VendorID)) {
|
||
continue;
|
||
}
|
||
|
||
match = 1;
|
||
|
||
//
|
||
// If this entry specifies a revision, check that it is consistent.
|
||
//
|
||
|
||
if (current->Flags & AGP_HACK_FLAG_REVISION) {
|
||
if (current->RevisionID == RevisionID) {
|
||
match += 2;
|
||
} else {
|
||
continue;
|
||
}
|
||
}
|
||
|
||
//
|
||
// If this entry specifies subsystems, check that they are consistent
|
||
//
|
||
|
||
if (current->Flags & AGP_HACK_FLAG_SUBSYSTEM) {
|
||
if (current->SubVendorID == SubVendorID &&
|
||
current->SubSystemID == SubSystemID) {
|
||
match += 4;
|
||
} else {
|
||
continue;
|
||
}
|
||
}
|
||
|
||
if (match > bestMatch) {
|
||
bestMatch = match;
|
||
hackFlags = current->DeviceFlags;
|
||
}
|
||
}
|
||
|
||
return hackFlags;
|
||
}
|
||
|
||
|
||
|
||
BOOLEAN
|
||
AgpOpenKey(
|
||
IN PWSTR KeyName,
|
||
IN HANDLE ParentHandle,
|
||
OUT PHANDLE Handle,
|
||
OUT PNTSTATUS Status
|
||
)
|
||
/*++
|
||
|
||
Description:
|
||
|
||
Open a registry key.
|
||
|
||
Arguments:
|
||
|
||
KeyName Name of the key to be opened.
|
||
ParentHandle Pointer to the parent handle (OPTIONAL)
|
||
Handle Pointer to a handle to recieve the opened key.
|
||
|
||
Return Value:
|
||
|
||
TRUE is key successfully opened, FALSE otherwise.
|
||
|
||
--*/
|
||
{
|
||
UNICODE_STRING nameString;
|
||
OBJECT_ATTRIBUTES nameAttributes;
|
||
NTSTATUS localStatus;
|
||
|
||
PAGED_CODE();
|
||
|
||
RtlInitUnicodeString(&nameString, KeyName);
|
||
|
||
InitializeObjectAttributes(&nameAttributes,
|
||
&nameString,
|
||
OBJ_CASE_INSENSITIVE,
|
||
ParentHandle,
|
||
(PSECURITY_DESCRIPTOR)NULL
|
||
);
|
||
localStatus = ZwOpenKey(Handle,
|
||
KEY_READ,
|
||
&nameAttributes
|
||
);
|
||
|
||
if (Status != NULL) {
|
||
|
||
//
|
||
// Caller wants underlying status.
|
||
//
|
||
|
||
*Status = localStatus;
|
||
}
|
||
|
||
//
|
||
// Return status converted to a boolean, TRUE if
|
||
// successful.
|
||
//
|
||
|
||
return NT_SUCCESS(localStatus);
|
||
}
|
||
|
||
|
||
|
||
BOOLEAN
|
||
AgpStringToUSHORT(
|
||
IN PWCHAR String,
|
||
OUT PUSHORT Result
|
||
)
|
||
/*++
|
||
|
||
Description:
|
||
|
||
Takes a 4 character hexidecimal sting and converts it into a USHORT.
|
||
|
||
Arguments:
|
||
|
||
String - the string
|
||
|
||
Result - the USHORT
|
||
|
||
Return Value:
|
||
|
||
TRUE is success, FASLE otherwise
|
||
|
||
--*/
|
||
{
|
||
ULONG count;
|
||
USHORT number = 0;
|
||
PWCHAR current;
|
||
|
||
current = String;
|
||
|
||
for (count = 0; count < 4; count++) {
|
||
|
||
number <<= 4;
|
||
|
||
if (*current >= L'0' && *current <= L'9') {
|
||
number |= *current - L'0';
|
||
} else if (*current >= L'A' && *current <= L'F') {
|
||
number |= *current + 10 - L'A';
|
||
} else if (*current >= L'a' && *current <= L'f') {
|
||
number |= *current + 10 - L'a';
|
||
} else {
|
||
return FALSE;
|
||
}
|
||
|
||
current++;
|
||
}
|
||
|
||
*Result = number;
|
||
return TRUE;
|
||
}
|
||
|