Author: janderwald Date: Sat Jul 11 21:44:41 2009 New Revision: 41890
URL: http://svn.reactos.org/svn/reactos?rev=41890&view=rev Log: - Implement dynamic unregistration of audio devices - IoGetDeviceProperty expects the PDO, not FDO - Implement IUnregisterSubdevice interface for all port drivers
Added: trunk/reactos/drivers/wdm/audio/backpln/portcls/unregister.c (with props) Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/adapter.c trunk/reactos/drivers/wdm/audio/backpln/portcls/api.c trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c trunk/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavert.c trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/adapter.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/adapter.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/adapter.c [iso-8859-1] Sat Jul 11 21:44:41 2009 @@ -145,6 +145,8 @@ 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 */ @@ -237,6 +239,8 @@ SUBDEVICE_DESCRIPTOR * SubDeviceDescriptor; ULONG Index; UNICODE_STRING RefName; + PSUBDEVICE_ENTRY Entry; + PSYMBOLICLINK_ENTRY SymEntry;
DPRINT1("PcRegisterSubdevice DeviceObject %p Name %S Unknown %p\n", DeviceObject, Name, Unknown); ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); @@ -276,18 +280,36 @@ return STATUS_UNSUCCESSFUL; }
+ /* allocate subdevice entry */ + Entry = AllocateItem(NonPagedPool, sizeof(SUBDEVICE_ENTRY), TAG_PORTCLASS); + if (!Entry) + { + /* Insufficient memory */ + SubDevice->lpVtbl->Release(SubDevice); + return STATUS_INSUFFICIENT_RESOURCES; + } + /* add an create item to the device header */ Status = KsAddObjectCreateItemToDeviceHeader(DeviceExt->KsDeviceHeader, PcCreateItemDispatch, (PVOID)SubDevice, Name, NULL); if (!NT_SUCCESS(Status)) { /* failed to attach */ SubDevice->lpVtbl->Release(SubDevice); + FreeItem(Entry, TAG_PORTCLASS); DPRINT1("KsAddObjectCreateItemToDeviceHeader failed with %x\n", Status); return Status; }
/* initialize reference string */ RtlInitUnicodeString(&RefName, Name); + + /* initialize subdevice entry */ + Entry->SubDevice = SubDevice; + RtlInitUnicodeString(&Entry->Name, Name); + InitializeListHead(&Entry->SymbolicLinkList); + + /* store subdevice entry */ + InsertTailList(&DeviceExt->SubDeviceList, &Entry->Entry);
for(Index = 0; Index < SubDeviceDescriptor->InterfaceCount; Index++) { @@ -300,12 +322,26 @@ &SymbolicLinkName); if (NT_SUCCESS(Status)) { + /* activate device interface */ IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); - RtlFreeUnicodeString(&SymbolicLinkName); + /* allocate symbolic link entry */ + SymEntry = AllocateItem(NonPagedPool, sizeof(SYMBOLICLINK_ENTRY), TAG_PORTCLASS); + if (SymEntry) + { + /* initialize symbolic link item */ + RtlInitUnicodeString(&SymEntry->SymbolicLink, SymbolicLinkName.Buffer); + /* store item */ + InsertTailList(&Entry->SymbolicLinkList, &SymEntry->Entry); + } + else + { + /* allocating failed */ + RtlFreeUnicodeString(&SymbolicLinkName); + } } }
- /* Release SubDevice reference */ + /* release SubDevice reference */ SubDevice->lpVtbl->Release(SubDevice);
return STATUS_SUCCESS;
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/api.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/api.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/api.c [iso-8859-1] Sat Jul 11 21:44:41 2009 @@ -20,8 +20,13 @@ OUT PVOID PropertyBuffer, OUT PULONG ResultLength) { + PPCLASS_DEVICE_EXTENSION DeviceExtension; + ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); - return IoGetDeviceProperty(DeviceObject, DeviceProperty, BufferLength, PropertyBuffer, ResultLength); + + DeviceExtension = (PPCLASS_DEVICE_EXTENSION)((PDEVICE_OBJECT)DeviceObject)->DeviceExtension; + + return IoGetDeviceProperty(DeviceExtension->PhysicalDeviceObject, DeviceProperty, BufferLength, PropertyBuffer, ResultLength); }
/*
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c [iso-8859-1] Sat Jul 11 21:44:41 2009 @@ -91,5 +91,6 @@ const GUID IID_IMiniportWaveRT = {0x0f9fc4d6, 0x6061, 0x4f3c, {0xb1, 0xfc, 0x7, 0x5e, 0x35, 0xf7, 0x96, 0xa}}; const GUID IID_IMiniportWaveRTStream = {0x000ac9ab, 0xfaab, 0x4f3d, {0x94, 0x55, 0x6f, 0xf8, 0x30, 0x6a, 0x74, 0xa0}}; const GUID IID_IMiniportWaveRTStreamNotification = {0x23759128, 0x96f1, 0x423b, {0xab, 0x4d, 0x81, 0x63, 0x5b, 0xcf, 0x8c, 0xa1}}; +const GUID IID_IUnregisterSubdevice = {0x16738177, 0xe199, 0x41f9, {0x9a, 0x87, 0xab, 0xb2, 0xa5, 0x43, 0x2f, 0x21}}; +const GUID IID_IUnregisterPhysicalConnection = {0x6c38e231, 0x2a0d, 0x428d, {0x81, 0xf8, 0x07, 0xcc, 0x42, 0x8b, 0xb9, 0xa4}};
-
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.c [iso-8859-1] Sat Jul 11 21:44:41 2009 @@ -82,6 +82,10 @@ else if (IsEqualGUIDAligned(refiid, &IID_IPortClsVersion)) { return NewPortClsVersion((PPORTCLSVERSION*)Output); + } + else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterSubdevice)) + { + return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); }
if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c [iso-8859-1] Sat Jul 11 21:44:41 2009 @@ -100,6 +100,10 @@ else if (IsEqualGUIDAligned(refiid, &IID_IPortClsVersion)) { return NewPortClsVersion((PPORTCLSVERSION*)Output); + } + else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterSubdevice)) + { + return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); }
if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.c [iso-8859-1] Sat Jul 11 21:44:41 2009 @@ -225,6 +225,10 @@ IsEqualGUIDAligned(refiid, &IID_IDrmPort2)) { return NewIDrmPort((PDRMPORT2*)Output); + } + else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterSubdevice)) + { + return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); }
if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c [iso-8859-1] Sat Jul 11 21:44:41 2009 @@ -285,6 +285,10 @@ else if (IsEqualGUIDAligned(refiid, &IID_IPortClsVersion)) { return NewPortClsVersion((PPORTCLSVERSION*)Output); + } + else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterSubdevice)) + { + return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); }
if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavert.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavert.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavert.c [iso-8859-1] Sat Jul 11 21:44:41 2009 @@ -221,6 +221,10 @@ IsEqualGUIDAligned(refiid, &IID_IDrmPort2)) { return NewIDrmPort((PDRMPORT2*)Output); + } + else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterSubdevice)) + { + return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output); }
if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/portcls.rbuild [iso-8859-1] Sat Jul 11 21:44:41 2009 @@ -49,6 +49,7 @@ <file>resource.c</file> <file>service_group.c</file> <file>undoc.c</file> + <file>unregister.c</file> <file>version.c</file> <file>portcls.rc</file> </module>
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h [iso-8859-1] Sat Jul 11 21:44:41 2009 @@ -294,6 +294,12 @@ PcIoTimerRoutine( IN PDEVICE_OBJECT DeviceObject, IN PVOID Context); + +NTSTATUS +NTAPI +NewIUnregisterSubdevice( + OUT PUNREGISTERSUBDEVICE *OutDevice); +
#define DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PinSet,\ PropGeneral, PropInstances, PropIntersection)\ @@ -315,8 +321,17 @@ typedef struct { LIST_ENTRY Entry; - KSOBJECT_HEADER ObjectHeader; -}SUBDEVICE_ENTRY; + UNICODE_STRING SymbolicLink; +}SYMBOLICLINK_ENTRY, *PSYMBOLICLINK_ENTRY; + + +typedef struct +{ + LIST_ENTRY Entry; + ISubdevice *SubDevice; + UNICODE_STRING Name; + LIST_ENTRY SymbolicLinkList; +}SUBDEVICE_ENTRY, *PSUBDEVICE_ENTRY;
typedef struct {
Added: trunk/reactos/drivers/wdm/audio/backpln/portcls/unregister.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/unregister.c (added) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/unregister.c [iso-8859-1] Sat Jul 11 21:44:41 2009 @@ -1,0 +1,172 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/backpln/portcls/unregister.c + * PURPOSE: Unregisters a subdevice + * PROGRAMMER: Johannes Anderwald + */ + +#include "private.h" + +typedef struct +{ + IUnregisterSubdeviceVtbl *lpVtbl; + LONG ref; + +}IUnregisterSubdeviceImpl; + +NTSTATUS +NTAPI +IUnregisterSubdevice_fnQueryInterface( + IUnregisterSubdevice* iface, + IN REFIID refiid, + OUT PVOID* Output) +{ + IUnregisterSubdeviceImpl * This = (IUnregisterSubdeviceImpl*)iface; + + if (IsEqualGUIDAligned(refiid, &IID_IUnregisterSubdevice) || + IsEqualGUIDAligned(refiid, &IID_IUnknown)) + { + *Output = &This->lpVtbl; + InterlockedIncrement(&This->ref); + return STATUS_SUCCESS; + } + + return STATUS_UNSUCCESSFUL; +} + +ULONG +NTAPI +IUnregisterSubdevice_fnAddRef( + IUnregisterSubdevice* iface) +{ + IUnregisterSubdeviceImpl * This = (IUnregisterSubdeviceImpl*)iface; + + return InterlockedIncrement(&This->ref); +} + +ULONG +NTAPI +IUnregisterSubdevice_fnRelease( + IUnregisterSubdevice* iface) +{ + IUnregisterSubdeviceImpl * This = (IUnregisterSubdeviceImpl*)iface; + + InterlockedDecrement(&This->ref); + + if (This->ref == 0) + { + FreeItem(This, TAG_PORTCLASS); + return 0; + } + return This->ref; +} + +NTSTATUS +NTAPI +IUnregisterSubdevice_fnUnregisterSubdevice( + IUnregisterSubdevice* iface, + IN PDEVICE_OBJECT DeviceObject, + IN PUNKNOWN Unknown) +{ + PPCLASS_DEVICE_EXTENSION DeviceExtension; + PLIST_ENTRY Entry; + PSUBDEVICE_ENTRY SubDeviceEntry; + PSYMBOLICLINK_ENTRY SymLinkEntry; + ISubdevice *SubDevice; + ULONG Found; + ULONG Index; + NTSTATUS Status; + + ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); + + DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + ASSERT(DeviceExtension); + + /* look up our undocumented interface */ + Status = Unknown->lpVtbl->QueryInterface(Unknown, &IID_ISubdevice, (LPVOID)&SubDevice); + if (!NT_SUCCESS(Status)) + { + DPRINT1("No ISubdevice interface\n"); + /* the provided port driver doesnt support ISubdevice */ + return STATUS_INVALID_PARAMETER; + } + + Entry = DeviceExtension->SubDeviceList.Flink; + Found = FALSE; + /* loop subdevice entry list and search for the subdevice */ + while(Entry != &DeviceExtension->SubDeviceList) + { + SubDeviceEntry = (PSUBDEVICE_ENTRY)CONTAINING_RECORD(Entry, SUBDEVICE_ENTRY, Entry); + if (SubDeviceEntry->SubDevice == SubDevice) + { + Found = TRUE; + break; + } + Entry = Entry->Flink; + } + /* release the subdevice */ + SubDevice->lpVtbl->Release(SubDevice); + + if (!Found) + return STATUS_NOT_FOUND; + + /* remove subdevice entry */ + RemoveEntryList(&SubDeviceEntry->Entry); + + /* loop our create items and disable the create handler */ + for(Index = 0; Index < DeviceExtension->MaxSubDevices; Index++) + { + if (!RtlCompareUnicodeString(&SubDeviceEntry->Name, &DeviceExtension->CreateItems[Index].ObjectClass, TRUE)) + { + DeviceExtension->CreateItems[Index].Create = NULL; + RtlInitUnicodeString(&DeviceExtension->CreateItems[Index].ObjectClass, NULL); + break; + } + } + + /* now unregister device interfaces */ + while(!IsListEmpty(&SubDeviceEntry->SymbolicLinkList)) + { + /* remove entry */ + Entry = RemoveHeadList(&SubDeviceEntry->SymbolicLinkList); + /* get symlink entry */ + SymLinkEntry = (PSYMBOLICLINK_ENTRY)CONTAINING_RECORD(Entry, SYMBOLICLINK_ENTRY, Entry); + + /* unregister device interface */ + IoSetDeviceInterfaceState(&SymLinkEntry->SymbolicLink, FALSE); + /* free symbolic link */ + RtlFreeUnicodeString(&SymLinkEntry->SymbolicLink); + /* free sym entry */ + FreeItem(SymLinkEntry, TAG_PORTCLASS); + } + + /* free subdevice entry */ + ExFreePool(SubDeviceEntry); + + return STATUS_SUCCESS; +} + +static IUnregisterSubdeviceVtbl vt_IUnregisterSubdeviceVtbl = +{ + IUnregisterSubdevice_fnQueryInterface, + IUnregisterSubdevice_fnAddRef, + IUnregisterSubdevice_fnRelease, + IUnregisterSubdevice_fnUnregisterSubdevice +}; + +NTSTATUS +NTAPI +NewIUnregisterSubdevice( + OUT PUNREGISTERSUBDEVICE *OutDevice) +{ + IUnregisterSubdeviceImpl * This = AllocateItem(NonPagedPool, sizeof(IUnregisterSubdeviceImpl), TAG_PORTCLASS); + if (!This) + return STATUS_INSUFFICIENT_RESOURCES; + + This->lpVtbl = &vt_IUnregisterSubdeviceVtbl; + This->ref = 1; + + *OutDevice = (PUNREGISTERSUBDEVICE)&This->lpVtbl; + return STATUS_SUCCESS; +}
Propchange: trunk/reactos/drivers/wdm/audio/backpln/portcls/unregister.c ------------------------------------------------------------------------------ svn:eol-style = native