Beispiel #1
0
INIT_FUNCTION
NTSTATUS
NTAPI
PiInitCacheGroupInformation(VOID)
{
    HANDLE KeyHandle;
    NTSTATUS Status;
    PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
    PUNICODE_STRING GroupTable;
    ULONG Count;
    UNICODE_STRING GroupString =
        RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet"
                            L"\\Control\\ServiceGroupOrder");

    /* Open the registry key */
    Status = IopOpenRegistryKeyEx(&KeyHandle,
                                  NULL,
                                  &GroupString,
                                  KEY_READ);
    if (NT_SUCCESS(Status))
    {
        /* Get the list */
        Status = IopGetRegistryValue(KeyHandle, L"List", &KeyValueInformation);
        ZwClose(KeyHandle);

        /* Make sure we got it */
        if (NT_SUCCESS(Status))
        {
            /* Make sure it's valid */
            if ((KeyValueInformation->Type == REG_MULTI_SZ) &&
                (KeyValueInformation->DataLength))
            {
                /* Convert it to unicode strings */
                Status = PnpRegMultiSzToUnicodeStrings(KeyValueInformation,
                                                       &GroupTable,
                                                       &Count);

                /* Cache it for later */
                PiInitGroupOrderTable = GroupTable;
                PiInitGroupOrderTableCount = (USHORT)Count;
            }
            else
            {
                /* Fail */
                Status = STATUS_UNSUCCESSFUL;
            }

            /* Free the information */
            ExFreePool(KeyValueInformation);
        }
    }

    /* Return status */
    return Status;
}
Beispiel #2
0
USHORT
NTAPI
PpInitGetGroupOrderIndex(IN HANDLE ServiceHandle)
{
    NTSTATUS Status;
    PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
    USHORT i;
    PVOID Buffer;
    UNICODE_STRING Group;
    PAGED_CODE();

    /* Make sure we have a cache */
    if (!PiInitGroupOrderTable) return -1;

    /* If we don't have a handle, the rest is easy -- return the count */
    if (!ServiceHandle) return PiInitGroupOrderTableCount + 1;

    /* Otherwise, get the group value */
    Status = IopGetRegistryValue(ServiceHandle, L"Group", &KeyValueInformation);
    if (!NT_SUCCESS(Status)) return PiInitGroupOrderTableCount;

    /* Make sure we have a valid string */
    ASSERT(KeyValueInformation->Type == REG_SZ);
    ASSERT(KeyValueInformation->DataLength);

    /* Convert to unicode string */
    Buffer = (PVOID)((ULONG_PTR)KeyValueInformation + KeyValueInformation->DataOffset);
    PnpRegSzToString(Buffer, KeyValueInformation->DataLength, &Group.Length);
    Group.MaximumLength = (USHORT)KeyValueInformation->DataLength;
    Group.Buffer = Buffer;

    /* Loop the groups */
    for (i = 0; i < PiInitGroupOrderTableCount; i++)
    {
        /* Try to find a match */
        if (RtlEqualUnicodeString(&Group, &PiInitGroupOrderTable[i], TRUE)) break;
    }

    /* We're done */
    ExFreePool(KeyValueInformation);
    return i;
}
Beispiel #3
0
BOOLEAN
PiAddPlugPlayBusEnumeratorToList(
    IN     HANDLE ServiceKeyHandle,
    IN     PUNICODE_STRING ServiceName,
    IN OUT PVOID Context
    )

/*++

Routine Description:

    This routine is a callback function for IopApplyFunctionToSubKeys.
    It is called for each service key under
    HKLM\System\CurrentControlSet\Services. Its purpose is to take each
    service entry representing a bus enumerator, and create a corresponding
    bus enumerator entry in the Plug&Play bus enumerator list.

    NOTE: The PnP Bus Enumerator list resource must be held for exclusive
    (write) access before invoking this routine. The PnP device-specific
    registry resource must be held for shared (read) access.

Arguments:

    ServiceKeyHandle - Supplies a handle to a service entry key.

    ServiceName - Supplies the name of this service.

    Context - Not used.

Returns:

    TRUE to continue the enumeration.
    FALSE to abort it.

--*/

{
    UNICODE_STRING ValueName;
    NTSTATUS Status;
    PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
    ULONG RequiredLength;
    BOOLEAN IsBusExtender = FALSE;
    PUNICODE_STRING DeviceIDList;
    ULONG DeviceIDCount;
    PPLUGPLAY_BUS_ENUMERATOR BusEnumerator;

    //
    // First, see if this service is for a bus extender.  (Since we have
    // scratch space, use it, so we don't do memory allocations when checking
    // each service.)
    //
    RtlInitUnicodeString(&ValueName, REGSTR_VALUE_PLUGPLAY_SERVICE_TYPE);
    Status = NtQueryValueKey(ServiceKeyHandle,
                             &ValueName,
                             KeyValueFullInformation,
                             PiScratchBuffer,
                             PNP_LARGE_SCRATCH_BUFFER_SIZE,
                             &RequiredLength
                            );
    if(NT_SUCCESS(Status)) {
        if((((PKEY_VALUE_FULL_INFORMATION)PiScratchBuffer)->Type == REG_DWORD) &&
           (((PKEY_VALUE_FULL_INFORMATION)PiScratchBuffer)->DataLength >= sizeof(ULONG))) {

            IsBusExtender = (PlugPlayServiceBusExtender == (PLUGPLAY_SERVICE_TYPE)
                    (*(PULONG)KEY_VALUE_DATA((PKEY_VALUE_FULL_INFORMATION)PiScratchBuffer)));
        }
    }

    if(!IsBusExtender) {
        return TRUE;
    }

    //
    // We have a bus extender, so allocate a node for it.
    //
    BusEnumerator = (PPLUGPLAY_BUS_ENUMERATOR)ExAllocatePool(PagedPool,
                                                             sizeof(PLUGPLAY_BUS_ENUMERATOR));
    if(!BusEnumerator) {
        return TRUE;
    }

    if(!IopConcatenateUnicodeStrings(&(BusEnumerator->ServiceName),
                                     ServiceName,
                                     NULL
                                    )) {
        ExFreePool(BusEnumerator);
        return TRUE;
    }

    //
    // Now, retrieve the list of compatible device IDs from the service's
    // DeviceIDs REG_MULTI_SZ value entry.
    //
    Status = IopGetRegistryValue(ServiceKeyHandle,
                                 REGSTR_VALUE_DEVICE_IDS,
                                 &KeyValueInformation
                                );
    if(!NT_SUCCESS(Status)) {
        //
        // Since we couldn't retrieve any compatible IDs, assume there are none,
        // and initialize the BusEnumerator structure with a device ID count of zero.
        //
        DeviceIDList = NULL;
        DeviceIDCount = 0;
    } else {

        Status = IopRegMultiSzToUnicodeStrings(KeyValueInformation,
                                               &DeviceIDList,
                                               &DeviceIDCount
                                              );
        ExFreePool(KeyValueInformation);

        if(!NT_SUCCESS(Status)) {
            ExFreePool(BusEnumerator->ServiceName.Buffer);
            ExFreePool(BusEnumerator);
            return TRUE;
        }
    }

    //
    // Finish filling in the bus enumerator node and insert it into the tail of the list.
    //
    InitializeListHead(&(BusEnumerator->BusInstanceListEntry));
    BusEnumerator->PlugPlayIDs = DeviceIDList;
    BusEnumerator->PlugPlayIDCount = DeviceIDCount;
    RtlInitUnicodeString(&(BusEnumerator->DriverName), NULL);
    //BusEnumerator->DriverObject = NULL;

    InsertTailList(&PpBusListHead, &(BusEnumerator->BusEnumeratorListEntry));

    return TRUE;
}
Beispiel #4
0
NTSTATUS
PiInitializeSystemEnumSubKeys(
    IN HANDLE CurrentKeyHandle,
    IN PUNICODE_STRING ValueName
    )

/*++

Routine Description:

    This routine checks to see if the key whose handle was passed in contains
    a value whose name was specified by the ValueName argument.  If so, it
    resets this value to a REG_DWORD 0. It then enumerates all subkeys under
    the current key, and recursively calls itself for each one.

Arguments:

    CurrentKeyHandle - Supplies a handle to the key which will be enumerated.

    ValueName - Supplies a pointer to the value entry name to be initialized.

Return Value:

    None.

--*/

{
    NTSTATUS Status;
    PKEY_BASIC_INFORMATION KeyInformation;
    PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
    USHORT i;
    ULONG TempValue, ResultLength;
    UNICODE_STRING UnicodeName;
    HANDLE WorkHandle;

    //
    // Set "FoundAtEnum=" entry of current key to FALSE, if exists.
    //
    Status = IopGetRegistryValue(CurrentKeyHandle,
                                 ValueName->Buffer,
                                 &KeyValueInformation
                                );
    if(NT_SUCCESS(Status)) {
        ExFreePool(KeyValueInformation);
        TempValue = 0;
        Status = NtSetValueKey(CurrentKeyHandle,
                               ValueName,
                               TITLE_INDEX_VALUE,
                               REG_DWORD,
                               &TempValue,
                               sizeof(TempValue)
                              );

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

    //
    // Enumerate current node's children and apply ourselves to each one
    //
    KeyInformation = (PKEY_BASIC_INFORMATION)PiScratchBuffer;

    for(i = 0; TRUE; i++) {
        Status = NtEnumerateKey(CurrentKeyHandle,
                                i,
                                KeyBasicInformation,
                                KeyInformation,
                                PNP_LARGE_SCRATCH_BUFFER_SIZE,
                                &ResultLength
                               );

        if(Status == STATUS_NO_MORE_ENTRIES) {
            break;
        } else if(!NT_SUCCESS(Status)) {
            continue;
        }
        UnicodeName.Length = (USHORT)KeyInformation->NameLength;
        UnicodeName.MaximumLength = (USHORT)KeyInformation->NameLength;
        UnicodeName.Buffer = KeyInformation->Name;

        Status = IopOpenRegistryKey(&WorkHandle,
                                    CurrentKeyHandle,
                                    &UnicodeName,
                                    KEY_ALL_ACCESS,
                                    FALSE
                                    );
        if(!NT_SUCCESS(Status)) {
            continue;
        }

        Status = PiInitializeSystemEnumSubKeys(WorkHandle, ValueName);
        NtClose(WorkHandle);
        if(!NT_SUCCESS(Status)) {
            return Status;
        }
    }
    return STATUS_SUCCESS;
}
Beispiel #5
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);

}
Beispiel #6
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;
}
Beispiel #7
0
NTSTATUS
NTAPI
PipCallDriverAddDevice(IN PDEVICE_NODE DeviceNode,
                       IN BOOLEAN LoadDriver,
                       IN PDRIVER_OBJECT DriverObject)
{
    NTSTATUS Status;
    HANDLE EnumRootKey, SubKey, ControlKey, ClassKey, PropertiesKey;
    UNICODE_STRING ClassGuid, Properties;
    UNICODE_STRING EnumRoot = RTL_CONSTANT_STRING(ENUM_ROOT);
    UNICODE_STRING ControlClass =
    RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class");
    PKEY_VALUE_FULL_INFORMATION KeyValueInformation = NULL;
    PWCHAR Buffer;

    /* Open enumeration root key */
    Status = IopOpenRegistryKeyEx(&EnumRootKey,
                                  NULL,
                                  &EnumRoot,
                                  KEY_READ);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("IopOpenRegistryKeyEx() failed with Status %08X\n", Status);
        return Status;
    }

    /* Open instance subkey */
    Status = IopOpenRegistryKeyEx(&SubKey,
                                  EnumRootKey,
                                  &DeviceNode->InstancePath,
                                  KEY_READ);
    ZwClose(EnumRootKey);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("IopOpenRegistryKeyEx() failed with Status %08X\n", Status);
        return Status;
    }

    /* Get class GUID */
    Status = IopGetRegistryValue(SubKey,
                                 REGSTR_VAL_CLASSGUID,
                                 &KeyValueInformation);
    if (NT_SUCCESS(Status))
    {
        /* Convert to unicode string */
        Buffer = (PVOID)((ULONG_PTR)KeyValueInformation + KeyValueInformation->DataOffset);
        PnpRegSzToString(Buffer, KeyValueInformation->DataLength, &ClassGuid.Length);
        ClassGuid.MaximumLength = (USHORT)KeyValueInformation->DataLength;
        ClassGuid.Buffer = Buffer;

        /* Open the key */
        Status = IopOpenRegistryKeyEx(&ControlKey,
                                      NULL,
                                      &ControlClass,
                                      KEY_READ);
        if (!NT_SUCCESS(Status))
        {
            /* No class key */
            DPRINT1("IopOpenRegistryKeyEx() failed with Status %08X\n", Status);
            ClassKey = NULL;
        }
        else
        {
            /* Open the class key */
            Status = IopOpenRegistryKeyEx(&ClassKey,
                                          ControlKey,
                                          &ClassGuid,
                                          KEY_READ);
            ZwClose(ControlKey);
            if (!NT_SUCCESS(Status))
            {
                /* No class key */
                DPRINT1("IopOpenRegistryKeyEx() failed with Status %08X\n", Status);
                ClassKey = NULL;
            }
        }

        /* Check if we made it till here */
        if (ClassKey)
        {
            /* Get the device properties */
            RtlInitUnicodeString(&Properties, REGSTR_KEY_DEVICE_PROPERTIES);
            Status = IopOpenRegistryKeyEx(&PropertiesKey,
                                          ClassKey,
                                          &Properties,
                                          KEY_READ);
            ZwClose(ClassKey);
            if (!NT_SUCCESS(Status))
            {
                /* No properties */
                DPRINT("IopOpenRegistryKeyEx() failed with Status %08X\n", Status);
                PropertiesKey = NULL;
            }
            else
            {
                ZwClose(PropertiesKey);
            }
        }

        /* Free the registry data */
        ExFreePool(KeyValueInformation);
    }

    /* Do ReactOS-style setup */
    Status = IopAttachFilterDrivers(DeviceNode, TRUE);
    if (!NT_SUCCESS(Status))
    {
        IopRemoveDevice(DeviceNode);
        return Status;
    }
    Status = IopInitializeDevice(DeviceNode, DriverObject);
    if (NT_SUCCESS(Status))
    {
        Status = IopAttachFilterDrivers(DeviceNode, FALSE);
        if (!NT_SUCCESS(Status))
        {
            IopRemoveDevice(DeviceNode);
            return Status;
        }

        Status = IopStartDevice(DeviceNode);
    }

    /* Return status */
    return Status;
}
Beispiel #8
0
USHORT
NTAPI
PipGetDriverTagPriority(IN HANDLE ServiceHandle)
{
    NTSTATUS Status;
    HANDLE KeyHandle = NULL;
    PKEY_VALUE_FULL_INFORMATION KeyValueInformation = NULL;
    PKEY_VALUE_FULL_INFORMATION KeyValueInformationTag;
    PKEY_VALUE_FULL_INFORMATION KeyValueInformationGroupOrderList;
    PVOID Buffer;
    UNICODE_STRING Group;
    PULONG GroupOrder;
    ULONG Count, Tag = 0;
    USHORT i = -1;
    UNICODE_STRING GroupString =
    RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet"
                        L"\\Control\\ServiceGroupOrder");

    /* Open the key */
    Status = IopOpenRegistryKeyEx(&KeyHandle, NULL, &GroupString, KEY_READ);
    if (!NT_SUCCESS(Status)) goto Quickie;

    /* Read the group */
    Status = IopGetRegistryValue(ServiceHandle, L"Group", &KeyValueInformation);
    if (!NT_SUCCESS(Status)) goto Quickie;

    /* Make sure we have a group */
    if ((KeyValueInformation->Type == REG_SZ) &&
        (KeyValueInformation->DataLength))
    {
        /* Convert to unicode string */
        Buffer = (PVOID)((ULONG_PTR)KeyValueInformation + KeyValueInformation->DataOffset);
        PnpRegSzToString(Buffer, KeyValueInformation->DataLength, &Group.Length);
        Group.MaximumLength = (USHORT)KeyValueInformation->DataLength;
        Group.Buffer = Buffer;
    }

    /* Now read the tag */
    Status = IopGetRegistryValue(ServiceHandle, L"Tag", &KeyValueInformationTag);
    if (!NT_SUCCESS(Status)) goto Quickie;

    /* Make sure we have a tag */
    if ((KeyValueInformationTag->Type == REG_DWORD) &&
        (KeyValueInformationTag->DataLength))
    {
        /* Read it */
        Tag = *(PULONG)((ULONG_PTR)KeyValueInformationTag +
                        KeyValueInformationTag->DataOffset);
    }

    /* We can get rid of this now */
    ExFreePool(KeyValueInformationTag);

    /* Now let's read the group's tag order */
    Status = IopGetRegistryValue(KeyHandle,
                                 Group.Buffer,
                                 &KeyValueInformationGroupOrderList);

    /* We can get rid of this now */
Quickie:
    if (KeyValueInformation) ExFreePool(KeyValueInformation);
    if (KeyHandle) NtClose(KeyHandle);
    if (!NT_SUCCESS(Status)) return -1;

    /* We're on the success path -- validate the tag order*/
    if ((KeyValueInformationGroupOrderList->Type == REG_BINARY) &&
        (KeyValueInformationGroupOrderList->DataLength))
    {
        /* Get the order array */
        GroupOrder = (PULONG)((ULONG_PTR)KeyValueInformationGroupOrderList +
                              KeyValueInformationGroupOrderList->DataOffset);

        /* Get the count */
        Count = *GroupOrder;
        ASSERT(((Count + 1) * sizeof(ULONG)) <=
               KeyValueInformationGroupOrderList->DataLength);

        /* Now loop each tag */
        GroupOrder++;
        for (i = 1; i <= Count; i++)
        {
            /* If we found it, we're out */
            if (Tag == *GroupOrder) break;

            /* Try the next one */
            GroupOrder++;
        }
    }

    /* Last buffer to free */
    ExFreePool(KeyValueInformationGroupOrderList);
    return i;
}