208 lines
5.1 KiB
C
208 lines
5.1 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1991 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
config.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module implements the code to find an ARC configuration tree
|
|||
|
entry as constructed by the OS Loader.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
David N. Cutler (davec) 9-Sep-1991
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
User mode only.
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "ki.h"
|
|||
|
|
|||
|
#ifdef ALLOC_PRAGMA
|
|||
|
#pragma alloc_text(INIT,KeFindConfigurationEntry)
|
|||
|
#pragma alloc_text(INIT,KeFindConfigurationNextEntry)
|
|||
|
#endif
|
|||
|
|
|||
|
PCONFIGURATION_COMPONENT_DATA
|
|||
|
KeFindConfigurationEntry (
|
|||
|
IN PCONFIGURATION_COMPONENT_DATA Child,
|
|||
|
IN CONFIGURATION_CLASS Class,
|
|||
|
IN CONFIGURATION_TYPE Type,
|
|||
|
IN PULONG Key OPTIONAL
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function search the specified configuration tree and returns a
|
|||
|
pointer to an entry that matches the specified class, type, and key
|
|||
|
parameters.
|
|||
|
|
|||
|
This routine is the same as KeFindConfurationEntryNext expect
|
|||
|
that the search is performed from the first entry
|
|||
|
|
|||
|
N.B. This routine can only be called during system initialization.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PCONFIGURATION_COMPONENT_DATA Resume;
|
|||
|
|
|||
|
Resume = NULL;
|
|||
|
return KeFindConfigurationNextEntry (Child, Class, Type, Key, &Resume);
|
|||
|
}
|
|||
|
|
|||
|
PCONFIGURATION_COMPONENT_DATA
|
|||
|
KeFindConfigurationNextEntry (
|
|||
|
IN PCONFIGURATION_COMPONENT_DATA Child,
|
|||
|
IN CONFIGURATION_CLASS Class,
|
|||
|
IN CONFIGURATION_TYPE Type,
|
|||
|
IN PULONG Key OPTIONAL,
|
|||
|
IN PCONFIGURATION_COMPONENT_DATA *Resume
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function search the specified configuration tree and returns a
|
|||
|
pointer to an entry that matches the specified class, type, and key
|
|||
|
parameters.
|
|||
|
|
|||
|
N.B. This routine can only be called during system initialization.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Child - Supplies an optional pointer to an NT configuration component.
|
|||
|
|
|||
|
Class - Supplies the configuration class of the entry to locate.
|
|||
|
|
|||
|
Type - Supplies the configuration type of the entry to locate.
|
|||
|
|
|||
|
Key - Supplies a pointer to an optional key value to use in locating
|
|||
|
the specified entry.
|
|||
|
|
|||
|
Resume - Supplies the last returned entry for which the search
|
|||
|
should resume from.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
If the specified entry is located, then a pointer to the configuration
|
|||
|
entry is returned as the function value. Otherwise, NULL is returned.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
PCONFIGURATION_COMPONENT_DATA Entry;
|
|||
|
ULONG MatchKey;
|
|||
|
ULONG MatchMask;
|
|||
|
PCONFIGURATION_COMPONENT_DATA Sibling;
|
|||
|
|
|||
|
//
|
|||
|
// Initialize the match key and mask based on whether the optional key
|
|||
|
// value is specified.
|
|||
|
//
|
|||
|
|
|||
|
if (ARGUMENT_PRESENT(Key)) {
|
|||
|
MatchMask = 0xffffffff;
|
|||
|
MatchKey = *Key;
|
|||
|
|
|||
|
} else {
|
|||
|
MatchMask = 0;
|
|||
|
MatchKey = 0;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Search specified configuration tree for an entry that matches the
|
|||
|
// the specified class, type, and key.
|
|||
|
//
|
|||
|
|
|||
|
while (Child != NULL) {
|
|||
|
if (*Resume) {
|
|||
|
//
|
|||
|
// If resume location found, clear resume location and continue
|
|||
|
// search with next entry
|
|||
|
//
|
|||
|
|
|||
|
if (Child == *Resume) {
|
|||
|
*Resume = NULL;
|
|||
|
}
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// If the class, type, and key match, then return a pointer to
|
|||
|
// the child entry.
|
|||
|
//
|
|||
|
|
|||
|
if ((Child->ComponentEntry.Class == Class) &&
|
|||
|
(Child->ComponentEntry.Type == Type) &&
|
|||
|
((Child->ComponentEntry.Key & MatchMask) == MatchKey)) {
|
|||
|
return Child;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If the child has a sibling list, then search the sibling list
|
|||
|
// for an entry that matches the specified class, type, and key.
|
|||
|
//
|
|||
|
|
|||
|
Sibling = Child->Sibling;
|
|||
|
while (Sibling != NULL) {
|
|||
|
if (*Resume) {
|
|||
|
//
|
|||
|
// If resume location found, clear resume location and continue
|
|||
|
// search with next entry
|
|||
|
//
|
|||
|
|
|||
|
if (Sibling == *Resume) {
|
|||
|
*Resume = NULL;
|
|||
|
}
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// If the class, type, and key match, then return a pointer to
|
|||
|
// the child entry.
|
|||
|
//
|
|||
|
|
|||
|
if ((Sibling->ComponentEntry.Class == Class) &&
|
|||
|
(Sibling->ComponentEntry.Type == Type) &&
|
|||
|
((Sibling->ComponentEntry.Key & MatchMask) == MatchKey)) {
|
|||
|
return Sibling;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If the sibling has a child tree, then search the child tree
|
|||
|
// for an entry that matches the specified class, type, and key.
|
|||
|
//
|
|||
|
|
|||
|
if (Sibling->Child != NULL) {
|
|||
|
Entry = KeFindConfigurationNextEntry (
|
|||
|
Sibling->Child,
|
|||
|
Class,
|
|||
|
Type,
|
|||
|
Key,
|
|||
|
Resume
|
|||
|
);
|
|||
|
|
|||
|
if (Entry != NULL) {
|
|||
|
return Entry;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
Sibling = Sibling->Sibling;
|
|||
|
}
|
|||
|
|
|||
|
Child = Child->Child;
|
|||
|
}
|
|||
|
|
|||
|
return NULL;
|
|||
|
}
|