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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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