Example #1
0
NTSTATUS
CmpInitializeHardwareConfiguration(
    IN PLOADER_PARAMETER_BLOCK LoaderBlock
    )
/*++

Routine Description:

    This routine creates \\Registry\Machine\Hardware node in
    the registry and calls SetupTree routine to put the hardware
    information to the registry.

Arguments:

    LoaderBlock - supplies a pointer to the LoaderBlock passed in from the
                  OS Loader.

Returns:

    NTSTATUS code for success or reason of failure.

--*/
{
    NTSTATUS Status;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE BaseHandle;
    PCONFIGURATION_COMPONENT_DATA ConfigurationRoot;
    ULONG Disposition;

    ConfigurationRoot = (PCONFIGURATION_COMPONENT_DATA)LoaderBlock->ConfigurationRoot;

    //
    // Create \\Registry\Machine\Hardware\DeviceMap
    //

    InitializeObjectAttributes(
        &ObjectAttributes,
        &CmRegistryMachineHardwareDeviceMapName,
        0,
        (HANDLE)NULL,
        NULL
        );
    ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;

    Status = NtCreateKey(                   // Paht may already exist
                &BaseHandle,
                KEY_READ | KEY_WRITE,
                &ObjectAttributes,
                TITLE_INDEX_VALUE,
                NULL,
                0,
                &Disposition
                );

    if (!NT_SUCCESS(Status)) {
        return(Status);
    }

    NtClose(BaseHandle);

    ASSERT(Disposition == REG_CREATED_NEW_KEY);

    //
    // Create \\Registry\Machine\Hardware\Description and use the
    // returned handle as the BaseHandle to build the hardware tree.
    //

    InitializeObjectAttributes(
        &ObjectAttributes,
        &CmRegistryMachineHardwareDescriptionName,
        0,
        (HANDLE)NULL,
        NULL
        );
    ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;

    Status = NtCreateKey(                   // Path may already exist
                &BaseHandle,
                KEY_READ | KEY_WRITE,
                &ObjectAttributes,
                TITLE_INDEX_VALUE,
                NULL,
                0,
                &Disposition
                );

    if (!NT_SUCCESS(Status)) {
        return(Status);
    }

    ASSERT(Disposition == REG_CREATED_NEW_KEY);

    //
    // Allocate 16K bytes memory from paged pool for constructing
    // configuration data for controller component.
    // NOTE:  The configuration Data for controller component
    //    usually takes less than 100 bytes.  But on EISA machine, the
    //    EISA configuration information takes more than 10K and up to
    //    64K.  I believe 16K is the reasonable number to handler 99.9%
    //    of the machines.  Therefore, 16K is the initial value.
    //

    CmpConfigurationData = (PCM_FULL_RESOURCE_DESCRIPTOR)ExAllocatePool(
                                        PagedPool,
                                        CmpConfigurationAreaSize
                                        );

    if (CmpConfigurationData == NULL) {
        return(STATUS_INSUFFICIENT_RESOURCES);
    }

    //
    // Call SetupConfigurationTree routine to go over each component
    // of the tree and add component information to registry database.
    //

    if (ConfigurationRoot) {
        Status = CmpSetupConfigurationTree(ConfigurationRoot,
                                           BaseHandle,
                                           -1,
                                           (ULONG)-1);
    } else {
        Status = STATUS_SUCCESS;
    }

    ExFreePool((PVOID)CmpConfigurationData);
    NtClose(BaseHandle);
    return(Status);
}
Example #2
0
NTSTATUS
CmpSetupConfigurationTree(
     IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
     IN HANDLE ParentHandle,
     IN INTERFACE_TYPE InterfaceType,
     IN ULONG BusNumber
     )
/*++

Routine Description:

    This routine traverses loader configuration tree and register
    the hardware information to the registry data base.

    Note to reduce the stack usage on machines with large number of PCI buses,
    we do not recursively process the sibling nodes.  We only recursively
    process the child trees.

Arguments:

    CurrentEntry - Supplies a pointer to a loader configuration
        tree or subtree.

    ParentHandle - Supplies the parent handle of CurrentEntry node.

    InterfaceType - Specify the Interface type of the bus that the
        CurrentEntry component resides.

    BusNumber - Specify the Bus Number of the bus that the CurrentEntry
        component resides.  If Bus number is -1, it means InterfaceType
        and BusNumber are meaningless for this component.

Returns:

    None.

--*/
{
    NTSTATUS Status;
    HANDLE NewHandle;
    USHORT i;
    CONFIGURATION_COMPONENT *Component;
    INTERFACE_TYPE LocalInterfaceType = InterfaceType;
    ULONG LocalBusNumber = BusNumber;
    USHORT DeviceIndexTable[NUMBER_TYPES];

    for (i = 0; i < NUMBER_TYPES; i++) {
        DeviceIndexTable[i] = 0;
    }

    //
    // Process current entry and its siblings
    //

    while (CurrentEntry) {

        //
        // Register current entry first before going down to its children
        //

        Component = &CurrentEntry->ComponentEntry;

        //
        // If the current component is a bus component, we will set up
        // its bus number and Interface type and use them to initialize
        // its subtree.
        //

        if (Component->Class == AdapterClass &&
            CurrentEntry->Parent->ComponentEntry.Class == SystemClass) {

            switch (Component->Type) {

            case EisaAdapter:
                LocalInterfaceType = Eisa;
                LocalBusNumber = CmpTypeCount[EISA_ADAPTER_INDEX]++;
                break;
            case TcAdapter:
                LocalInterfaceType = TurboChannel;
                LocalBusNumber = CmpTypeCount[TURBOCHANNEL_ADAPTER_INDEX]++;
                break;
            case MultiFunctionAdapter:

                //
                // Here we try to distinguish if the Multifunction adapter is
                // Isa, Mca, Internal bus and assign BusNumber based on
                // its interface type (bus type.)
                //

                if (Component->Identifier) {
                    for (i=0; CmpMultifunctionTypes[i].AscString; i++) {
                        if (_stricmp((PCHAR)CmpMultifunctionTypes[i].AscString,
                                    Component->Identifier) == 0) {
                                        break;
                        }
                    }

                    LocalInterfaceType = CmpMultifunctionTypes[i].InterfaceType;
                    LocalBusNumber = CmpMultifunctionTypes[i].Count++;
                }
                break;

            case ScsiAdapter:

                //
                // Set the bus type to internal.
                //

                LocalInterfaceType = Internal;
                LocalBusNumber = CmpTypeCount[ScsiAdapter]++;
                break;

            default:
                LocalInterfaceType = -1;
                LocalBusNumber = CmpUnknownBusCount++;
                break;
            }
        }

        //
        // Initialize and copy current component to hardware registry
        //

        Status = CmpInitializeRegistryNode(
                     CurrentEntry,
                     ParentHandle,
                     &NewHandle,
                     LocalInterfaceType,
                     LocalBusNumber,
                     DeviceIndexTable
                     );

        if (!NT_SUCCESS(Status)) {
            return(Status);
        }

        //
        // Once we are going one level down, we need to clear the TypeCount
        // table for everything under the current component class ...
        //

        if (CurrentEntry->Child) {

            //
            // Process the child entry of current entry
            //

            Status = CmpSetupConfigurationTree(CurrentEntry->Child,
                                               NewHandle,
                                               LocalInterfaceType,
                                               LocalBusNumber
                                               );
            if (!NT_SUCCESS(Status)) {
                NtClose(NewHandle);
                return(Status);
            }
        }
        NtClose(NewHandle);
        CurrentEntry = CurrentEntry->Sibling;
    }
    return(STATUS_SUCCESS);
}
Example #3
0
NTSTATUS
NTAPI
INIT_FUNCTION
CmpSetupConfigurationTree(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
                          IN HANDLE ParentHandle,
                          IN INTERFACE_TYPE InterfaceType,
                          IN ULONG BusNumber)
{
    PCONFIGURATION_COMPONENT Component;
    USHORT DeviceIndexTable[MaximumType + 1] = {0};
    ULONG Interface = InterfaceType, Bus = BusNumber, i;
    NTSTATUS Status;
    HANDLE NewHandle;

    /* Loop each entry */
    while (CurrentEntry)
    {
        /* Check if this is an adapter */
        Component = &CurrentEntry->ComponentEntry;
        if ((Component->Class == AdapterClass) &&
            (CurrentEntry->Parent->ComponentEntry.Class == SystemClass))
        {
            /* Check what kind of adapter it is */
            switch (Component->Type)
            {
                /* EISA */
                case EisaAdapter:

                    /* Fixup information */
                    Interface = Eisa;
                    Bus = CmpTypeCount[EisaAdapter]++;
                    break;

                /* Turbo-channel */
                case TcAdapter:

                    /* Fixup information */
                    Interface = TurboChannel;
                    Bus = CmpTypeCount[TurboChannel]++;
                    break;

                /* ISA, PCI, etc busses */
                case MultiFunctionAdapter:

                    /* Check if we have an  identifier */
                    if (Component->Identifier)
                    {
                        /* Loop each multi-function adapter type */
                        for (i = 0; CmpMultifunctionTypes[i].Identifier; i++)
                        {
                            /* Check for a name match */
                            if (!_stricmp(CmpMultifunctionTypes[i].Identifier,
                                          Component->Identifier))
                            {
                                /* Match found */
                                break;
                            }
                        }

                        /* Fix up information */
                        Interface = CmpMultifunctionTypes[i].InterfaceType;
                        Bus = CmpMultifunctionTypes[i].Count++;
                    }
                    break;

                /* SCSI Bus */
                case ScsiAdapter:

                    /* Fix up */
                    Interface = Internal;
                    Bus = CmpTypeCount[ScsiAdapter]++;
                    break;

                /* Unknown */
                default:
                    Interface = -1;
                    Bus = CmpUnknownBusCount++;
                    break;
            }
        }

        /* Dump information on the component */

        /* Setup the hardware node */
        Status = CmpInitializeRegistryNode(CurrentEntry,
                                           ParentHandle,
                                           &NewHandle,
                                           Interface,
                                           Bus,
                                           DeviceIndexTable);
        if (!NT_SUCCESS(Status)) return Status;

        /* Check for children */
        if (CurrentEntry->Child)
        {
            /* Recurse child */
            Status = CmpSetupConfigurationTree(CurrentEntry->Child,
                                               NewHandle,
                                               Interface,
                                               Bus);
            if (!NT_SUCCESS(Status))
            {
                /* Fail */
                NtClose(NewHandle);
                return Status;
            }
        }

        /* Get to the next entry */
        NtClose(NewHandle);
        CurrentEntry = CurrentEntry->Sibling;
    }

    /* We're done */
    return STATUS_SUCCESS;
}
Example #4
0
NTSTATUS
NTAPI
INIT_FUNCTION
CmpInitializeHardwareConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
    NTSTATUS Status;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE KeyHandle;
    ULONG Disposition;
    UNICODE_STRING KeyName;

    /* Setup the key name */
    RtlInitUnicodeString(&KeyName,
                         L"\\Registry\\Machine\\Hardware\\DeviceMap");
    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    /* Create the device map key */
    Status = NtCreateKey(&KeyHandle,
                         KEY_READ | KEY_WRITE,
                         &ObjectAttributes,
                         0,
                         NULL,
                         0,
                         &Disposition);
    if (!NT_SUCCESS(Status)) return Status;
    NtClose(KeyHandle);

    /* Nobody should've created this key yet! */
    ASSERT(Disposition == REG_CREATED_NEW_KEY);

    /* Setup the key name */
    RtlInitUnicodeString(&KeyName,
                         L"\\Registry\\Machine\\Hardware\\Description");
    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    /* Create the description key */
    Status = NtCreateKey(&KeyHandle,
                          KEY_READ | KEY_WRITE,
                          &ObjectAttributes,
                          0,
                          NULL,
                          0,
                          &Disposition);
    if (!NT_SUCCESS(Status)) return Status;

    /* Nobody should've created this key yet! */
    ASSERT(Disposition == REG_CREATED_NEW_KEY);

    /* Allocate the configuration data buffer */
    CmpConfigurationData = ExAllocatePoolWithTag(PagedPool,
                                                 CmpConfigurationAreaSize,
                                                 TAG_CM);
    if (!CmpConfigurationData) return STATUS_INSUFFICIENT_RESOURCES;

    /* Check if we got anything from NTLDR */
    if (LoaderBlock->ConfigurationRoot)
    {
        /* Setup the configuration tree */
        Status = CmpSetupConfigurationTree(LoaderBlock->ConfigurationRoot,
                                           KeyHandle,
                                           -1,
                                           -1);
    }
    else
    {
        /* Nothing else to do */
        Status = STATUS_SUCCESS;
    }

    /* Close our handle, free the buffer and return status */
    ExFreePoolWithTag(CmpConfigurationData, TAG_CM);
    NtClose(KeyHandle);
    return Status;
}
Example #5
0
NTSTATUS
CmpInitializeHardwareConfiguration(
    IN PLOADER_PARAMETER_BLOCK LoaderBlock
    )
/*++

Routine Description:

    This routine creates \\Registry\Machine\Hardware node in
    the registry and calls SetupTree routine to put the hardware
    information to the registry.

Arguments:

    LoaderBlock - supplies a pointer to the LoaderBlock passed in from the
                  OS Loader.

Returns:

    NTSTATUS code for sucess or reason of failure.

--*/
{
    NTSTATUS Status;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE BaseHandle;
    PCONFIGURATION_COMPONENT_DATA ConfigurationRoot;
    ULONG Disposition;

    ConfigurationRoot = (PCONFIGURATION_COMPONENT_DATA)LoaderBlock->ConfigurationRoot;
    if (ConfigurationRoot) {

#ifdef _X86_

        //
        //  The following strings found in the registry identify obscure,
        //  yet market dominant, non PC/AT compatible i386 machine in Japan.
        //

#define MACHINE_TYPE_FUJITSU_FMR_NAME_A    "FUJITSU FMR-"
#define MACHINE_TYPE_NEC_PC98_NAME_A       "NEC PC-98"

        {
            PCONFIGURATION_COMPONENT_DATA SystemNode;
            ULONG JapanMachineId;

            //
            // For Japan, we have to special case some non PC/AT machines, so
            // determine at this time what kind of platform we are on:
            //
            // NEC PC9800 Compatibles/Fujitsu FM-R Compatibles/IBM PC/AT Compatibles
            //
            // Default is PC/AT compatible.
            //

            JapanMachineId = MACHINE_TYPE_PC_AT_COMPATIBLE;

            //
            // Find the hardware description node
            //

            SystemNode = KeFindConfigurationEntry(ConfigurationRoot,
                                                  SystemClass,
                                                  MaximumType,
                                                  NULL);

            //
            // Did we find something?
            //

            if (SystemNode) {

                //
                // Check platform from identifier string
                //

                if (RtlCompareMemory(SystemNode->ComponentEntry.Identifier,
                                     MACHINE_TYPE_NEC_PC98_NAME_A,
                                     sizeof(MACHINE_TYPE_NEC_PC98_NAME_A) - 1) ==
                    sizeof(MACHINE_TYPE_NEC_PC98_NAME_A) - 1) {

                    //
                    // we are running on NEC PC-9800 comaptibles.
                    //

                    JapanMachineId = MACHINE_TYPE_PC_9800_COMPATIBLE;
                    SetNEC_98;

                } else if (RtlCompareMemory(SystemNode->ComponentEntry.Identifier,
                                            MACHINE_TYPE_FUJITSU_FMR_NAME_A,
                                            sizeof(MACHINE_TYPE_FUJITSU_FMR_NAME_A) - 1) ==
                           sizeof(MACHINE_TYPE_FUJITSU_FMR_NAME_A) - 1) {

                    //
                    // we are running on Fujitsu FMR comaptibles.
                    //

                    JapanMachineId = MACHINE_TYPE_FMR_COMPATIBLE;
                }
            }

            //
            //  Now 'or' this value into the kernel global.
            //

            KeI386MachineType |= JapanMachineId;
        }
#endif //_X86_

        //
        // Create \\Registry\Machine\Hardware\DeviceMap
        //

        InitializeObjectAttributes(
            &ObjectAttributes,
            &CmRegistryMachineHardwareDeviceMapName,
            0,
            (HANDLE)NULL,
            NULL
            );
        ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;

        Status = NtCreateKey(                   // Paht may already exist
                    &BaseHandle,
                    KEY_READ | KEY_WRITE,
                    &ObjectAttributes,
                    TITLE_INDEX_VALUE,
                    NULL,
                    0,
                    &Disposition
                    );

        if (!NT_SUCCESS(Status)) {
            return(Status);
        }

        NtClose(BaseHandle);

        ASSERT(Disposition == REG_CREATED_NEW_KEY);

        //
        // Create \\Registry\Machine\Hardware\Description and use the
        // returned handle as the BaseHandle to build the hardware tree.
        //

        InitializeObjectAttributes(
            &ObjectAttributes,
            &CmRegistryMachineHardwareDescriptionName,
            0,
            (HANDLE)NULL,
            NULL
            );
        ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;

        Status = NtCreateKey(                   // Path may already exist
                    &BaseHandle,
                    KEY_READ | KEY_WRITE,
                    &ObjectAttributes,
                    TITLE_INDEX_VALUE,
                    NULL,
                    0,
                    &Disposition
                    );

        if (!NT_SUCCESS(Status)) {
            return(Status);
        }

        ASSERT(Disposition == REG_CREATED_NEW_KEY);

        //
        // Allocate 16K bytes memory from paged pool for constructing
        // configuration data for controller component.
        // NOTE:  The configuration Data for controller component
        //    usually takes less than 100 bytes.  But on EISA machine, the
        //    EISA configuration information takes more than 10K and up to
        //    64K.  I believe 16K is the reasonable number to handler 99.9%
        //    of the machines.  Therefore, 16K is the initial value.
        //

        CmpConfigurationData = (PCM_FULL_RESOURCE_DESCRIPTOR)ExAllocatePool(
                                            PagedPool,
                                            CmpConfigurationAreaSize
                                            );

        if (CmpConfigurationData == NULL) {
            return(STATUS_INSUFFICIENT_RESOURCES);
        }

        //
        // Call SetupConfigurationTree routine to go over each component
        // of the tree and add component information to registry database.
        //

        Status = CmpSetupConfigurationTree(ConfigurationRoot,
                                           BaseHandle,
                                           -1,
                                           (ULONG)-1
                                           );
        ExFreePool((PVOID)CmpConfigurationData);
        NtClose(BaseHandle);
        return(Status);
    } else {
        return(STATUS_SUCCESS);
    }
}