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; }
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; }
// // 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; }