Ejemplo n.º 1
0
BOOLEAN
IopInitializeBusKey(
    IN HANDLE KeyHandle,
    IN PUNICODE_STRING KeyName,
    IN OUT PVOID WorkName
    )

/*++

Routine Description:

    This routine is a callback function for IopApplyFunctionToSubKeys.
    It is called for each subkey under HKLM\System\Enum.

Arguments:

    KeyHandle - Supplies a handle to this key.

    KeyName - Supplies the name of this key.

    WorkName - points to the unicodestring which describes the path up to
        this key.

Returns:

    TRUE to continue the enumeration.
    FALSE to abort it.

--*/
{
    USHORT length;
    PWSTR p;
    PUNICODE_STRING unicodeName = WorkName;
    NTSTATUS status;

    length = unicodeName->Length;

    p = unicodeName->Buffer;
    if ( unicodeName->Length / sizeof(WCHAR) != 0) {
        p += unicodeName->Length / sizeof(WCHAR);
        *p = OBJ_NAME_PATH_SEPARATOR;
        unicodeName->Length += sizeof (WCHAR);
    }

    RtlAppendStringToString((PSTRING)unicodeName, (PSTRING)KeyName);

    //
    // Enumerate all subkeys under the System\Enum.
    //

    status = IopApplyFunctionToSubKeys(KeyHandle,
                                       NULL,
                                       KEY_ALL_ACCESS,
                                       TRUE,
                                       IopInitializeDeviceKey,
                                       WorkName
                                       );
    unicodeName->Length = length;      // Should be zero
    return TRUE;
}
Ejemplo n.º 2
0
NTSTATUS
IopInitializeRegistryNode(
    IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
    IN HANDLE EnumRootHandle,
    IN PUNICODE_STRING WorkName,
    IN PUNICODE_STRING KeyName,
    IN ULONG Instance,
    IN INTERFACE_TYPE InterfaceType,
    IN BUS_DATA_TYPE BusDataType,
    IN ULONG BusNumber
    )

/*++

Routine Description:

    This routine creates a node for the current firmware component
    and puts component data to the data part of the node.

Arguments:

    CurrentEntry - Supplies a pointer to a configuration component.

    EnumRootHandle - Supplies the handle of Enum key under which we will build
        our new key.

    WorkName - Supplies a point to a unicode string which is the name of
        its parent node.

    KeyName - Suppiles a pointer to a UNICODE string which will be the name
        of the new key.

    Instance - Supplies an instance number of KeyName.

    InterfaceType - Specify the Interface type of the bus that the
        CurrentEntry component resides. (See BusNumber also)

    BusDataType - Specifies the configuration type of the bus.

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

Returns:

    None.

--*/
{

    NTSTATUS status;
    HANDLE handle, keyHandle;
    UNICODE_STRING unicodeName, unicodeValueName;
    PCONFIGURATION_COMPONENT component;
    PKEY_VALUE_FULL_INFORMATION keyValueInformation, serviceInfo = NULL;
    PWSTR service = (PWSTR)NULL, p;
    ULONG disposition, foundAlready, dataLength = 0;
    ULONG serviceLength = 0, tmpValue, emptyResource = 0;
    BOOLEAN newKey = FALSE;
    PCM_RESOURCE_LIST dataArea, configuration1;
    CHAR unicodeBuffer[20];
    PUCHAR resourceBuffer = IopPnpScratchBuffer2;
    BOOLEAN freeDataArea = FALSE, isDuplicated;

    component = &CurrentEntry->ComponentEntry;

    //
    // Open/Create a key under Enum/Root bransh. If fails,
    // exit (nothing we can do.)
    //

    status = IopOpenRegistryKeyPersist (
                     &keyHandle,
                     EnumRootHandle,
                     KeyName,
                     KEY_ALL_ACCESS,
                     TRUE,
                     &disposition
                     );
    if (!NT_SUCCESS(status)) {
        return status;
    }

#if 0  // not sure if we need it

    //
    // If the key is newly created, set its NewDevice value to TRUE so that
    // user mode Pnp mgr can initiate a device installation.  The NewDevice
    // value will be reset by user mode Pnp mgr.  SO , we don't touch it here.
    //

    if (disposition == REG_CREATED_NEW_KEY) {
        newKey = TRUE;
        PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_NEWDEVICE);
        tmpValue = 1;
        NtSetValueKey(
                    keyHandle,
                    &unicodeValueName,
                    TITLE_INDEX_VALUE,
                    REG_DWORD,
                    &tmpValue,
                    sizeof (tmpValue)
                    );

        PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_STATIC);
        NtSetValueKey(
                    keyHandle,
                    &unicodeValueName,
                    TITLE_INDEX_VALUE,
                    REG_DWORD,
                    &tmpValue,
                    sizeof(tmpValue)
                    );
    }

#endif

    if (component->Type > OtherController) {

        //
        // The current component is a peripheral.
        //

        //
        // Create a new instance key under KeyName
        //

        PiUlongToInstanceKeyUnicodeString(&unicodeName, unicodeBuffer, 20, Instance);
        status = IopOpenRegistryKeyPersist (
                     &handle,
                     keyHandle,
                     &unicodeName,
                     KEY_ALL_ACCESS,
                     TRUE,
                     &disposition
                     );
        NtClose(keyHandle);
        if (!NT_SUCCESS(status)) {
            goto init_Exit;
        }


        //
        //
        // Create all the default value entry for the newly created key.
        // Service =  (do NOT create)
        // BaseDevicePath = WorkName
        // FoundAtEnum = 1
        // InterfaceType = InterfaceType     (only for bus device)
        // SystemBusNumber = BusNumber       (only for bus device)
        // BusDataType = BusDataType         (only for bus device)
        //

        PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_BASEDEVICEPATH);
        p = WorkName->Buffer;
        p += WorkName->Length / sizeof(WCHAR);
        *p = UNICODE_NULL;
        NtSetValueKey(
                    handle,
                    &unicodeValueName,
                    TITLE_INDEX_VALUE,
                    REG_SZ,
                    WorkName->Buffer,
                    WorkName->Length + sizeof (UNICODE_NULL)
                    );

        PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_FOUNDATENUM);
        tmpValue = 1;
        NtSetValueKey(
                    handle,
                    &unicodeValueName,
                    TITLE_INDEX_VALUE,
                    REG_DWORD,
                    &tmpValue,
                    sizeof(tmpValue)
                    );

        PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_SYSTEMBUSNUMBER);
        tmpValue = BusNumber;
        NtSetValueKey(
                    handle,
                    &unicodeValueName,
                    TITLE_INDEX_VALUE,
                    REG_DWORD,
                    &tmpValue,
                    sizeof(tmpValue)
                    );

        PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_INTERFACETYPE);
        tmpValue = InterfaceType;
        NtSetValueKey(
                    handle,
                    &unicodeValueName,
                    TITLE_INDEX_VALUE,
                    REG_DWORD,
                    &tmpValue,
                    sizeof(tmpValue)
                    );

        PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_BUSDATATYPE);
        tmpValue = BusDataType;
        NtSetValueKey(
                    handle,
                    &unicodeValueName,
                    TITLE_INDEX_VALUE,
                    REG_DWORD,
                    &tmpValue,
                    sizeof(tmpValue)
                    );

        NtClose(handle);

        //
        // Append keyanme and instance key name to workname
        // (In fact, we don't need to do this because there
        // is nothing under peripheral component.)
        //
        //
        // Append KeyName to workname
        //

        p = WorkName->Buffer;
        p += WorkName->Length / sizeof(WCHAR);
        *p = OBJ_NAME_PATH_SEPARATOR;
        WorkName->Length += sizeof (WCHAR);
        RtlAppendStringToString((PSTRING)WorkName,
                                (PSTRING)KeyName);

    } else {

        //
        // Current component is a controller
        //

        //
        // Append KeyName to workname
        //

        p = WorkName->Buffer;
        p += WorkName->Length / sizeof(WCHAR);
        *p = OBJ_NAME_PATH_SEPARATOR;
        WorkName->Length += sizeof (WCHAR);
        RtlAppendStringToString((PSTRING)WorkName,
                                (PSTRING)KeyName);

        //
        // We need to convert the h/w tree configuration data format from
        // CM_PARTIAL_RESOURCE_DESCRIPTIOR to CM_RESOURCE_LIST.
        //

        if (CurrentEntry->ConfigurationData) {

            //
            // This component has configuration data, we copy the data
            // to our work area, add some more data items and copy the new
            // configuration data to the registry.
            //

            dataLength = component->ConfigurationDataLength +
                          FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR,
                          PartialResourceList) +
                          FIELD_OFFSET(CM_RESOURCE_LIST, List);
            dataArea = (PCM_RESOURCE_LIST)resourceBuffer;

            //
            // Make sure our reserved area is big enough to hold the data.
            //

            if (dataLength > PNP_LARGE_SCRATCH_BUFFER_SIZE) {

                //
                // If reserved area is not big enough, we resize our reserved
                // area.  If, unfortunately, the reallocation fails, we simply
                // loss the configuration data of this particular component.
                //

                dataArea = (PCM_RESOURCE_LIST)ExAllocatePool(
                                                PagedPool,
                                                dataLength
                                                );

                if (dataArea) {
                    freeDataArea = TRUE;
                }
            }
            if (dataArea) {
                RtlMoveMemory((PUCHAR)&dataArea->List->PartialResourceList.Version,
                              CurrentEntry->ConfigurationData,
                              component->ConfigurationDataLength
                              );
                dataArea->Count = 1;
                dataArea->List[0].InterfaceType = InterfaceType;
                dataArea->List[0].BusNumber = BusNumber;
            }
        }

        if (CurrentEntry->ConfigurationData == NULL || !dataArea) {

            //
            // This component has NO configuration data (or we can't resize
            // our reserved area to hold the data), we simple add whatever
            // is required to set up a CM_FULL_RESOURCE_LIST.
            //

            dataArea = (PCM_RESOURCE_LIST)&emptyResource;
            dataLength = FIELD_OFFSET(CM_RESOURCE_LIST, List);
        }

        if (!newKey) {

            //
            // If the key exists already, we need to check if current entry
            // already being converted (most likely the answer is yes.).  If it already
            // converted, we simply set "FoundAtEnum=" to TRUE.  Otherwise, we will
            // create it.
            //

            tmpValue = 0;
            PiUlongToInstanceKeyUnicodeString(&unicodeName, unicodeBuffer, 20, tmpValue);
            status = IopOpenRegistryKey (&handle,
                                         keyHandle,
                                         &unicodeName,
                                         KEY_ALL_ACCESS,
                                         FALSE
                                         );
            while (NT_SUCCESS(status)) {

                //
                // if the current key has been Found/Enum'ed already, we need
                // to skip it.
                //

                foundAlready = 0;
                status = IopGetRegistryValue (handle,
                                              REGSTR_VALUE_FOUNDATENUM,
                                              &keyValueInformation);
                if (NT_SUCCESS(status)) {
                    if (keyValueInformation->DataLength != 0) {
                        foundAlready = *(PULONG)KEY_VALUE_DATA(keyValueInformation);
                    }
                    ExFreePool(keyValueInformation);
                }

                if (!foundAlready) {
                    keyValueInformation = NULL;
                    status = IopGetRegistryValue (handle,
                                                  REGSTR_VALUE_DETECTSIGNATURE,
                                                  &keyValueInformation);
                    if (NT_SUCCESS(status) && keyValueInformation->DataLength != 0) {
                        configuration1 = (PCM_RESOURCE_LIST)KEY_VALUE_DATA(keyValueInformation);
                    } else if (status == STATUS_OBJECT_NAME_NOT_FOUND ||
                               keyValueInformation->DataLength == 0) {

                        //
                        // If no "DetectSignature =" value entry, we set up an empty
                        // CM_RESOURCE_LIST.
                        //

                        configuration1 = (PCM_RESOURCE_LIST)&emptyResource;
                    }

                    //
                    // To detect ARC duplicated components, we should be able
                    // to simply compare the RAW resource list.  If they are the
                    // same *most likely* they are duplicates.  This includes
                    // the case that both resource list are empty.  (if they
                    // are empty, we should be able to simply pick up the
                    // key and use it.)
                    //

                    isDuplicated = IopIsDuplicatedResourceLists(
                                       configuration1,
                                       dataArea);
                    if (!isDuplicated) {

                        //
                        // BUGBUG We should also check for bus info.
                        //

                        isDuplicated = IopIsDuplicatedDevices(
                                               configuration1,
                                               dataArea,
                                               NULL,
                                               NULL
                                               );
                    }

                    if (keyValueInformation) {
                        ExFreePool(keyValueInformation);
                    }
                    if (isDuplicated) {
                        PiWstrToUnicodeString( &unicodeValueName, REGSTR_VALUE_FOUNDATENUM);
                        tmpValue = 1;
                        status = NtSetValueKey(handle,
                                               &unicodeValueName,
                                               TITLE_INDEX_VALUE,
                                               REG_DWORD,
                                               &tmpValue,
                                               sizeof(tmpValue)
                                               );
                        NtClose(handle);
                        NtClose(keyHandle);
                        goto init_Exit0;
                    }
                }
                NtClose(handle);
                tmpValue++;
                PiUlongToInstanceKeyUnicodeString(&unicodeName,
                                                  unicodeBuffer,
                                                  20,
                                                  tmpValue);
                status = IopOpenRegistryKey (&handle,
                                             keyHandle,
                                             &unicodeName,
                                             KEY_ALL_ACCESS,
                                             FALSE
                                             );
            }

            Instance = tmpValue;
        }

        //
        // We need to create the new instance key if we can come here...
        //

        PiUlongToInstanceKeyUnicodeString(&unicodeName, unicodeBuffer, 20, Instance);
        status = IopOpenRegistryKeyPersist (
                     &handle,
                     keyHandle,
                     &unicodeName,
                     KEY_ALL_ACCESS,
                     TRUE,
                     NULL
                     );
        NtClose(keyHandle);
        PNP_ASSERT(NT_SUCCESS(status), "IopInitRegistryNode: Fail to create new key.");
        if (!NT_SUCCESS(status)) {
            goto init_Exit;
        }

        //
        // Newly created key --
        //
        // Create all the default value entry for the newly created key.
        // Service =
#if 0
        // NewInstance = 1
#endif
        // FoundAtEnum = 1
        // Configuration =
        // InterfaceType = InterfaceType
        // SystemBusNumber = BusNumber
        // BusDataType = BusDataType
        //

#if 0
        PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_NEWINSTANCE);
        tmpValue = 1;
        NtSetValueKey(
                    handle,
                    &unicodeValueName,
                    TITLE_INDEX_VALUE,
                    REG_DWORD,
                    &tmpValue,
                    sizeof(tmpValue)
                    );
#endif

        PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_FOUNDATENUM);
        tmpValue = 1;
        NtSetValueKey(
                    handle,
                    &unicodeValueName,
                    TITLE_INDEX_VALUE,
                    REG_DWORD,
                    &tmpValue,
                    sizeof(tmpValue)
                    );

#if 0

        //
        // SystemBusNumber, InterfaceType and BusDataType are for Bus
        // devices only. For ntdetect/arc detected devices, we don't set
        // up bus devices.
        //

        PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_SYSTEMBUSNUMBER);
        tmpValue = BusNumber;
        NtSetValueKey(
                    handle,
                    &unicodeValueName,
                    TITLE_INDEX_VALUE,
                    REG_DWORD,
                    &tmpValue,
                    sizeof(tmpValue)
                    );

        PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_INTERFACETYPE);
        tmpValue = InterfaceType;
        NtSetValueKey(
                    handle,
                    &unicodeValueName,
                    TITLE_INDEX_VALUE,
                    REG_DWORD,
                    &tmpValue,
                    sizeof(tmpValue)
                    );

        PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_BUSDATATYPE);
        tmpValue = BusDataType;
        NtSetValueKey(
                    handle,
                    &unicodeValueName,
                    TITLE_INDEX_VALUE,
                    REG_DWORD,
                    &tmpValue,
                    sizeof(tmpValue)
                    );
#endif

        PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_CONFIGURATION);
        NtSetValueKey(
                    handle,
                    &unicodeValueName,
                    TITLE_INDEX_VALUE,
                    REG_RESOURCE_LIST,
                    dataArea,
                    dataLength
                    );

        PiWstrToUnicodeString(&unicodeValueName, REGSTR_VALUE_DETECTSIGNATURE);
        NtSetValueKey(
                    handle,
                    &unicodeValueName,
                    TITLE_INDEX_VALUE,
                    REG_RESOURCE_LIST,
                    dataArea,
                    dataLength
                    );
        NtClose(handle);
    }
    status = STATUS_SUCCESS;
init_Exit0:
    p = WorkName->Buffer;
    p += WorkName->Length / sizeof(WCHAR);
    *p = OBJ_NAME_PATH_SEPARATOR;
    WorkName->Length += sizeof (WCHAR);
    RtlAppendStringToString((PSTRING)WorkName,
                            (PSTRING)&unicodeName);
init_Exit:
    if (freeDataArea) {
        ExFreePool(dataArea);
    }
    if (serviceInfo) {
        ExFreePool(serviceInfo);
    }
    return(status);

}
Ejemplo n.º 3
0
NTSTATUS
IopInitializeHardwareConfiguration(
    IN PLOADER_PARAMETER_BLOCK LoaderBlock
    )

/*++

Routine Description:

    This routine creates \\Registry\Machine\Sysem\Enum\Root node in
    the registry and calls worker routine to put the hardware
    information detected by arc firmware/ntdetect to the Enum\Root
    branch.
    This routine and its worker routines use both pnp scratch buffer1
    and scratch buffer2.

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;
    HANDLE baseHandle;
    UNICODE_STRING unicodeName, rootName;
    PCONFIGURATION_COMPONENT_DATA currentEntry;
    PCONFIGURATION_COMPONENT component;
    INTERFACE_TYPE interfaceType;
    BUS_DATA_TYPE busDataType;
    ULONG busNumber, i;

    unicodeName.Length = 0;
    unicodeName.MaximumLength = PNP_LARGE_SCRATCH_BUFFER_SIZE;
    unicodeName.Buffer = IopPnpScratchBuffer1;
    PiWstrToUnicodeString(&rootName, REGSTR_KEY_ROOTENUM);
    RtlAppendStringToString((PSTRING)&unicodeName,
                            (PSTRING)&rootName);
    currentEntry = (PCONFIGURATION_COMPONENT_DATA)LoaderBlock->ConfigurationRoot;

    if (currentEntry) {

        //
        // Open\Create \\Registry\Machine\System\CurrentControlSet\Enum\Root and use the
        // returned handle as the BaseHandle to build the Arc keys.
        //

        status = IopOpenRegistryKey(&baseHandle,
                                    NULL,
                                    &CmRegistryMachineSystemCurrentControlSetEnumRootName,
                                    KEY_ALL_ACCESS,
                                    FALSE
                                    );
        if (!NT_SUCCESS(status)) {
            return status;
        }

        currentEntry = currentEntry->Child;

        while (currentEntry != NULL) {

            component = &currentEntry->ComponentEntry;

            //
            // We are only interested in isa, or internal bus component.
            // For other busses, they will be picked up by bus enumerators.
            //

            if (component->Class == AdapterClass) {
                if (component->Type == MultiFunctionAdapter) {
                    _strupr(component->Identifier);
                    if (!strstr(component->Identifier, "PNP")) {
                        if (!_stricmp(component->Identifier, "ISA")) {
                            interfaceType = Isa;
                            busNumber = 0;
                            busDataType = MaximumBusDataType;
                        } else if (!_stricmp(component->Identifier, "INTERNAL")) {
                            interfaceType = Internal;
                            busNumber = 0;
                            busDataType = MaximumBusDataType;
#if defined(_X86_)
                        } else if (!_stricmp(component->Identifier, "MCA")) {
                            interfaceType = MicroChannel;
                            busNumber = 0;
                            busDataType = Pos;
#endif
                        } else {
                            currentEntry = currentEntry->Sibling;
                            continue;
                        }
                    }
                }
#if defined(_X86_)
                  else if (component->Type == EisaAdapter) {
                      interfaceType = Eisa;
                      busNumber = 0;
                      busDataType = EisaConfiguration;
                } else {
                    currentEntry = currentEntry->Sibling;
                    continue;
                }
#endif
#if 0
                //
                // Reset peripheral count before processing a bus.
                //

                for (i = 0; i <= MaximumType; i++) {
                     IopPeripheralCount[i] = 0;
                }
#endif
                status = IopSetupConfigurationTree(currentEntry->Child,
                                                   baseHandle,
                                                   &unicodeName,
                                                   interfaceType,
                                                   busDataType,
                                                   busNumber
                                                   );
            }
            currentEntry = currentEntry->Sibling;
        }
        NtClose(baseHandle);
        return(status);
    } else {
        return STATUS_SUCCESS;
    }
}
Ejemplo n.º 4
0
BOOLEAN
IopInitializeDeviceInstanceKey(
    IN HANDLE KeyHandle,
    IN PUNICODE_STRING KeyName,
    IN OUT PVOID WorkName
    )

/*++

Routine Description:

    This routine is a callback function for IopApplyFunctionToSubKeys.
    It is called for each subkey under HKLM\System\Enum\BusKey\DeviceKey.

Arguments:

    KeyHandle - Supplies a handle to this key.

    KeyName - Supplies the name of this key.

    WorkName - points to the unicodestring which describes the path up to
        this key.

Returns:

    TRUE to continue the enumeration.
    FALSE to abort it.

--*/
{
    UNICODE_STRING unicodeName, serviceName;
    PKEY_VALUE_FULL_INFORMATION keyValueInformation;
    NTSTATUS status;
    BOOLEAN duplicate = FALSE;
    ULONG foundAtEnum, deviceFlags, instance, tmpValue1, tmpValue2;
    USHORT length;
    PUNICODE_STRING pUnicode;

    //
    // Get the "Problem" value entry to determine what we need to do with
    // the device instance key.
    //

    deviceFlags = 0;
    status = IopGetRegistryValue ( KeyHandle,
                                   REGSTR_VALUE_PROBLEM,
                                   &keyValueInformation
                                   );
    if (NT_SUCCESS(status)) {
        if ((keyValueInformation->Type == REG_DWORD) &&
            (keyValueInformation->DataLength >= sizeof(ULONG))) {
            deviceFlags = *(PULONG)KEY_VALUE_DATA(keyValueInformation);
        }
        ExFreePool(keyValueInformation);
    }

    if (deviceFlags == CM_PROB_MOVED) {

        //
        // If the device instance was moved, we simply delete the key.
        // The key will be deleted once the caller close the open handle.
        //

        NtDeleteKey(KeyHandle);
        return TRUE;
    }

    //
    // The device instance key exists.  We need to propagate the ConfigFlag
    // to problem and StatusFlags
    //

    deviceFlags = 0;
    status = IopGetRegistryValue(KeyHandle,
                                 REGSTR_VALUE_CONFIG_FLAGS,
                                 &keyValueInformation);
    if (NT_SUCCESS(status)) {
        if ((keyValueInformation->Type == REG_DWORD) &&
            (keyValueInformation->DataLength >= sizeof(ULONG))) {
            deviceFlags = *(PULONG)KEY_VALUE_DATA(keyValueInformation);
        }
        ExFreePool(keyValueInformation);
    }
    if (deviceFlags & CONFIGFLAG_REINSTALL) {

        tmpValue1 = CM_PROB_REINSTALL;      // Problem
        tmpValue2 = DN_HAS_PROBLEM;         // StatusFlags
    } else {
        tmpValue1 = tmpValue2 = 0;
    }
    PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_PROBLEM);
    NtSetValueKey(KeyHandle,
                  &unicodeName,
                  TITLE_INDEX_VALUE,
                  REG_DWORD,
                  &tmpValue1,
                  sizeof(tmpValue1)
                  );

    PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_STATUSFLAGS);
    NtSetValueKey(KeyHandle,
                  &unicodeName,
                  TITLE_INDEX_VALUE,
                  REG_DWORD,
                  &tmpValue2,
                  sizeof(tmpValue2)
                  );

    //
    // Get the "DuplicateOf" value entry to determine if the device instance
    // should be registered.  If the device instance is duplicate, We don't
    // add it to its service key's enum branch.
    //

    status = IopGetRegistryValue ( KeyHandle,
                                   REGSTR_VALUE_DUPLICATEOF,
                                   &keyValueInformation
                                   );
    if (NT_SUCCESS(status)) {
        if ((keyValueInformation->Type == REG_SZ) &&
            (keyValueInformation->DataLength > 0)) {
            duplicate = TRUE;
        }
        ExFreePool(keyValueInformation);
    }

    if (!duplicate) {

        //
        // Combine WorkName and KeyName to form device instance path
        // and register this device instance by
        // constructing new value entry for ServiceKeyName\Enum key.
        // i.e., <Number> = <PathToSystemEnumBranch>
        //

        pUnicode = (PUNICODE_STRING)WorkName;
        length = pUnicode->Length;                  // Save WorkName
        if (pUnicode->Buffer[pUnicode->Length / sizeof(WCHAR) - 1] != OBJ_NAME_PATH_SEPARATOR) {
            pUnicode->Buffer[pUnicode->Length / sizeof(WCHAR)] = OBJ_NAME_PATH_SEPARATOR;
            pUnicode->Length += 2;
        }
        RtlAppendStringToString((PSTRING)pUnicode, (PSTRING)KeyName);
        PpDeviceRegistration(pUnicode, TRUE);
        pUnicode->Length = length;                  // Restore WorkName
    }

    //
    // Get the "Service=" value entry from KeyHandle
    //

    keyValueInformation = NULL;
    serviceName.Length = 0;
    status = IopGetRegistryValue ( KeyHandle,
                                   REGSTR_VALUE_SERVICE,
                                   &keyValueInformation
                                   );
    if (NT_SUCCESS(status)) {

        //
        // Append the new instance to its corresponding
        // Service\Name\Enum.
        //

        if ((keyValueInformation->Type == REG_SZ) &&
            (keyValueInformation->DataLength != 0)) {

            //
            // Set up ServiceKeyName unicode string
            //

            IopRegistryDataToUnicodeString(
                              &serviceName,
                              (PWSTR)KEY_VALUE_DATA(keyValueInformation),
                              keyValueInformation->DataLength
                              );
        }

        //
        // Do not Free keyValueInformation
        //

    }

    //
    // The Pnp mgr set FoundAtEnum to 0 for everything under system\ccs\enum.
    // For the stuff under Root we need to set them to 1 except if their
    // CsConfigFlags was set to CSCONFIGFLAG_DO_NOT_CREATE.
    //

    foundAtEnum = 1;
    status = RtlUnicodeStringToInteger(KeyName, 10, &instance);
    if (NT_SUCCESS(status)) {
        if (serviceName.Length != 0) {
            status = IopGetDeviceInstanceCsConfigFlags(
                         &serviceName,
                         instance,
                         &deviceFlags
                         );

            if (NT_SUCCESS(status) && (deviceFlags & CSCONFIGFLAG_DO_NOT_CREATE)) {
                foundAtEnum = 0;
            }
        }
    }
    if (keyValueInformation) {
        ExFreePool(keyValueInformation);
    }
    PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_FOUNDATENUM);
    NtSetValueKey(KeyHandle,
                  &unicodeName,
                  TITLE_INDEX_VALUE,
                  REG_DWORD,
                  &foundAtEnum,
                  sizeof(foundAtEnum)
                  );

    //
    // Clean up "NtLogicalDevicePaths=" and "NtPhysicalDevicePaths=" of this key
    //

    PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_NT_PHYSICAL_DEVICE_PATHS);
    NtDeleteValueKey(KeyHandle, &unicodeName);

    PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_NT_LOGICAL_DEVICE_PATHS);
    NtDeleteValueKey(KeyHandle, &unicodeName);

    return TRUE;
}
Ejemplo n.º 5
0
NTSTATUS
IopInitServiceEnumList (
    VOID
    )

/*++

Routine Description:

    This routine scans through System\Enum\Root subtree and assigns device
    instances to their corresponding Service\name\Enum\Root entries.  Basically,
    this routine establishes the Enum branches of service list.

Arguments:

    None.

Return Value:

   The function value is the final status of the operation.

--*/

{
    NTSTATUS status;
    HANDLE baseHandle;
    UNICODE_STRING workName, tmpName;

    //
    // Open System\CurrentControlSet\Enum key and call worker routine to recursively
    // scan through the subkeys.
    //

    status = IopOpenRegistryKeyPersist(&baseHandle,
                                       NULL,
                                       &CmRegistryMachineSystemCurrentControlSetEnumRootName,
                                       KEY_READ,
                                       TRUE,
                                       NULL
                                       );

    if (NT_SUCCESS(status)) {

        workName.Buffer = (PWSTR)IopPnpScratchBuffer1;
        RtlFillMemory((PUCHAR)IopPnpScratchBuffer1, PNP_LARGE_SCRATCH_BUFFER_SIZE, 0);
        workName.MaximumLength = PNP_LARGE_SCRATCH_BUFFER_SIZE;
        workName.Length = 0;
#if 1   // only look at ROOT key
        PiWstrToUnicodeString(&tmpName, REGSTR_KEY_ROOTENUM);
        RtlAppendStringToString((PSTRING)&workName, (PSTRING)&tmpName);
#endif

        //
        // Enumerate all subkeys under the System\CCS\Enum\Root.
        //

        status = IopApplyFunctionToSubKeys(baseHandle,
                                           NULL,
                                           KEY_ALL_ACCESS,
                                           TRUE,
#if 0
                                           IopInitializeBusKey,
#else
                                           IopInitializeDeviceKey,
#endif
                                           &workName
                                           );
        NtClose(baseHandle);
    }
    return status;
}
Ejemplo n.º 6
0
void
__cdecl main(
    int argc,
    char *argv[]
    )
{
    NTSTATUS status;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE          BaseHandle;
    HANDLE          WorkHandle;
    ULONG           Disposition;
    UNICODE_STRING  ClassName;
    ULONG           i;
    ULONG           j;
    PUCHAR  p;

    //
    // Process args
    //

    processargs(argc, argv);


    //
    // Set up and create/open KeyPath|KeyName
    //

    printf("rtvbatcr: starting\n");

    WorkName.MaximumLength = WORK_SIZE;
    WorkName.Length = 0L;
    WorkName.Buffer = &(workbuffer[0]);

    RtlCopyString((PSTRING)&WorkName, (PSTRING)&KeyPath);

    p = WorkName.Buffer;
    p += WorkName.Length;
    *p = '\\';
    p++;
    *p = '\0';
    WorkName.Length += 2;

    RtlAppendStringToString((PSTRING)&WorkName, (PSTRING)&KeyName);

    RtlInitUnicodeString(
        &ClassName,
        L"Test Class Name"
        );

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

    status = NtCreateKey(
                &BaseHandle,
                MAXIMUM_ALLOWED,
                &ObjectAttributes,
                0,
                &ClassName,
                REG_OPTION_VOLATILE,
                &Disposition
                );
    if (!NT_SUCCESS(status)) {
        printf("rtvbatcr: t0: %08lx\n", status);
        failure++;
        goto punt;
    }


    //
    // Create NumberChildren subkeys
    //

    for (i = 0; i < NumberChildren; i++) {

        sprintf(formatbuffer, "%s%d", BaseName, i);
        RtlInitString(&format, formatbuffer);
        RtlAnsiStringToUnicodeString(&WorkName, &format, FALSE);


        InitializeObjectAttributes(
            &ObjectAttributes,
            &WorkName,
            0,
            BaseHandle,
            NULL
            );
        ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;

        status = NtCreateKey(
                    &WorkHandle,
                    MAXIMUM_ALLOWED,
                    &ObjectAttributes,
                    0,
                    &ClassName,
                    REG_OPTION_VOLATILE,
                    &Disposition
                    );
        if (!NT_SUCCESS(status)) {
            printf("rtvbatcr: t1: status = %08lx i = %d\n", status, i);
            failure++;
        }

        //
        // Create NumberValues value entries for each (current) key
        //

        for (j = 0; j < NumberValues; j++) {

            sprintf(formatbuffer, "%s%d", BaseName, j);
            RtlInitString(&format, formatbuffer);
            RtlAnsiStringToUnicodeString(&WorkName, &format, FALSE);

            sprintf(
                formatbuffer, "This is a rtvbatcr value for %s%d", BaseName, j
                );

            status = NtSetValueKey(
                        WorkHandle,
                        &WorkName,
                        j,
                        j,
                        formatbuffer,
                        strlen(formatbuffer)+1
                        );
            if (!NT_SUCCESS(status)) {
                printf("rtvbatcr: t2: status = %08lx j = %d\n", status, j);
                failure++;
            }
        }
        NtClose(WorkHandle);
    }

punt:
    printf("rtvbatcr: %d failures\n", failure);
    exit(failure);
}
Ejemplo n.º 7
0
void
Dump(
    HANDLE  Handle
    )
{
    NTSTATUS    status;
    PKEY_BASIC_INFORMATION KeyInformation;
    OBJECT_ATTRIBUTES ObjectAttributes;
    ULONG   NamePos;
    ULONG   index;
    STRING  enumname;
    HANDLE  WorkHandle;
    ULONG   ResultLength;
    static  char buffer[WORK_SIZE];
    PUCHAR  p;

    KeyInformation = (PKEY_BASIC_INFORMATION)buffer;
    NamePos = WorkName.Length;

    //
    // Print name of node we are about to dump out
    //
    print(&WorkName);
    printf("::\n\n");

    //
    // Print out node's values
    //
    DumpValues(Handle);

    //
    // Enumerate node's children and apply ourselves to each one
    //

    for (index = 0; TRUE; index++) {

        RtlZeroMemory(KeyInformation, WORK_SIZE);
        status = NtEnumerateKey(
                    Handle,
                    index,
                    KeyBasicInformation,
                    KeyInformation,
                    WORK_SIZE,
                    &ResultLength
                    );

        if (status == STATUS_NO_MORE_ENTRIES) {

            WorkName.Length = NamePos;
            return;

        } else if (!NT_SUCCESS(status)) {

            printf("rtdmp: dump1: status = %08lx\n", status);
            exit(1);

        }

        enumname.Buffer = &(KeyInformation->Name[0]);
        enumname.Length = KeyInformation->NameLength;
        enumname.MaximumLength = KeyInformation->NameLength;

        p = WorkName.Buffer;
        p += WorkName.Length;
        *p = '\\';
        p++;
        *p = '\0';
        WorkName.Length += 2;

        RtlAppendStringToString((PSTRING)&WorkName, (PSTRING)&enumname);

        InitializeObjectAttributes(
            &ObjectAttributes,
            &enumname,
            0,
            Handle,
            NULL
            );
        ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;

        status = NtOpenKey(
                    &WorkHandle,
                    MAXIMUM_ALLOWED,
                    &ObjectAttributes
                    );
        if (!NT_SUCCESS(status)) {
            printf("rtdmp: dump2: %08lx\n", status);
            exit(1);
        }

        Dump(WorkHandle);
        NtClose(WorkHandle);
        WorkName.Length = NamePos;
    }
}