Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

567 lines
14 KiB

/*++
*
* Copyright (c) 1995 FirePower Systems, Inc.
*
* $RCSfile: vrconfig.c $
* $Revision: 1.10 $
* $Date: 1996/04/15 02:56:07 $
* $Locker: $
*
Module Name:
vrconfig.c
Abstract:
This module contains the configuration functions.
Author:
A. Benjamin 2-May-1994
Revision History:
09-06-94 Shin Iwamoto at FirePower Systems Inc.
Added checking ConfigurationData in VrGetConfigurationData().
Added checking Componet in VrGetParent() and VrGetPeer().
09-01-94 Shin Iwamoto at FirePower Systems Inc.
Added to be an error if the ConfigurationDataLength field of
NewComponent is non-zero and the COnfigurationData parameter is null.
07-22-94 Shin Iwamoto at FirePower Systems Inc.
Added VrAddChild() and VrDeleteComponent().
07-21-94 Shin Iwamoto at FirePower Systems Inc.
Moved the intialization of vector table for VrGetEnvironmentVariable
and VrGetMemoryDescriptor into vrenv.c.
07-20-94 Shin Iwamoto at FirePower Systems Inc.
Moved VrSystemInit() and VrNotYet() to vrmain.c and then
renamed VrSystemInit() with VrConfigInitialize() for only
initializing the vector table.
--*/
#include "veneer.h"
/*
* Name: VrAddChild
*
* Description:
* This function adds a new component entry as a child of Component,
* including an identifier string if the IdentifierLength field of
* NewComponent is non-zero, and configuration data if the
* ConfigurationDataLength field of NewComponent is non-zero and the
* ConfigurationData parameter is present. If Componet is NULL,
* the root component is being added.
*
* Arguments:
* Component - Supplies a pointer to a configuration component.
* NewComponent- Supplies a pointer to a new configuration component
* to be added as a child of Component.
* ConfigurationData - Supplies an optional pointer to a configuration
* data buffer.
*
* Return Value:
* Returns a pointer to the new configuration component entry.
* If the create operation was unsuccessful, NULL is returned.
*
*/
PCONFIGURATION_COMPONENT
VrAddChild(
IN PCONFIGURATION_COMPONENT Component,
IN PCONFIGURATION_COMPONENT NewComponent,
IN PVOID ConfigurationData OPTIONAL
)
{
PCONFIGURATION_NODE ConfNode;
PCONFIGURATION_NODE ChildNode;
PCONFIGURATION_NODE ParentNode;
//
// If there is not enough space for the new component, retrun NULL.
//
ConfNode = new(CONFIGURATION_NODE);
if ((PCHAR) ConfNode == NULL) {
return (PCONFIGURATION_COMPONENT) NULL;
}
//
// Fill in new configuration entry with Identifier and ConfigurationData.
//
bcopy((PCHAR)NewComponent, (PCHAR)&ConfNode->Component,
sizeof(CONFIGURATION_COMPONENT));
if (NewComponent->IdentifierLength != 0) {
ConfNode->Component.Identifier = malloc(NewComponent->IdentifierLength);
if (ConfNode->Component.Identifier == NULL) {
ConfNode->Component.IdentifierLength = 0;
goto ErrorAddChild;
}
bcopy(NewComponent->Identifier, ConfNode->Component.Identifier,
NewComponent->IdentifierLength);
} else {
ConfNode->Component.Identifier = NULL; // For safety
}
if (NewComponent->ConfigurationDataLength != 0) {
if (ConfigurationData == NULL) {
ConfNode->Component.ConfigurationDataLength = 0;
goto ErrorAddChild;
}
ConfNode->ConfigurationData =
(CM_PARTIAL_RESOURCE_LIST *)
malloc(NewComponent->ConfigurationDataLength);
if (ConfNode->ConfigurationData == NULL) {
ConfNode->Component.ConfigurationDataLength = 0;
goto ErrorAddChild;
}
bcopy(ConfigurationData, (PCHAR)(ConfNode->ConfigurationData),
NewComponent->ConfigurationDataLength);
}
//
// If Component is NULL and the new Class is system, the root component
// is being added, otherwise the new is added according to Component.
//
if ((Component == NULL) && (NewComponent->Class == SystemClass)) {
//
// If the root component is being added, replace the root component.
// However, some information such as phandle are adhered.
// XXXX Is it Ok?
//
ConfNode->Peer = RootNode->Peer;
ConfNode->Child = RootNode->Child;
ConfNode->Parent = NULL;
ConfNode->OfPhandle = RootNode->OfPhandle;
RootNode = ConfNode;
//
// The parent of the old parent's children is changed.
//
ChildNode = ConfNode->Child;
while(ChildNode != NULL) {
ChildNode->Parent = ConfNode;
ChildNode = ChildNode->Peer;
}
} else {
if (Component == NULL) {
ParentNode = RootNode;
} else {
ParentNode = CONTAINING_RECORD(Component,
CONFIGURATION_NODE,
Component);
}
ConfNode->Peer = ParentNode->Child;
ParentNode->Child = ConfNode;
ConfNode->Child = NULL;
ConfNode->Parent = ParentNode;
ConfNode->OfPhandle = OFChild(ParentNode->OfPhandle);
if (!(ConfNode->OfPhandle)) { // This "can't happen."
goto ErrorAddChild;
}
}
return (&ConfNode->Component);
ErrorAddChild:
if (ConfNode->Component.IdentifierLength != 0) {
free(ConfNode->Component.Identifier);
}
if (ConfNode->Component.ConfigurationDataLength != 0) {
free((PVOID)ConfNode->ConfigurationData);
}
bzero((char *)ConfNode, sizeof(CONFIGURATION_NODE)); // For safety
free((char *) ConfNode);
return (PCONFIGURATION_COMPONENT) NULL;
}
/*
* Name: VrDeleteComponent
*
* Description:
* This function deletes a component entry. If the entry has one or more
* children, an error is returned, otherwise the entry is deleted.
* Deleting the entry will implicitly delete the identifier string and
* the configuration data.
*
* Arguments:
* Component - Supplies a pointer to a configuration component.
*
* Return Value:
* Returns ESUCCESS if the entry was successfully deleted, otherwise retunrs
* EINVAL or EACCES.
*
*/
ARC_STATUS
VrDeleteComponent(
IN PCONFIGURATION_COMPONENT Component
)
{
PCONFIGURATION_NODE ConfNode;
PCONFIGURATION_NODE SearchNode;
if (Component == NULL) {
return EINVAL;
}
if (!(Component->Version == ARC_VERSION &&
Component->Revision == ARC_REVISION)) {
return EINVAL;
}
ConfNode = CONTAINING_RECORD(Component,
CONFIGURATION_NODE,
Component);
//
// If Component's parent field is NULL, return EINVAL.
//
if (ConfNode->Parent == NULL) {
return EINVAL;
}
//
// If Component has children, return EACCES.
//
if (ConfNode->Child != NULL) {
return EACCES;
}
//
// Find the entry that points to Component, and point it to
// Components's peer. If this is Components's parent, update the child
// pointer, otherwise this is apeer and update the peer pointer.
//
SearchNode = ConfNode->Parent;
if (SearchNode->Child == ConfNode) {
SearchNode->Child = ConfNode->Peer;
} else {
SearchNode = SearchNode->Child;
while (SearchNode->Peer != ConfNode) {
SearchNode = SearchNode->Peer;
}
SearchNode->Peer = ConfNode->Peer;
}
//
// Free Conponent with Identifier and ConfigurationData, if any.
//
if (ConfNode->Component.IdentifierLength != 0) {
free(ConfNode->Component.Identifier);
}
if (ConfNode->Component.ConfigurationDataLength != 0) {
free((PVOID)ConfNode->ConfigurationData);
}
bzero((char *)ConfNode, sizeof(CONFIGURATION_NODE)); // For safety
free((char *) ConfNode);
return ESUCCESS;
}
/*++
Routine Description:
The system configuration data structure is organized as a tree of
component structures. This function returns a pointer to the first
child of a configuration node.
If Component is null, then a pointer to the root node is returned.
Arguments:
Component - pointer to a component structure.
Return Value:
Returns a pointer to the structure of the child of component
if one exists, otherwise it returns a null pointer.
--*/
PCONFIGURATION_COMPONENT
VrGetChild (
IN PCONFIGURATION_COMPONENT Component OPTIONAL
)
{
PCONFIGURATION_NODE OfLink;
debug(VRDBG_VR, "VrGetChild: Entry - Component: %x\n", Component);
if (Component == (PCONFIGURATION_COMPONENT)NULL) {
debug(VRDBG_VR, "VrGetChild: Root %x\n", &RootNode->Component);
return &RootNode->Component;
}
OfLink = CONTAINING_RECORD(Component,
CONFIGURATION_NODE,
Component);
if (OfLink->Child == NULL ) {
debug(VRDBG_VR, "VrGetChild: NULL\n");
return NULL;
} else {
debug(VRDBG_VR, "VrGetChild: Child %x (%s)\n",
&OfLink->Child->Component, OfLink->Child->ComponentName);
return &OfLink->Child->Component;
}
}
PCONFIGURATION_COMPONENT
VrGetParent(IN PCONFIGURATION_COMPONENT Component)
{
PCONFIGURATION_NODE OfLink;
debug(VRDBG_VR, "VrGetParent: Entry - Component: %x\n", Component);
if (Component == NULL) {
return NULL;
}
if (!(Component->Version == ARC_VERSION &&
Component->Revision == ARC_REVISION)) {
return NULL;
}
OfLink = CONTAINING_RECORD(Component,
CONFIGURATION_NODE,
Component);
if (OfLink->Parent == NULL) {
debug(VRDBG_VR, "VrGetParent: Exit-1\n");
return NULL;
} else {
debug(VRDBG_VR, "VrGetParent: Exit-2\n");
return &OfLink->Parent->Component;
}
}
PCONFIGURATION_COMPONENT
VrGetPeer(IN PCONFIGURATION_COMPONENT Component)
{
PCONFIGURATION_NODE OfNode;
debug(VRDBG_VR, "VrGetPeer: Entry - Component: %x\n", Component);
if (Component == NULL) {
return NULL;
}
if (!(Component->Version == ARC_VERSION &&
Component->Revision == ARC_REVISION)) {
return NULL;
}
OfNode = CONTAINING_RECORD(Component,
CONFIGURATION_NODE,
Component);
if (OfNode->Peer == NULL ) {
debug(VRDBG_VR, "VrGetPeer: NULL\n");
return NULL;
} else {
debug(VRDBG_VR, "VrGetPeer: Peer %x (%s)\n",
&OfNode->Peer->Component, OfNode->Peer->ComponentName);
return &OfNode->Peer->Component;
}
}
/*++
GetComponent - This function returns a pointer to the component structure
that best matches the path string pointed to by Path. The search algorithm
searches for each component starting with the first and continues
until either the string has been exhausted or no component mathes the
string.
BUBUG The spec. specifies the following two inconsistent return values
1. The function returns a pointer to the last successfully matched
component.
2. If the path is invalid or if a component structure does not
exist, this function returns a null pointer.
--*/
PCONFIGURATION_COMPONENT
VrGetComponent(
IN PCHAR Path
)
{
PCONFIGURATION_NODE Node;
debug(VRDBG_VR, "VrGetComponent: Entry - Path: %s\n", Path);
if (Node = ArcPathToNode(Path)) {
debug(VRDBG_VR, "VrGetComponent: Exit; found %x (%s)\n",
&Node->Component, Node->ComponentName);
return (&Node->Component);
} else {
debug(VRDBG_VR, "VrGetComponent: No match found!\n");
return (NULL);
}
}
/*++
Routine Description:
This functions returns the configuration data associated with Component
in the buffer supplied by ConfigurationData. The length of the data
is stored in the Component structure.
Arguments:
ConfigurationData - Supplies a pointer to a buffer to receive the
configuration data.
Component - Supplies a pointer to a configuration component.
Return Value:
If the configuration data is successfully copied into the buffer
provided by ConfigurationData, ESUCCESS is returned. Otherwise one of
the following error codes is returned.
EINVAL Component is not a valid configuration component, or the
configuration is invalid.
--*/
ARC_STATUS
VrGetConfigurationData (
OUT PVOID ConfigurationData,
IN PCONFIGURATION_COMPONENT Component
)
{
PCONFIGURATION_NODE Node;
ULONG DataSize;
debug(VRDBG_VR, "VrGetConfigurationData: Entry - Config.Data: %x Comp.: %x\n",
ConfigurationData, Component);
if (Component == NULL) {
return EINVAL;
}
DataSize = Component->ConfigurationDataLength;
//
// check the passing parameters
//
if (DataSize == 0) {
return EINVAL;
}
Node = CONTAINING_RECORD( Component, CONFIGURATION_NODE, Component );
#ifdef TOO_STRINGENT
//
// If Component's Parent field is NULL, return EINVAL.
//
if (Node->Parent == NULL) {
return EINVAL;
}
//
// If the Component doesn't point to a valid configuration component,
// return EINVAL.
//
if (!(Node->ConfigurationData->Version == ARC_VERSION &&
Node->ConfigurationData->Revision == ARC_REVISION)) {
return EINVAL;
}
#endif
//
// Copy the data.
//
bcopy((PCHAR)Node->ConfigurationData, ConfigurationData, DataSize);
debug(VRDBG_VR, "VrGetConfigurationData: Exit; copied %d bytes from %x\n",
DataSize, Node->ConfigurationData);
return ESUCCESS;
}
/*
* Name: VrSaveConfiguration
*
* Description:
* This function stores all of the configuration entries into NVRAM,
* including the associated identifier strings and configuration data.
*
* Arguments:
* None.
*
* Return Value:
* Returns ESUCCESS if thesave completed successfully, otherwise returns
* ENOSPC.
*
*/
ARC_STATUS
VrSaveConfiguration(
VOID
)
{
//
// Open Firmware doesn't batch the NVRAM writes; thus this always succeeds.
//
return ESUCCESS;
}
/*++
Routine Description:
This routine initializes the firmware vector in the system parameter
block.
Arguments:
None.
Return Value:
None.
--*/
VOID
VrConfigInitialize(
VOID
)
{
debug(VRDBG_ENTRY, "VrConfigInitialize BEGIN....\n");
(PARC_ADD_CHILD_ROUTINE)
SYSTEM_BLOCK->FirmwareVector[AddChildRoutine] = VrAddChild;
(PARC_DELETE_COMPONENT_ROUTINE)
SYSTEM_BLOCK->FirmwareVector[DeleteComponentRoutine] =
VrDeleteComponent;
(PARC_GET_CHILD_ROUTINE)
SYSTEM_BLOCK->FirmwareVector[GetChildRoutine] = VrGetChild;
(PARC_GET_PARENT_ROUTINE)
SYSTEM_BLOCK->FirmwareVector[GetParentRoutine] = VrGetParent;
(PARC_GET_PEER_ROUTINE)
SYSTEM_BLOCK->FirmwareVector[GetPeerRoutine] = VrGetPeer;
(PARC_GET_DATA_ROUTINE)
SYSTEM_BLOCK->FirmwareVector[GetDataRoutine] =
VrGetConfigurationData;
(PARC_GET_COMPONENT_ROUTINE)
SYSTEM_BLOCK->FirmwareVector[GetComponentRoutine] =
VrGetComponent;
(PARC_SAVE_CONFIGURATION_ROUTINE)
SYSTEM_BLOCK->FirmwareVector[SaveConfigurationRoutine] =
VrSaveConfiguration;
debug(VRDBG_ENTRY, "VrConfigInitialize ....END\n");
}