Exemple #1
0
/* Loop to install all queued devices installations */
static ULONG NTAPI
DeviceInstallThread(IN PVOID Parameter)
{
    HINF hSetupInf = *(HINF*)Parameter;
    PSLIST_ENTRY ListEntry;
    DeviceInstallParams* Params;
    LARGE_INTEGER Timeout;

    for (;;)
    {
        ListEntry = RtlInterlockedPopEntrySList(&DeviceInstallListHead);

        if (ListEntry == NULL)
        {
            /*
             * The list is now empty, but there may be a new enumerated device
             * that is going to be added to the list soon. In order to avoid
             * setting the hNoPendingInstalls event to release it soon after,
             * we wait for maximum 1 second for no PnP enumeration event being
             * received before declaring that no pending installations are
             * taking place and setting the corresponding event.
             */
            Timeout.QuadPart = -10000000LL; /* Wait for 1 second */
            if (NtWaitForSingleObject(hDeviceInstallListNotEmpty, FALSE, &Timeout) == STATUS_TIMEOUT)
            {
                /* We timed out: set the event and do the actual wait */
                NtSetEvent(hNoPendingInstalls, NULL);
                NtWaitForSingleObject(hDeviceInstallListNotEmpty, FALSE, NULL);
            }
        }
        else
        {
            NtResetEvent(hNoPendingInstalls, NULL);
            Params = CONTAINING_RECORD(ListEntry, DeviceInstallParams, ListEntry);
            InstallDevice(hSetupInf, hEnumKey, hServicesKey, Params->DeviceIds);
            RtlFreeHeap(ProcessHeap, 0, Params);
        }
    }

    return 0;
}
Exemple #2
0
NTSTATUS
EventThread(IN LPVOID lpParameter)
{
    UNICODE_STRING EnumU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Enum");
    UNICODE_STRING ServicesU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services");
    PPLUGPLAY_EVENT_BLOCK PnpEvent;
    OBJECT_ATTRIBUTES ObjectAttributes;
    ULONG PnpEventSize;
    HINF hInf;
    HANDLE hEnum, hServices;
    NTSTATUS Status;

    hInf = *(HINF *)lpParameter;

    InitializeObjectAttributes(&ObjectAttributes, &EnumU, OBJ_CASE_INSENSITIVE, NULL, NULL);
    Status = NtOpenKey(&hEnum, KEY_QUERY_VALUE, &ObjectAttributes);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtOpenKey('%wZ') failed with status 0x%08lx\n", &EnumU, Status);
        return Status;
    }

    InitializeObjectAttributes(&ObjectAttributes, &ServicesU, OBJ_CASE_INSENSITIVE, NULL, NULL);
    Status = NtCreateKey(&hServices, KEY_ALL_ACCESS, &ObjectAttributes, 0, NULL, 0, NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtCreateKey('%wZ') failed with status 0x%08lx\n", &ServicesU, Status);
        NtClose(hEnum);
        return Status;
    }

    PnpEventSize = 0x1000;
    PnpEvent = (PPLUGPLAY_EVENT_BLOCK)RtlAllocateHeap(ProcessHeap, 0, PnpEventSize);
    if (PnpEvent == NULL)
    {
        NtClose(hEnum);
        NtClose(hServices);
        return STATUS_NO_MEMORY;
    }

    for (;;)
    {
        DPRINT("Calling NtGetPlugPlayEvent()\n");

        /* Wait for the next pnp event */
        Status = NtGetPlugPlayEvent(0, 0, PnpEvent, PnpEventSize);

        /* Resize the buffer for the PnP event if it's too small. */
        if (Status == STATUS_BUFFER_TOO_SMALL)
        {
            PnpEventSize += 0x400;
            RtlFreeHeap(ProcessHeap, 0, PnpEvent);
            PnpEvent = (PPLUGPLAY_EVENT_BLOCK)RtlAllocateHeap(ProcessHeap, 0, PnpEventSize);
            if (PnpEvent == NULL)
            {
                NtClose(hEnum);
                NtClose(hServices);
                return STATUS_NO_MEMORY;
            }
            continue;
        }

        if (!NT_SUCCESS(Status))
        {
            DPRINT("NtPlugPlayEvent() failed (Status %lx)\n", Status);
            break;
        }

        /* Process the pnp event */
        DPRINT("Received PnP Event\n");
        if (IsEqualIID(&PnpEvent->EventGuid, (REFGUID)&GUID_DEVICE_ENUMERATED))
        {
            DPRINT("Device arrival event: %S\n", PnpEvent->TargetDevice.DeviceIds);
            InstallDevice(hInf, hEnum, hServices, PnpEvent->TargetDevice.DeviceIds);
        }
        else
        {
            DPRINT("Unknown event\n");
        }

        /* Dequeue the current pnp event and signal the next one */
        NtPlugPlayControl(PlugPlayControlUserResponse, NULL, 0);
    }

    RtlFreeHeap(ProcessHeap, 0, PnpEvent);
    NtClose(hEnum);
    NtClose(hServices);

    return STATUS_SUCCESS;
}