mirror of
https://github.com/reactos/reactos.git
synced 2024-09-12 13:54:41 +00:00
161 lines
4.2 KiB
C++
161 lines
4.2 KiB
C++
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS Kernel Streaming
|
|
* FILE: drivers/wdm/audio/backpln/portcls/unregister.cpp
|
|
* PURPOSE: Unregisters a subdevice
|
|
* PROGRAMMER: Johannes Anderwald
|
|
*/
|
|
|
|
#include "private.hpp"
|
|
|
|
#ifndef YDEBUG
|
|
#define NDEBUG
|
|
#endif
|
|
|
|
#include <debug.h>
|
|
|
|
class CUnregisterSubdevice : public IUnregisterSubdevice
|
|
{
|
|
public:
|
|
STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
|
|
|
|
STDMETHODIMP_(ULONG) AddRef()
|
|
{
|
|
InterlockedIncrement(&m_Ref);
|
|
return m_Ref;
|
|
}
|
|
STDMETHODIMP_(ULONG) Release()
|
|
{
|
|
InterlockedDecrement(&m_Ref);
|
|
|
|
if (!m_Ref)
|
|
{
|
|
delete this;
|
|
return 0;
|
|
}
|
|
return m_Ref;
|
|
}
|
|
|
|
|
|
IMP_IUnregisterSubdevice;
|
|
|
|
CUnregisterSubdevice(IUnknown * OuterUnknown) : m_Ref(0) {}
|
|
virtual ~CUnregisterSubdevice(){}
|
|
|
|
protected:
|
|
LONG m_Ref;
|
|
|
|
};
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
CUnregisterSubdevice::QueryInterface(
|
|
IN REFIID refiid,
|
|
OUT PVOID* Output)
|
|
{
|
|
UNICODE_STRING GuidString;
|
|
|
|
if (IsEqualGUIDAligned(refiid, IID_IUnregisterSubdevice) ||
|
|
IsEqualGUIDAligned(refiid, IID_IUnknown))
|
|
{
|
|
*Output = PVOID(PUNREGISTERSUBDEVICE(this));
|
|
PUNKNOWN(*Output)->AddRef();
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
|
|
{
|
|
DPRINT1("IPortWaveCyclic_fnQueryInterface no interface!!! iface %S\n", GuidString.Buffer);
|
|
RtlFreeUnicodeString(&GuidString);
|
|
}
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
CUnregisterSubdevice::UnregisterSubdevice(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PUNKNOWN Unknown)
|
|
{
|
|
PPCLASS_DEVICE_EXTENSION DeviceExtension;
|
|
PLIST_ENTRY Entry;
|
|
PSYMBOLICLINK_ENTRY SymLinkEntry;
|
|
PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor;
|
|
ISubdevice *SubDevice;
|
|
ULONG Index;
|
|
NTSTATUS Status;
|
|
|
|
PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
|
|
|
|
DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
PC_ASSERT(DeviceExtension);
|
|
|
|
// look up our undocumented interface
|
|
Status = Unknown->QueryInterface(IID_ISubdevice, (LPVOID*)&SubDevice);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT("No ISubdevice interface\n");
|
|
// the provided port driver doesnt support ISubdevice
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = SubDevice->GetDescriptor(&SubDeviceDescriptor);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT("Failed to retrieve subdevice descriptor %x\n", Status);
|
|
// the provided port driver doesnt support ISubdevice
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
// loop our create items and disable the create handler
|
|
for(Index = 0; Index < DeviceExtension->MaxSubDevices; Index++)
|
|
{
|
|
if (!RtlCompareUnicodeString(&SubDeviceDescriptor->RefString, &DeviceExtension->CreateItems[Index].ObjectClass, TRUE))
|
|
{
|
|
DeviceExtension->CreateItems[Index].Create = NULL;
|
|
RtlInitUnicodeString(&DeviceExtension->CreateItems[Index].ObjectClass, NULL);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// now unregister device interfaces
|
|
while(!IsListEmpty(&SubDeviceDescriptor->SymbolicLinkList))
|
|
{
|
|
// remove entry
|
|
Entry = RemoveHeadList(&SubDeviceDescriptor->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);
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
NewIUnregisterSubdevice(
|
|
OUT PUNREGISTERSUBDEVICE *OutDevice)
|
|
{
|
|
NTSTATUS Status;
|
|
CUnregisterSubdevice * This = new(NonPagedPool, TAG_PORTCLASS) CUnregisterSubdevice(NULL);
|
|
if (!This)
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
Status = This->QueryInterface(IID_IUnregisterSubdevice, (PVOID*)OutDevice);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
delete This;
|
|
return Status;
|
|
}
|
|
|
|
*OutDevice = (PUNREGISTERSUBDEVICE)This;
|
|
return Status;
|
|
}
|