Пример #1
0
/*
 * @implemented
 */
VOID
RegisterForTargetDeviceNotification(IN PDEVICE_EXTENSION DeviceExtension,
                                    IN PDEVICE_INFORMATION DeviceInformation)
{
    NTSTATUS Status;
    PFILE_OBJECT FileObject;
    PDEVICE_OBJECT DeviceObject;

    /* Get device object */
    Status = IoGetDeviceObjectPointer(&(DeviceInformation->DeviceName),
                                      FILE_READ_ATTRIBUTES,
                                      &FileObject,
                                      &DeviceObject);
    if (!NT_SUCCESS(Status))
    {
        return;
    }

    /* And simply register for notifications */
    Status = IoRegisterPlugPlayNotification(EventCategoryTargetDeviceChange,
                                            0, FileObject,
                                            DeviceExtension->DriverObject,
                                            MountMgrTargetDeviceNotification,
                                            DeviceInformation,
                                            &(DeviceInformation->TargetDeviceNotificationEntry));
    if (!NT_SUCCESS(Status))
    {
        DeviceInformation->TargetDeviceNotificationEntry = NULL;
    }

    ObDereferenceObject(FileObject);

    return;
}
Пример #2
0
NTSTATUS
SysAudioRegisterNotifications(
    IN PDRIVER_OBJECT  DriverObject,
    IN PDEVICE_OBJECT DeviceObject)
{
    NTSTATUS Status;
    PSYSAUDIODEVEXT DeviceExtension;

    DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;

    Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
                                            PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
                                            (PVOID)&KS_CATEGORY_AUDIO,
                                            DriverObject,
                                            DeviceInterfaceChangeCallback,
                                            (PVOID)DeviceObject,
                                            (PVOID*)&DeviceExtension->KsAudioNotificationEntry);

    if (!NT_SUCCESS(Status))
    {
        DPRINT("IoRegisterPlugPlayNotification failed with %x\n", Status);
    }

    Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
                                            PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
                                            (PVOID)&DMOCATEGORY_ACOUSTIC_ECHO_CANCEL,
                                            DriverObject,
                                            DeviceInterfaceChangeCallback,
                                            (PVOID)DeviceObject,
                                            (PVOID*)&DeviceExtension->EchoCancelNotificationEntry);

    if (!NT_SUCCESS(Status))
    {
        /* ignore failure for now */
        DPRINT("IoRegisterPlugPlayNotification failed for DMOCATEGORY_ACOUSTIC_ECHO_CANCEL\n", Status);
    }

    return STATUS_SUCCESS;
}
Пример #3
0
static
VOID
Test_IoRegisterPlugPlayNotification(VOID)
{
    NTSTATUS Status;
    PVOID NotificationEntry;

    Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
                                            PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
                                            (PVOID)&GUID_DEVICE_SYS_BUTTON,
                                            KmtDriverObject,
                                            NotificationCallback,
                                            &NotificationContext,
                                            &NotificationEntry);
    ok_eq_hex(Status, STATUS_SUCCESS);
    if (!skip(NT_SUCCESS(Status), "PlugPlayNotification not registered\n"))
    {
        Status = IoUnregisterPlugPlayNotification(NotificationEntry);
        ok_eq_hex(Status, STATUS_SUCCESS);
    }
}
Пример #4
0
NTSTATUS mydrvEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath){
	UNREFERENCED_PARAMETER(pRegPath);
	UNICODE_STRING uKbdClassDrv;
	NTSTATUS status = STATUS_UNSUCCESSFUL;

	DbgPrint("Keyboard Filter Driver - DriverEntry\nCompiled at " __TIME__ " on " __DATE__ "\n");
	//DbgPrint("sizeof(DEVICE_EXTENSION): %llu", sizeof(KBDFNFLT_DEVICE_EXTENSION));
	//DbgPrint("offset, size: %llu, %llu", FIELD_OFFSET(KBDFNFLT_DEVICE_EXTENSION, pKeyboardDevice), FIELD_SIZE(KBDFNFLT_DEVICE_EXTENSION, pKeyboardDevice));
	//DbgPrint("offset, size: %llu, %llu", FIELD_OFFSET(KBDFNFLT_DEVICE_EXTENSION, pKbdClassDrv), FIELD_SIZE(KBDFNFLT_DEVICE_EXTENSION, pKbdClassDrv));
	//DbgPrint("offset, size: %llu, %llu", FIELD_OFFSET(KBDFNFLT_DEVICE_EXTENSION, pDevObjString), FIELD_SIZE(KBDFNFLT_DEVICE_EXTENSION, pDevObjString));
	//DbgPrint("offset, size: %llu, %llu", FIELD_OFFSET(KBDFNFLT_DEVICE_EXTENSION, kState), FIELD_SIZE(KBDFNFLT_DEVICE_EXTENSION, kState));
	//DbgPrint("offset, size: %llu, %llu", FIELD_OFFSET(KBDFNFLT_DEVICE_EXTENSION, workitem), 0);//FIELD_SIZE(KBDFNFLT_DEVICE_EXTENSION, workitem));


	/////////////////////////////////////////////////////////////////////////////////////////   
	// Fill in IRP dispatch table in the DriverObject to handle I/O Request Packets (IRPs)    
	/////////////////////////////////////////////////////////////////////////////////////////   

	// For a filter driver, we want pass down ALL IRP_MJ_XX requests to the driver which   
	// we are hooking except for those we are interested in modifying.   
	for (int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
#pragma warning(suppress: 28168)
		pDrvObj->MajorFunction[i] = dispatchPassDown;
	DbgPrint("Filled dispatch table with generic pass down routine...\n");
	
	//Explicitly fill in the IRP's we want to hook   
	pDrvObj->MajorFunction[IRP_MJ_READ] = dispatchRead;

	//Create a keyboard device object  
	PDEVICE_OBJECT pKbdFnFltDevice = NULL;
	status = IoCreateDevice(pDrvObj, sizeof(KBDFNFLT_DEVICE_EXTENSION) + IoSizeofWorkItem(), NULL, //no name   
		FILE_DEVICE_KEYBOARD, 0, TRUE, &pKbdFnFltDevice);
	//Make sure the device was created ok   
	if (status)
		return status;

	RtlInitUnicodeString(&uKbdClassDrv, KBDCLASS_NAME);

	status = ObReferenceObjectByName(&uKbdClassDrv, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, 0, IoDriverObjectType, KernelMode, NULL, &((PKBDFNFLT_DEVICE_EXTENSION)pKbdFnFltDevice->DeviceExtension)->pKbdClassDrv);
	if (status){
		IoDeleteDevice(pKbdFnFltDevice);
		return status;
	}

	GUID kbdDevClass = GUID_CLASS_KEYBOARD;
	PIO_WORKITEM pWorkitem = (PIO_WORKITEM)&((PKBDFNFLT_DEVICE_EXTENSION)pKbdFnFltDevice->DeviceExtension)->workitem;

	IoInitializeWorkItem(pKbdFnFltDevice, pWorkitem);
	((PKBDFNFLT_DEVICE_EXTENSION)pKbdFnFltDevice->DeviceExtension)->pWorkitem = pWorkitem;
	//PIO_WORKITEM pWorkitem = ExAllocatePoolWithTag(NonPagedPool, IoSizeofWorkItem(), g_poolTag);
	//if (!pWorkitem){
	//
	
	//}
	DbgPrint("%p", &((PKBDFNFLT_DEVICE_EXTENSION)pKbdFnFltDevice->DeviceExtension)->pKeyboardDevice);
	DbgPrint("%p", &((PKBDFNFLT_DEVICE_EXTENSION)pKbdFnFltDevice->DeviceExtension)->pKbdClassDrv);
	DbgPrint("%p", &((PKBDFNFLT_DEVICE_EXTENSION)pKbdFnFltDevice->DeviceExtension)->pDevObjString);
	DbgPrint("%p", &((PKBDFNFLT_DEVICE_EXTENSION)pKbdFnFltDevice->DeviceExtension)->keyState);
	DbgPrint("%p", &((PKBDFNFLT_DEVICE_EXTENSION)pKbdFnFltDevice->DeviceExtension)->workitem);

	//IoInitializeWorkItem(&pKbdFnFltDevice)
	//PVOID pNotificationEntry = NULL;
	status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
		PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
		&kbdDevClass, pDrvObj, keyboardAddedOrRemoved, pKbdFnFltDevice, &g_pNotificationEntry);
	if (status){
		DbgPrint("something went wrong    %lX", status);
		IoUninitializeWorkItem(pWorkitem);
		IoDeleteDevice(pKbdFnFltDevice);
		return status;
	}



	//Go ahead and hook the keyboard now   
	//status = hookKeyboard(pDrvObj);
	//if (status){
	//	DbgPrint("something went wrong%lX", status);
	//	return status;
	//}

	DbgPrint("Hooked IRP_MJ_READ routine...\n");

	// Set the DriverUnload procedure   
	pDrvObj->DriverUnload = mydrvUnload;
	DbgPrint("Set DriverUnload function pointer...\n");
	DbgPrint("Exiting Driver Entry......\n");
	return STATUS_SUCCESS;
}
Пример #5
0
BOOLEAN
NTAPI
INIT_FUNCTION
PoInitSystem(IN ULONG BootPhase)
{
    PVOID NotificationEntry;
    PCHAR CommandLine;
    BOOLEAN ForceAcpiDisable = FALSE;

    /* Check if this is phase 1 init */
    if (BootPhase == 1)
    {
        /* Register power button notification */
        IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
                                       PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
                                       (PVOID)&GUID_DEVICE_SYS_BUTTON,
                                       IopRootDeviceNode->
                                       PhysicalDeviceObject->DriverObject,
                                       PopAddRemoveSysCapsCallback,
                                       NULL,
                                       &NotificationEntry);

        /* Register lid notification */
        IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
                                       PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
                                       (PVOID)&GUID_DEVICE_LID,
                                       IopRootDeviceNode->
                                       PhysicalDeviceObject->DriverObject,
                                       PopAddRemoveSysCapsCallback,
                                       NULL,
                                       &NotificationEntry);
        return TRUE;
    }

    /* Get the Command Line */
    CommandLine = KeLoaderBlock->LoadOptions;

    /* Upcase it */
    _strupr(CommandLine);

    /* Check for ACPI disable */
    if (strstr(CommandLine, "NOACPI")) ForceAcpiDisable = TRUE;

    if (ForceAcpiDisable)
    {
        /* Set the ACPI State to False if it's been forced that way */
        PopAcpiPresent = FALSE;
    }
    else
    {
        /* Otherwise check if the LoaderBlock has a ACPI Table  */
        PopAcpiPresent = KeLoaderBlock->Extension->AcpiTable != NULL ? TRUE : FALSE;
    }


    /* Initialize volume support */
    InitializeListHead(&PopVolumeDevices);
    KeInitializeGuardedMutex(&PopVolumeLock);

    /* Initialize support for dope */
    KeInitializeSpinLock(&PopDopeGlobalLock);

    /* Initialize support for shutdown waits and work-items */
    PopInitShutdownList();

    return TRUE;
}
Пример #6
0
NTSTATUS
ToastMon_EvtDeviceAdd(
    IN WDFDRIVER Driver,
    IN PWDFDEVICE_INIT DeviceInit
    )
/*++
Routine Description:

    ToastMon_EvtDeviceAdd is called by the framework in response to AddDevice
    call from the PnP manager. We create and initialize a device object to
    represent a new instance of toaster device.

Arguments:

    Driver - Handle to a framework driver object created in DriverEntry

    DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.

Return Value:

    NTSTATUS

--*/
{
    WDF_OBJECT_ATTRIBUTES           attributes;
    NTSTATUS                        status = STATUS_SUCCESS;
    WDFDEVICE                       device;
    PDEVICE_EXTENSION               deviceExtension;

    KdPrint( ("ToastMon_EvtDeviceAdd routine\n"));

    UNREFERENCED_PARAMETER(Driver);

    PAGED_CODE();

    //
    // Specify the size of device extension where we track per device
    // context.
    //
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_EXTENSION);

    attributes.EvtCleanupCallback = ToastMon_EvtDeviceContextCleanup;

    //
    // Create a framework device object.This call will inturn create
    // a WDM deviceobject, attach to the lower stack and set the
    // appropriate flags and attributes.
    //
    status = WdfDeviceCreate(&DeviceInit, &attributes, &device);
    if (!NT_SUCCESS(status)) {
        KdPrint( ("WdfDeviceCreate failed with Status 0x%x\n", status));
        return status;
    }

    //
    // Get the DeviceExtension and initialize it.
    //
    deviceExtension = GetDeviceExtension(device);

    deviceExtension->WdfDevice = device;

    //
    // Create a collection to store information about target devices.
    //
    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.ParentObject = device;

    status = WdfCollectionCreate(&attributes,
                                &deviceExtension->TargetDeviceCollection);
    if (!NT_SUCCESS(status))
    {
        KdPrint( ("WdfCollectionCreate failed with status 0x%x\n", status));
        return status;
    }

    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.ParentObject = device;

    status = WdfWaitLockCreate(&attributes,
                               &deviceExtension->TargetDeviceCollectionLock);
    if (!NT_SUCCESS(status))
    {
        KdPrint( ("WdfWaitLockCreate failed with status 0x%x\n", status));
        return status;
    }

    //
    // Register for TOASTER device interface change notification.
    // We will get GUID_DEVICE_INTERFACE_ARRIVAL and
    // GUID_DEVICE_INTERFACE_REMOVAL notification when the toaster
    // device is started and removed.
    // Framework doesn't provide a WDF interface to register for interface change
    // notification. However if the target device is opened by symboliclink using
    // IoTarget, framework registers itself EventCategoryTargetDeviceChange
    // notification on the handle and responds to the pnp notifications.
    //
    // Note that as soon as you register, arrival notification will be sent
    // about all existing toaster devices even before this device is started. So if
    // you cannot handle these notification before start then you should register this in
    // PrepareHardware or SelfManagedIoInit callback.
    // You must unregister this notification when the device is removed in the
    // DeviceContextCleanup callback. This call takes a reference on the driverobject.
    // So if you don't unregister it will prevent the driver from unloading.
    //
    status = IoRegisterPlugPlayNotification (
                EventCategoryDeviceInterfaceChange,
                PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
                (PVOID)&GUID_DEVINTERFACE_TOASTER,
                WdfDriverWdmGetDriverObject(WdfDeviceGetDriver(device)),
                (PDRIVER_NOTIFICATION_CALLBACK_ROUTINE)
                    ToastMon_PnpNotifyInterfaceChange,
                (PVOID)deviceExtension,
                &deviceExtension->NotificationHandle);

    if (!NT_SUCCESS(status)) {
        KdPrint(("RegisterPnPNotifiction failed: 0x%x\n", status));
        return status;
    }

    RegisterForWMINotification(deviceExtension);

    return status;
}
Пример #7
0
void add_volume_device(superblock* sb, PDEVICE_OBJECT mountmgr, PUNICODE_STRING devpath, UINT64 length, ULONG disk_num, ULONG part_num) {
    NTSTATUS Status;
    LIST_ENTRY* le;
    PDEVICE_OBJECT DeviceObject;
    volume_child* vc;
    PFILE_OBJECT FileObject;
    UNICODE_STRING devpath2;
    BOOL inserted = FALSE, new_pdo = FALSE;
    pdo_device_extension* pdode = NULL;
    PDEVICE_OBJECT pdo = NULL;

    if (devpath->Length == 0)
        return;

    ExAcquireResourceExclusiveLite(&pdo_list_lock, TRUE);

    le = pdo_list.Flink;
    while (le != &pdo_list) {
        pdo_device_extension* pdode2 = CONTAINING_RECORD(le, pdo_device_extension, list_entry);

        if (RtlCompareMemory(&pdode2->uuid, &sb->uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
            pdode = pdode2;
            break;
        }

        le = le->Flink;
    }

    Status = IoGetDeviceObjectPointer(devpath, FILE_READ_ATTRIBUTES, &FileObject, &DeviceObject);
    if (!NT_SUCCESS(Status)) {
        ERR("IoGetDeviceObjectPointer returned %08x\n", Status);
        ExReleaseResourceLite(&pdo_list_lock);
        return;
    }

    if (!pdode) {
        if (no_pnp) {
            Status = IoReportDetectedDevice(drvobj, InterfaceTypeUndefined, 0xFFFFFFFF, 0xFFFFFFFF, NULL, NULL, 0, &pdo);

            if (!NT_SUCCESS(Status)) {
                ERR("IoReportDetectedDevice returned %08x\n", Status);
                ExReleaseResourceLite(&pdo_list_lock);
                return;
            }

            pdode = ExAllocatePoolWithTag(NonPagedPool, sizeof(pdo_device_extension), ALLOC_TAG);

            if (!pdode) {
                ERR("out of memory\n");
                ExReleaseResourceLite(&pdo_list_lock);
                return;
            }
        } else {
            Status = IoCreateDevice(drvobj, sizeof(pdo_device_extension), NULL, FILE_DEVICE_DISK,
                                    FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, FALSE, &pdo);
            if (!NT_SUCCESS(Status)) {
                ERR("IoCreateDevice returned %08x\n", Status);
                ExReleaseResourceLite(&pdo_list_lock);
                goto fail;
            }

            pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;

            pdode = pdo->DeviceExtension;
        }

        RtlZeroMemory(pdode, sizeof(pdo_device_extension));

        pdode->type = VCB_TYPE_PDO;
        pdode->pdo = pdo;
        pdode->uuid = sb->uuid;

        ExInitializeResourceLite(&pdode->child_lock);
        InitializeListHead(&pdode->children);
        pdode->num_children = sb->num_devices;
        pdode->children_loaded = 0;

        pdo->Flags &= ~DO_DEVICE_INITIALIZING;
        pdo->SectorSize = (USHORT)sb->sector_size;

        ExAcquireResourceExclusiveLite(&pdode->child_lock, TRUE);

        new_pdo = TRUE;
    } else {
        ExAcquireResourceExclusiveLite(&pdode->child_lock, TRUE);
        ExConvertExclusiveToSharedLite(&pdo_list_lock);

        le = pdode->children.Flink;
        while (le != &pdode->children) {
            volume_child* vc2 = CONTAINING_RECORD(le, volume_child, list_entry);

            if (RtlCompareMemory(&vc2->uuid, &sb->dev_item.device_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
                // duplicate, ignore
                ExReleaseResourceLite(&pdode->child_lock);
                ExReleaseResourceLite(&pdo_list_lock);
                goto fail;
            }

            le = le->Flink;
        }
    }

    vc = ExAllocatePoolWithTag(PagedPool, sizeof(volume_child), ALLOC_TAG);
    if (!vc) {
        ERR("out of memory\n");

        ExReleaseResourceLite(&pdode->child_lock);
        ExReleaseResourceLite(&pdo_list_lock);

        goto fail;
    }

    vc->uuid = sb->dev_item.device_uuid;
    vc->devid = sb->dev_item.dev_id;
    vc->generation = sb->generation;
    vc->notification_entry = NULL;

    Status = IoRegisterPlugPlayNotification(EventCategoryTargetDeviceChange, 0, FileObject,
                                            drvobj, pnp_removal, pdode, &vc->notification_entry);
    if (!NT_SUCCESS(Status))
        WARN("IoRegisterPlugPlayNotification returned %08x\n", Status);

    vc->devobj = DeviceObject;
    vc->fileobj = FileObject;

    devpath2 = *devpath;

    // The PNP path sometimes begins \\?\ and sometimes \??\. We need to remove this prefix
    // so we can compare properly if the device is removed.
    if (devpath->Length > 4 * sizeof(WCHAR) && devpath->Buffer[0] == '\\' && (devpath->Buffer[1] == '\\' || devpath->Buffer[1] == '?') &&
        devpath->Buffer[2] == '?' && devpath->Buffer[3] == '\\') {
        devpath2.Buffer = &devpath2.Buffer[3];
        devpath2.Length -= 3 * sizeof(WCHAR);
        devpath2.MaximumLength -= 3 * sizeof(WCHAR);
    }

    vc->pnp_name.Length = vc->pnp_name.MaximumLength = devpath2.Length;
    vc->pnp_name.Buffer = ExAllocatePoolWithTag(PagedPool, devpath2.Length, ALLOC_TAG);

    if (vc->pnp_name.Buffer)
        RtlCopyMemory(vc->pnp_name.Buffer, devpath2.Buffer, devpath2.Length);
    else {
        ERR("out of memory\n");
        vc->pnp_name.Length = vc->pnp_name.MaximumLength = 0;
    }

    vc->size = length;
    vc->seeding = sb->flags & BTRFS_SUPERBLOCK_FLAGS_SEEDING ? TRUE : FALSE;
    vc->disk_num = disk_num;
    vc->part_num = part_num;
    vc->had_drive_letter = FALSE;

    le = pdode->children.Flink;
    while (le != &pdode->children) {
        volume_child* vc2 = CONTAINING_RECORD(le, volume_child, list_entry);

        if (vc2->generation < vc->generation) {
            if (le == pdode->children.Flink)
                pdode->num_children = sb->num_devices;

            InsertHeadList(vc2->list_entry.Blink, &vc->list_entry);
            inserted = TRUE;
            break;
        }

        le = le->Flink;
    }

    if (!inserted)
        InsertTailList(&pdode->children, &vc->list_entry);

    pdode->children_loaded++;

    if (pdode->vde && pdode->vde->mounted_device) {
        device_extension* Vcb = pdode->vde->mounted_device->DeviceExtension;

        ExAcquireResourceExclusiveLite(&Vcb->tree_lock, TRUE);

        le = Vcb->devices.Flink;
        while (le != &Vcb->devices) {
            device* dev = CONTAINING_RECORD(le, device, list_entry);

            if (!dev->devobj && RtlCompareMemory(&dev->devitem.device_uuid, &sb->dev_item.device_uuid, sizeof(BTRFS_UUID)) == sizeof(BTRFS_UUID)) {
                dev->devobj = DeviceObject;
                dev->disk_num = disk_num;
                dev->part_num = part_num;
                init_device(Vcb, dev, FALSE);
                break;
            }

            le = le->Flink;
        }

        ExReleaseResourceLite(&Vcb->tree_lock);
    }

    if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
        pdode->removable = TRUE;

        if (pdode->vde && pdode->vde->device)
            pdode->vde->device->Characteristics |= FILE_REMOVABLE_MEDIA;
    }

    if (pdode->num_children == pdode->children_loaded || (pdode->children_loaded == 1 && allow_degraded_mount(&sb->uuid))) {
        if (pdode->num_children == 1) {
            Status = remove_drive_letter(mountmgr, devpath);
            if (!NT_SUCCESS(Status) && Status != STATUS_NOT_FOUND)
                WARN("remove_drive_letter returned %08x\n", Status);

            vc->had_drive_letter = NT_SUCCESS(Status);
        } else {
            le = pdode->children.Flink;

            while (le != &pdode->children) {
                UNICODE_STRING name;

                vc = CONTAINING_RECORD(le, volume_child, list_entry);

                name.Length = name.MaximumLength = vc->pnp_name.Length + (3 * sizeof(WCHAR));
                name.Buffer = ExAllocatePoolWithTag(PagedPool, name.Length, ALLOC_TAG);

                if (!name.Buffer) {
                    ERR("out of memory\n");

                    ExReleaseResourceLite(&pdode->child_lock);
                    ExReleaseResourceLite(&pdo_list_lock);

                    goto fail;
                }

                RtlCopyMemory(name.Buffer, L"\\??", 3 * sizeof(WCHAR));
                RtlCopyMemory(&name.Buffer[3], vc->pnp_name.Buffer, vc->pnp_name.Length);

                Status = remove_drive_letter(mountmgr, &name);

                if (!NT_SUCCESS(Status) && Status != STATUS_NOT_FOUND)
                    WARN("remove_drive_letter returned %08x\n", Status);

                ExFreePool(name.Buffer);

                vc->had_drive_letter = NT_SUCCESS(Status);

                le = le->Flink;
            }
        }

        if ((!new_pdo || !no_pnp) && pdode->vde) {
            Status = IoSetDeviceInterfaceState(&pdode->vde->bus_name, TRUE);
            if (!NT_SUCCESS(Status))
                WARN("IoSetDeviceInterfaceState returned %08x\n", Status);
        }
    }

    ExReleaseResourceLite(&pdode->child_lock);

    if (new_pdo) {
        control_device_extension* cde = master_devobj->DeviceExtension;

        InsertTailList(&pdo_list, &pdode->list_entry);

        if (!no_pnp)
            IoInvalidateDeviceRelations(cde->buspdo, BusRelations);
    }

    ExReleaseResourceLite(&pdo_list_lock);

    if (new_pdo && no_pnp)
        AddDevice(drvobj, pdo);

    return;

fail:
    ObDereferenceObject(FileObject);
}
Пример #8
0
NTSTATUS
WdmAudOpenSysAudioDevices(
    IN PDEVICE_OBJECT DeviceObject,
    IN PWDMAUD_DEVICE_EXTENSION DeviceExtension)
{
    NTSTATUS Status = STATUS_SUCCESS;
    LPWSTR SymbolicLinkList;
    SYSAUDIO_ENTRY * Entry;
    ULONG Length;
    HANDLE hSysAudio;
    PFILE_OBJECT FileObject;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\sysaudio\\GLOBAL");

    if (DeviceExtension->DeviceInterfaceSupport)
    {
        Status = IoGetDeviceInterfaces(&KSCATEGORY_SYSAUDIO,
                                       NULL,
                                       0,
                                       &SymbolicLinkList);

        if (NT_SUCCESS(Status))
        {
            WdmAudOpenSysAudioDeviceInterfaces(DeviceExtension, SymbolicLinkList);
            FreeItem(SymbolicLinkList);
        }


        Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
                                                PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,
                                               (PVOID)&KSCATEGORY_SYSAUDIO,
                                                DeviceObject->DriverObject,
                                                DeviceInterfaceChangeCallback,
                                               (PVOID)DeviceExtension,
                                               &DeviceExtension->SysAudioNotification);
    }
    else
    {
            Entry = (SYSAUDIO_ENTRY*)AllocateItem(NonPagedPool, sizeof(SYSAUDIO_ENTRY));
            if (!Entry)
            {
                return STATUS_INSUFFICIENT_RESOURCES;
            }


            Length = wcslen(DeviceName.Buffer) + 1;
            Entry->SymbolicLink.Length = 0;
            Entry->SymbolicLink.MaximumLength = Length * sizeof(WCHAR);
            Entry->SymbolicLink.Buffer = AllocateItem(NonPagedPool, Entry->SymbolicLink.MaximumLength);

            if (!Entry->SymbolicLink.Buffer)
            {
                FreeItem(Entry);
                return STATUS_INSUFFICIENT_RESOURCES;
            }

            Status = RtlAppendUnicodeStringToString(&Entry->SymbolicLink, &DeviceName);

            if (!NT_SUCCESS(Status))
            {
                FreeItem(Entry->SymbolicLink.Buffer);
                FreeItem(Entry);
                return Status;
            }

            InsertTailList(&DeviceExtension->SysAudioDeviceList, &Entry->Entry);
            DeviceExtension->NumSysAudioDevices++;

            DPRINT("Opening device %S\n", Entry->SymbolicLink.Buffer);
            Status = WdmAudOpenSysAudioDevice(Entry->SymbolicLink.Buffer, &hSysAudio);
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("Failed to open sysaudio %x\n", Status);
                return Status;
            }

            /* get the file object */
            Status = ObReferenceObjectByHandle(hSysAudio, FILE_READ_DATA | FILE_WRITE_DATA, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("Failed to reference FileObject %x\n", Status);
                ZwClose(hSysAudio);
                return Status;
            }
            DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
            DeviceExtension->hSysAudio = hSysAudio;
            DeviceExtension->FileObject = FileObject;
    }

    return Status;
}