Пример #1
0
NTSTATUS
NTAPI
WdmAudInstallDevice(
    IN  PDRIVER_OBJECT  DriverObject)
{
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\wdmaud");
    UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\wdmaud");
    PDEVICE_OBJECT DeviceObject;
    NTSTATUS Status;
    PWDMAUD_DEVICE_EXTENSION DeviceExtension;

    DPRINT("WdmAudInstallDevice called\n");

    Status = IoCreateDevice(DriverObject,
                            sizeof(WDMAUD_DEVICE_EXTENSION),
                            &DeviceName,
                            FILE_DEVICE_KS,
                            0,
                            FALSE,
                            &DeviceObject);

    if (!NT_SUCCESS(Status))
    {
        DPRINT1("IoCreateDevice failed with %x\n", Status);
        return Status;
    }

    /* get device extension */
    DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
    RtlZeroMemory(DeviceExtension, sizeof(WDMAUD_DEVICE_EXTENSION));

    /* allocate work item */
    DeviceExtension->WorkItem = IoAllocateWorkItem(DeviceObject);
    if (!DeviceExtension->WorkItem)
    {
        /* failed to allocate work item */
        IoDeleteDevice(DeviceObject);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    /* register device interfaces */
    Status = WdmAudRegisterDeviceInterface(DeviceObject, DeviceExtension);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("WdmRegisterDeviceInterface failed with %x\n", Status);
        IoDeleteDevice(DeviceObject);
        return Status;
    }

    /* initialize sysaudio device list */
    InitializeListHead(&DeviceExtension->SysAudioDeviceList);

    /* initialize client context device list */
    InitializeListHead(&DeviceExtension->WdmAudClientList);

    /* initialize spinlock */
    KeInitializeSpinLock(&DeviceExtension->Lock);

    /* initialization completion event */
    KeInitializeEvent(&DeviceExtension->InitializationCompletionEvent, NotificationEvent, FALSE);

    /* initialize timer */
    IoInitializeTimer(DeviceObject, WdmAudTimerRoutine, (PVOID)WdmAudTimerRoutine);

    /* find available sysaudio devices */
    Status = WdmAudOpenSysAudioDevices(DeviceObject, DeviceExtension);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("WdmAudOpenSysAudioDevices failed with %x\n", Status);
        IoDeleteSymbolicLink(&SymlinkName);
        IoDeleteDevice(DeviceObject);
        return Status;
    }

    /* allocate ks device header */
    Status = KsAllocateDeviceHeader(&DeviceExtension->DeviceHeader, 0, NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("KsAllocateDeviceHeader failed with %x\n", Status);
        IoDeleteSymbolicLink(&SymlinkName);
        IoDeleteDevice(DeviceObject);
        return Status;
    }

    /* start the timer */
    IoStartTimer(DeviceObject);

    DeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
    DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;

    return STATUS_SUCCESS;
}
Пример #2
0
NTSTATUS
NTAPI
StreamClassAddDevice(
    IN PDRIVER_OBJECT  DriverObject,
    IN PDEVICE_OBJECT  PhysicalDeviceObject)
{
    PSTREAM_CLASS_DRIVER_EXTENSION DriverObjectExtension;
    PDEVICE_OBJECT DeviceObject, LowerDeviceObject;
    PSTREAM_DEVICE_EXTENSION DeviceExtension;
    PKSOBJECT_CREATE_ITEM ItemList;
    NTSTATUS Status;

    /* Fetch driver object extension */
    DriverObjectExtension = IoGetDriverObjectExtension(DriverObject, (PVOID)StreamClassAddDevice);
    if (!DriverObjectExtension)
    {
        /* Failed to get driver extension */
        return STATUS_DEVICE_DOES_NOT_EXIST;
    }
    /* Allocate Create Item */
    ItemList = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
    if (!ItemList)
    {
        /* Failed to allocated Create Item */
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    /* Create the FDO */
    Status = IoCreateDevice(DriverObject, DriverObjectExtension->Data.DeviceExtensionSize + sizeof(STREAM_DEVICE_EXTENSION), NULL, FILE_DEVICE_KS, FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, 0, &DeviceObject);
    if (!NT_SUCCESS(Status))
    {
        /* Failed to create the FDO */
        ExFreePool(ItemList);
        return Status;
    }

    /* Attach to device stack */
    LowerDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
    if (!LowerDeviceObject)
    {
        /* Failed to attach */
        IoDeleteDevice(DeviceObject);
        return STATUS_UNSUCCESSFUL;
    }

    /* Zero Create item */
    RtlZeroMemory(ItemList, sizeof(KSOBJECT_CREATE_ITEM));
    /* Setup object class */
    RtlInitUnicodeString(&ItemList->ObjectClass, L"GLOBAL");
    /* Setup CreateDispatch routine */
    ItemList->Create = StreamClassCreateFilter;

    /* Get device extension */
    DeviceExtension = (PSTREAM_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
    /* Zero device extension */
    RtlZeroMemory(DeviceExtension, sizeof(STREAM_DEVICE_EXTENSION));
    /* Initialize Ks streaming */
    Status = KsAllocateDeviceHeader(&DeviceExtension->Header, 1, ItemList);
    if (!NT_SUCCESS(Status))
    {
        /* Cleanup resources */
        IoDetachDevice(LowerDeviceObject);
        IoDeleteDevice(DeviceObject);
        ExFreePool(ItemList);
        return Status;
    }

    /* Store lower device object */
    DeviceExtension->LowerDeviceObject = LowerDeviceObject;

    /* Store physical device object */
    DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
    /* Store driver object extension */
    DeviceExtension->DriverExtension = DriverObjectExtension;
    /* Initialize memory list */
    InitializeListHead(&DeviceExtension->MemoryResourceList);
    /* Setup device extension */
    DeviceExtension->DeviceExtension = (PVOID) (DeviceExtension + 1);
    /* Init interrupt dpc */
    KeInitializeDpc(&DeviceExtension->InterruptDpc, StreamClassInterruptDpc, (PVOID)DeviceExtension);

    /* Set device transfer method */
    DeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
    /* Clear init flag */
    DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;

    return Status;
}
Пример #3
0
//
//  Typically called by a driver's AddDevice function, which is set when
//  calling PcInitializeAdapterDriver. This performs some common driver
//  operations, such as creating a device extension.
//
//  The StartDevice parameter is a driver-supplied function which gets
//  called in response to IRP_MJ_PNP / IRP_MN_START_DEVICE.
//
NTSTATUS
NTAPI
PcAddAdapterDevice(
    IN  PDRIVER_OBJECT DriverObject,
    IN  PDEVICE_OBJECT PhysicalDeviceObject,
    IN  PCPFNSTARTDEVICE StartDevice,
    IN  ULONG MaxObjects,
    IN  ULONG DeviceExtensionSize)
{
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    PDEVICE_OBJECT fdo;
    PDEVICE_OBJECT PrevDeviceObject;
    PPCLASS_DEVICE_EXTENSION portcls_ext = NULL;

    DPRINT("PcAddAdapterDevice called\n");
    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    if (!DriverObject || !PhysicalDeviceObject || !StartDevice)
    {
        return STATUS_INVALID_PARAMETER;
    }

    // check if the DeviceExtensionSize is provided
    if ( DeviceExtensionSize < PORT_CLASS_DEVICE_EXTENSION_SIZE )
    {
        // driver does not need a device extension 
        if ( DeviceExtensionSize != 0 )
        {
            // DeviceExtensionSize must be zero
            return STATUS_INVALID_PARAMETER;
        }
        // set size to our extension size
        DeviceExtensionSize = PORT_CLASS_DEVICE_EXTENSION_SIZE;
    }

    // create the device
    status = IoCreateDevice(DriverObject,
                            DeviceExtensionSize,
                            NULL,
                            FILE_DEVICE_KS,
                            FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN,
                            FALSE,
                            &fdo);

    if (!NT_SUCCESS(status))
    {
        DPRINT("IoCreateDevice() failed with status 0x%08lx\n", status);
        return status;
    }

    // Obtain the new device extension
    portcls_ext = (PPCLASS_DEVICE_EXTENSION) fdo->DeviceExtension;
    // initialize the device extension
    RtlZeroMemory(portcls_ext, DeviceExtensionSize);
    // allocate create item
    portcls_ext->CreateItems = (PKSOBJECT_CREATE_ITEM)AllocateItem(NonPagedPool, MaxObjects * sizeof(KSOBJECT_CREATE_ITEM), TAG_PORTCLASS);

    if (!portcls_ext->CreateItems)
    {
        // not enough resources
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto cleanup;
    }

    // store max subdevice count
    portcls_ext->MaxSubDevices = MaxObjects;
    // store the physical device object
    portcls_ext->PhysicalDeviceObject = PhysicalDeviceObject;
    // set up the start device function
    portcls_ext->StartDevice = StartDevice;
    // initialize timer lock
    KeInitializeSpinLock(&portcls_ext->TimerListLock);
    // initialize timer list
    InitializeListHead(&portcls_ext->TimerList);
    // initialize io timer
    IoInitializeTimer(fdo, PcIoTimerRoutine, NULL);
    // start the io timer
    IoStartTimer(fdo);

    // set io flags
    fdo->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
    // clear initializing flag
    fdo->Flags &= ~ DO_DEVICE_INITIALIZING;

    // allocate the device header
    status = KsAllocateDeviceHeader(&portcls_ext->KsDeviceHeader, MaxObjects, portcls_ext->CreateItems);
    // did we succeed
    if (!NT_SUCCESS(status))
    {
        goto cleanup;
    }

    // attach device to device stack
    PrevDeviceObject = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);
    // did we succeed
    if (PrevDeviceObject)
    {
        // store the device object in the device header
        //KsSetDevicePnpBaseObject(portcls_ext->KsDeviceHeader, fdo, PrevDeviceObject);
        portcls_ext->PrevDeviceObject = PrevDeviceObject;
    }
    else
    {
        // return error code
        status = STATUS_UNSUCCESSFUL;
        goto cleanup;
    }

    // register shutdown notification
    IoRegisterShutdownNotification(PhysicalDeviceObject);

    return status;

cleanup:

    if (portcls_ext->KsDeviceHeader)
    {
        // free the device header
        KsFreeDeviceHeader(portcls_ext->KsDeviceHeader);
    }

    if (portcls_ext->CreateItems)
    {
        // free previously allocated create items
        FreeItem(portcls_ext->CreateItems, TAG_PORTCLASS);
    }

    // delete created fdo
    IoDeleteDevice(fdo);


    return status;
}