/* init child pdo*/
ChildDeviceExtension = (PHDA_PDO_DEVICE_EXTENSION)AudioGroup->ChildPDO->DeviceExtension;
ChildDeviceExtension->IsFDO = FALSE;
+ ChildDeviceExtension->ReportedMissing = FALSE;
ChildDeviceExtension->Codec = Entry;
ChildDeviceExtension->AudioGroup = AudioGroup;
ChildDeviceExtension->FDO = DeviceObject;
PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
ULONG CodecIndex, AFGIndex;
PHDA_CODEC_ENTRY CodecEntry;
+ PDEVICE_OBJECT ChildPDO;
+ PHDA_PDO_DEVICE_EXTENSION ChildDeviceExtension;
/* get device extension */
DeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
{
MmFreeContiguousMemory(DeviceExtension->CorbBase);
}
+
for (CodecIndex = 0; CodecIndex < HDA_MAX_CODECS; CodecIndex++)
{
CodecEntry = DeviceExtension->Codecs[CodecIndex];
for (AFGIndex = 0; AFGIndex < CodecEntry->AudioGroupCount; AFGIndex++)
{
+ ChildPDO = CodecEntry->AudioGroups[AFGIndex]->ChildPDO;
+ if (ChildPDO != NULL)
+ {
+ ChildDeviceExtension = static_cast<PHDA_PDO_DEVICE_EXTENSION>(ChildPDO->DeviceExtension);
+ ChildDeviceExtension->Codec = NULL;
+ ChildDeviceExtension->AudioGroup = NULL;
+ ChildDeviceExtension->FDO = NULL;
+ ChildDeviceExtension->ReportedMissing = TRUE;
+ HDA_PDORemoveDevice(ChildPDO);
+ }
FreeItem(CodecEntry->AudioGroups[AFGIndex]);
}
FreeItem(CodecEntry);
NTSTATUS Status;
PIO_STACK_LOCATION IoStack;
PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension;
+ ULONG CodecIndex, AFGIndex;
+ PHDA_CODEC_ENTRY CodecEntry;
+ PHDA_PDO_DEVICE_EXTENSION ChildDeviceExtension;
FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
IoStack = IoGetCurrentIrpStackLocation(Irp);
return Status;
case IRP_MN_REMOVE_DEVICE:
return HDA_FDORemoveDevice(DeviceObject, Irp);
+ case IRP_MN_SURPRISE_REMOVAL:
+ for (CodecIndex = 0; CodecIndex < HDA_MAX_CODECS; CodecIndex++)
+ {
+ CodecEntry = FDODeviceExtension->Codecs[CodecIndex];
+
+ for (AFGIndex = 0; AFGIndex < CodecEntry->AudioGroupCount; AFGIndex++)
+ {
+ ChildDeviceExtension = static_cast<PHDA_PDO_DEVICE_EXTENSION>(CodecEntry->AudioGroups[AFGIndex]->ChildPDO->DeviceExtension);
+ ChildDeviceExtension->ReportedMissing = TRUE;
+ }
+ }
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ break;
case IRP_MN_QUERY_REMOVE_DEVICE:
case IRP_MN_CANCEL_REMOVE_DEVICE:
Irp->IoStatus.Status = STATUS_SUCCESS;
/* no op for pdo */
Status = STATUS_SUCCESS;
break;
+ case IRP_MN_REMOVE_DEVICE:
+ Status = HDA_PDORemoveDevice(DeviceObject);
+ break;
+ case IRP_MN_QUERY_REMOVE_DEVICE:
+ case IRP_MN_CANCEL_REMOVE_DEVICE:
+ Status = STATUS_SUCCESS;
+ break;
case IRP_MN_QUERY_BUS_INFORMATION:
/* query bus information */
Status = HDA_PDOQueryBusInformation(Irp);
typedef struct
{
BOOLEAN IsFDO;
+ BOOLEAN ReportedMissing;
PHDA_CODEC_ENTRY Codec;
PHDA_CODEC_AUDIO_GROUP AudioGroup;
PDEVICE_OBJECT FDO;
/* pdo.cpp*/
+NTSTATUS
+HDA_PDORemoveDevice(
+ _In_ PDEVICE_OBJECT DeviceObject);
+
NTSTATUS
HDA_PDOQueryBusInformation(
IN PIRP Irp);
*/
#include "hdaudbus.h"
+NTSTATUS
+HDA_PDORemoveDevice(
+ _In_ PDEVICE_OBJECT DeviceObject)
+{
+ PHDA_PDO_DEVICE_EXTENSION DeviceExtension;
+
+ /* get device extension */
+ DeviceExtension = static_cast<PHDA_PDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
+ ASSERT(DeviceExtension->IsFDO == FALSE);
+
+ if (DeviceExtension->ReportedMissing)
+ {
+ if (DeviceExtension->AudioGroup != NULL)
+ {
+ DeviceExtension->AudioGroup->ChildPDO = NULL;
+ }
+ IoDeleteDevice(DeviceObject);
+ }
+
+ return STATUS_SUCCESS;
+}
+
NTSTATUS
HDA_PDOQueryBusInformation(
IN PIRP Irp)