mirror of
https://github.com/reactos/reactos.git
synced 2024-08-05 19:11:16 +00:00
- Implement dynamic unregistration of audio devices
- IoGetDeviceProperty expects the PDO, not FDO - Implement IUnregisterSubdevice interface for all port drivers svn path=/trunk/; revision=41890
This commit is contained in:
parent
038d68b156
commit
9913f96067
|
@ -145,6 +145,8 @@ PcAddAdapterDevice(
|
|||
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 @@ PcRegisterSubdevice(
|
|||
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,12 +280,22 @@ PcRegisterSubdevice(
|
|||
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;
|
||||
}
|
||||
|
@ -289,6 +303,14 @@ PcRegisterSubdevice(
|
|||
/* 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++)
|
||||
{
|
||||
/* FIXME
|
||||
|
@ -300,12 +322,26 @@ PcRegisterSubdevice(
|
|||
&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;
|
||||
|
|
|
@ -20,8 +20,13 @@ PcGetDeviceProperty(
|
|||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -91,5 +91,6 @@ const GUID IID_IPortWaveRTStream = {0x1809ce5a, 0x64bc, 0x4e62,
|
|||
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}};
|
||||
|
||||
|
|
|
@ -83,6 +83,10 @@ IPortDMus_fnQueryInterface(
|
|||
{
|
||||
return NewPortClsVersion((PPORTCLSVERSION*)Output);
|
||||
}
|
||||
else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterSubdevice))
|
||||
{
|
||||
return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output);
|
||||
}
|
||||
|
||||
if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
|
||||
{
|
||||
|
|
|
@ -101,6 +101,10 @@ IPortTopology_fnQueryInterface(
|
|||
{
|
||||
return NewPortClsVersion((PPORTCLSVERSION*)Output);
|
||||
}
|
||||
else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterSubdevice))
|
||||
{
|
||||
return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output);
|
||||
}
|
||||
|
||||
if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
|
||||
{
|
||||
|
|
|
@ -226,6 +226,10 @@ IPortWaveCyclic_fnQueryInterface(
|
|||
{
|
||||
return NewIDrmPort((PDRMPORT2*)Output);
|
||||
}
|
||||
else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterSubdevice))
|
||||
{
|
||||
return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output);
|
||||
}
|
||||
|
||||
if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
|
||||
{
|
||||
|
|
|
@ -286,6 +286,10 @@ IPortWavePci_fnQueryInterface(
|
|||
{
|
||||
return NewPortClsVersion((PPORTCLSVERSION*)Output);
|
||||
}
|
||||
else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterSubdevice))
|
||||
{
|
||||
return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output);
|
||||
}
|
||||
|
||||
if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
|
||||
{
|
||||
|
|
|
@ -222,6 +222,10 @@ IPortWaveRT_fnQueryInterface(
|
|||
{
|
||||
return NewIDrmPort((PDRMPORT2*)Output);
|
||||
}
|
||||
else if (IsEqualGUIDAligned(refiid, &IID_IUnregisterSubdevice))
|
||||
{
|
||||
return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output);
|
||||
}
|
||||
|
||||
if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
|
||||
{
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -295,6 +295,12 @@ PcIoTimerRoutine(
|
|||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PVOID Context);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NewIUnregisterSubdevice(
|
||||
OUT PUNREGISTERSUBDEVICE *OutDevice);
|
||||
|
||||
|
||||
#define DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PinSet,\
|
||||
PropGeneral, PropInstances, PropIntersection)\
|
||||
DEFINE_KSPROPERTY_TABLE(PinSet) {\
|
||||
|
@ -315,8 +321,17 @@ DEFINE_KSPROPERTY_TABLE(PinSet) {\
|
|||
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
|
||||
{
|
||||
|
|
172
reactos/drivers/wdm/audio/backpln/portcls/unregister.c
Normal file
172
reactos/drivers/wdm/audio/backpln/portcls/unregister.c
Normal file
|
@ -0,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;
|
||||
}
|
Loading…
Reference in a new issue