- Partly implement IPortFilterWaveCyclic_fnNewIrpTarget

- Store KSPIN_DESCRIPTOR in subdevice descriptor
- Return correct result for IInterruptSync_fnCallSynchronizedRoutine
- Add stub interface for IPortPinWaveCyclic
- Implement PcValidateConnectRequest

svn path=/trunk/; revision=39605
This commit is contained in:
Johannes Anderwald 2009-02-15 13:29:01 +00:00
parent 6ea1608c49
commit 23bde85444
10 changed files with 622 additions and 11 deletions

View file

@ -6,6 +6,9 @@ typedef struct
LONG ref;
IPortWaveCyclic* Port;
IPortPinWaveCyclic * Pin;
}IPortFilterWaveCyclicImpl;
/*
@ -80,8 +83,53 @@ IPortFilterWaveCyclic_fnNewIrpTarget(
IN PIRP Irp,
IN KSOBJECT_CREATE *CreateObject)
{
ISubdevice * ISubDevice;
NTSTATUS Status;
IPortPinWaveCyclic * Pin;
return STATUS_UNSUCCESSFUL;
SUBDEVICE_DESCRIPTOR * Descriptor;
PKSPIN_CONNECT ConnectDetails;
IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl *)iface;
ASSERT(This->Port);
Status = This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&ISubDevice);
if (!NT_SUCCESS(Status))
return STATUS_UNSUCCESSFUL;
Status = ISubDevice->lpVtbl->GetDescriptor(ISubDevice, &Descriptor);
if (!NT_SUCCESS(Status))
return STATUS_UNSUCCESSFUL;
Status = PcValidateConnectRequest(Irp, &Descriptor->Factory, &ConnectDetails);
if (!NT_SUCCESS(Status))
{
ISubDevice->lpVtbl->Release(ISubDevice);
return STATUS_UNSUCCESSFUL;
}
ISubDevice->lpVtbl->Release(ISubDevice);
Status = NewPortPinWaveCyclic(&Pin);
if (!NT_SUCCESS(Status))
{
return Status;
}
Status = Pin->lpVtbl->Init(Pin, This->Port, iface, ConnectDetails, &Descriptor->Factory.KsPinDescriptor[ConnectDetails->PinId]);
if (!NT_SUCCESS(Status))
{
Pin->lpVtbl->Release(Pin);
return Status;
}
/* store pin handle */
This->Pin = Pin;
/* store result */
*OutTarget = (IIrpTarget*)Pin;
return Status;
}
/*
@ -256,7 +304,8 @@ static IPortFilterWaveCyclicVtbl vt_IPortFilterWaveCyclic =
NTSTATUS NewPortFilterWaveCyclic(
OUT IPortFilterWaveCyclic ** OutFilter)
OUT IPortFilterWaveCyclic ** OutFilter,
IN IPortWaveCyclic* iface)
{
IPortFilterWaveCyclicImpl * This;
@ -267,6 +316,10 @@ NTSTATUS NewPortFilterWaveCyclic(
/* initialize IPortFilterWaveCyclic */
This->ref = 1;
This->lpVtbl = &vt_IPortFilterWaveCyclic;
This->Port = iface;
/* increment reference count */
iface->lpVtbl->AddRef(iface);
/* return result */
*OutFilter = (IPortFilterWaveCyclic*)&This->lpVtbl;

View file

@ -97,10 +97,18 @@ DECLARE_INTERFACE_(IIrpTarget, IUnknown)
struct IIrpTargetFactory;
typedef struct
{
ULONG PinDescriptorCount;
ULONG PinDescriptorSize;
KSPIN_DESCRIPTOR * KsPinDescriptor;
}KSPIN_FACTORY;
typedef struct
{
ULONG InterfaceCount;
GUID *Interfaces;
KSPIN_FACTORY Factory;
}SUBDEVICE_DESCRIPTOR, *PSUBDEVICE_DESCRIPTOR;
#undef INTERFACE

View file

@ -120,7 +120,7 @@ IInterruptSync_fnCallSynchronizedRoutine(
KIRQL OldIrql;
IInterruptSyncImpl * This = (IInterruptSyncImpl*)iface;
DPRINT1("IInterruptSync_fnCallSynchronizedRoutine This %p Routine %p DynamicContext %p\n", This, Routine, DynamicContext);
DPRINT1("IInterruptSync_fnCallSynchronizedRoutine This %p Routine %p DynamicContext %p Irql %x Interrupt %p\n", This, Routine, DynamicContext, KeGetCurrentIrql(), This->Interrupt);
if (!This->Interrupt)
{
@ -140,7 +140,10 @@ IInterruptSync_fnCallSynchronizedRoutine(
This->SyncRoutine = Routine;
This->DynamicContext = DynamicContext;
return KeSynchronizeExecution(This->Interrupt, IInterruptSynchronizedRoutine, (PVOID)This);
if (KeSynchronizeExecution(This->Interrupt, IInterruptSynchronizedRoutine, (PVOID)This))
return STATUS_SUCCESS;
else
return STATUS_UNSUCCESSFUL;
}
NTAPI

View file

@ -0,0 +1,486 @@
#include "private.h"
typedef struct
{
IPortPinWaveCyclicVtbl *lpVtbl;
IServiceSinkVtbl *lpVtblServiceSink;
LONG ref;
IPortWaveCyclic * Port;
IPortFilterWaveCyclic * Filter;
KSPIN_DESCRIPTOR * KsPinDescriptor;
}IPortPinWaveCyclicImpl;
//==================================================================================================================================
static
NTSTATUS
NTAPI
IServiceSink_fnQueryInterface(
IServiceSink* iface,
IN REFIID refiid,
OUT PVOID* Output)
{
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortPinWaveCyclicImpl, lpVtblServiceSink);
DPRINT("IServiceSink_fnQueryInterface entered\n");
if (IsEqualGUIDAligned(refiid, &IID_IServiceSink) ||
IsEqualGUIDAligned(refiid, &IID_IUnknown))
{
*Output = &This->lpVtblServiceSink;
InterlockedIncrement(&This->ref);
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
}
static
ULONG
NTAPI
IServiceSink_fnAddRef(
IServiceSink* iface)
{
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortPinWaveCyclicImpl, lpVtblServiceSink);
DPRINT("IServiceSink_fnAddRef entered\n");
return InterlockedIncrement(&This->ref);
}
static
ULONG
NTAPI
IServiceSink_fnRelease(
IServiceSink* iface)
{
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortPinWaveCyclicImpl, lpVtblServiceSink);
InterlockedDecrement(&This->ref);
DPRINT("IServiceSink_fnRelease entered %u\n", This->ref);
if (This->ref == 0)
{
FreeItem(This, TAG_PORTCLASS);
return 0;
}
/* Return new reference count */
return This->ref;
}
static
VOID
NTAPI
IServiceSink_fnRequestService(
IServiceSink* iface)
{
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortPinWaveCyclicImpl, lpVtblServiceSink);
DPRINT("IServiceSink_fnRequestService entered %p\n", This);
}
static IServiceSinkVtbl vt_IServiceSink =
{
IServiceSink_fnQueryInterface,
IServiceSink_fnAddRef,
IServiceSink_fnRelease,
IServiceSink_fnRequestService
};
//==================================================================================================================================
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortPinWaveCyclic_fnQueryInterface(
IPortPinWaveCyclic* iface,
IN REFIID refiid,
OUT PVOID* Output)
{
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
if (IsEqualGUIDAligned(refiid, &IID_IIrpTarget) ||
//IsEqualGUIDAligned(refiid, &IID_IPortPinWaveCyclic) ||
IsEqualGUIDAligned(refiid, &IID_IUnknown))
{
*Output = &This->lpVtbl;
InterlockedIncrement(&This->ref);
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
}
/*
* @implemented
*/
ULONG
NTAPI
IPortPinWaveCyclic_fnAddRef(
IPortPinWaveCyclic* iface)
{
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
return InterlockedIncrement(&This->ref);
}
/*
* @implemented
*/
ULONG
NTAPI
IPortPinWaveCyclic_fnRelease(
IPortPinWaveCyclic* iface)
{
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
InterlockedDecrement(&This->ref);
if (This->ref == 0)
{
FreeItem(This, TAG_PORTCLASS);
return 0;
}
return This->ref;
}
/*
* @unimplemented
*/
NTSTATUS
NTAPI
IPortPinWaveCyclic_fnNewIrpTarget(
IN IPortPinWaveCyclic* iface,
OUT struct IIrpTarget **OutTarget,
IN WCHAR * Name,
IN PUNKNOWN Unknown,
IN POOL_TYPE PoolType,
IN PDEVICE_OBJECT * DeviceObject,
IN PIRP Irp,
IN KSOBJECT_CREATE *CreateObject)
{
return STATUS_UNSUCCESSFUL;
}
/*
* @unimplemented
*/
NTSTATUS
NTAPI
IPortPinWaveCyclic_fnDeviceIoControl(
IN IPortPinWaveCyclic* iface,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
UNIMPLEMENTED
IoStack = IoGetCurrentIrpStackLocation(Irp);
if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY)
{
/// FIXME
/// handle property event
}
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT)
{
/// FIXME
/// handle enable event
}
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_DISABLE_EVENT)
{
/// FIXME
/// handle disable event
}
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_RESET_STATE)
{
/// FIXME
/// handle reset state
}
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM || IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_READ_STREAM)
{
/// FIXME
/// handle reset state
}
else
{
return KsDefaultDeviceIoCompletion(DeviceObject, Irp);
}
return STATUS_UNSUCCESSFUL;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortPinWaveCyclic_fnRead(
IN IPortPinWaveCyclic* iface,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortPinWaveCyclic_fnWrite(
IN IPortPinWaveCyclic* iface,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortPinWaveCyclic_fnFlush(
IN IPortPinWaveCyclic* iface,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
}
/*
* @unimplemented
*/
NTSTATUS
NTAPI
IPortPinWaveCyclic_fnClose(
IN IPortPinWaveCyclic* iface,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
return STATUS_UNSUCCESSFUL;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortPinWaveCyclic_fnQuerySecurity(
IN IPortPinWaveCyclic* iface,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortPinWaveCyclic_fnSetSecurity(
IN IPortPinWaveCyclic* iface,
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortPinWaveCyclic_fnFastDeviceIoControl(
IN IPortPinWaveCyclic* iface,
IN PFILE_OBJECT FileObject,
IN BOOLEAN Wait,
IN PVOID InputBuffer,
IN ULONG InputBufferLength,
OUT PVOID OutputBuffer,
IN ULONG OutputBufferLength,
IN ULONG IoControlCode,
OUT PIO_STATUS_BLOCK StatusBlock,
IN PDEVICE_OBJECT DeviceObject)
{
return STATUS_SUCCESS;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortPinWaveCyclic_fnFastRead(
IN IPortPinWaveCyclic* iface,
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN BOOLEAN Wait,
IN ULONG LockKey,
IN PVOID Buffer,
OUT PIO_STATUS_BLOCK StatusBlock,
IN PDEVICE_OBJECT DeviceObject)
{
return STATUS_SUCCESS;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
IPortPinWaveCyclic_fnFastWrite(
IN IPortPinWaveCyclic* iface,
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN BOOLEAN Wait,
IN ULONG LockKey,
IN PVOID Buffer,
OUT PIO_STATUS_BLOCK StatusBlock,
IN PDEVICE_OBJECT DeviceObject)
{
return STATUS_SUCCESS;
}
/*
* @unimplemented
*/
NTSTATUS
NTAPI
IPortPinWaveCyclic_fnInit(
IN IPortPinWaveCyclic* iface,
IN PPORTWAVECYCLIC Port,
IN PPORTFILTERWAVECYCLIC Filter,
IN KSPIN_CONNECT * ConnectDetails,
IN KSPIN_DESCRIPTOR * KsPinDescriptor)
{
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
Port->lpVtbl->AddRef(Port);
Filter->lpVtbl->AddRef(Filter);
This->Port = Port;
This->Filter = Filter;
This->KsPinDescriptor = KsPinDescriptor;
return STATUS_SUCCESS;
}
/*
* @unimplemented
*/
ULONG
NTAPI
IPortPinWaveCyclic_fnGetCompletedPosition(
IN IPortPinWaveCyclic* iface)
{
UNIMPLEMENTED;
return 0;
}
/*
* @unimplemented
*/
ULONG
NTAPI
IPortPinWaveCyclic_fnGetCycleCount(
IN IPortPinWaveCyclic* iface)
{
UNIMPLEMENTED;
return 0;
}
/*
* @unimplemented
*/
ULONG
NTAPI
IPortPinWaveCyclic_fnGetDeviceBufferSize(
IN IPortPinWaveCyclic* iface)
{
UNIMPLEMENTED;
return 0;
}
/*
* @unimplemented
*/
PVOID
NTAPI
IPortPinWaveCyclic_fnGetIrpStream(
IN IPortPinWaveCyclic* iface)
{
UNIMPLEMENTED;
return NULL;
}
/*
* @implemented
*/
PMINIPORT
NTAPI
IPortPinWaveCyclic_fnGetMiniport(
IN IPortPinWaveCyclic* iface)
{
UNIMPLEMENTED;
return NULL;
}
static IPortPinWaveCyclicVtbl vt_IPortPinWaveCyclic =
{
IPortPinWaveCyclic_fnQueryInterface,
IPortPinWaveCyclic_fnAddRef,
IPortPinWaveCyclic_fnRelease,
IPortPinWaveCyclic_fnNewIrpTarget,
IPortPinWaveCyclic_fnDeviceIoControl,
IPortPinWaveCyclic_fnRead,
IPortPinWaveCyclic_fnWrite,
IPortPinWaveCyclic_fnFlush,
IPortPinWaveCyclic_fnClose,
IPortPinWaveCyclic_fnQuerySecurity,
IPortPinWaveCyclic_fnSetSecurity,
IPortPinWaveCyclic_fnFastDeviceIoControl,
IPortPinWaveCyclic_fnFastRead,
IPortPinWaveCyclic_fnFastWrite,
IPortPinWaveCyclic_fnInit,
IPortPinWaveCyclic_fnGetCompletedPosition,
IPortPinWaveCyclic_fnGetCycleCount,
IPortPinWaveCyclic_fnGetDeviceBufferSize,
IPortPinWaveCyclic_fnGetIrpStream,
IPortPinWaveCyclic_fnGetMiniport
};
NTSTATUS NewPortPinWaveCyclic(
OUT IPortPinWaveCyclic ** OutPin)
{
IPortPinWaveCyclicImpl * This;
This = AllocateItem(NonPagedPool, sizeof(IPortPinWaveCyclicImpl), TAG_PORTCLASS);
if (!This)
return STATUS_INSUFFICIENT_RESOURCES;
/* initialize IPortPinWaveCyclic */
This->ref = 1;
This->lpVtbl = &vt_IPortPinWaveCyclic;
This->lpVtblServiceSink = &vt_IServiceSink;
/* store result */
*OutPin = (IPortPinWaveCyclic*)&This->lpVtbl;
return STATUS_SUCCESS;
}

View file

@ -22,5 +22,5 @@ FreeItem(
IN ULONG Tag)
{
//ExFreePoolWithTag(Item, Tag);
ExFreePoolWithTag(Item, Tag);
}

View file

@ -97,7 +97,7 @@ IPortEvents_fnRelease(
IPortEvents* iface)
{
IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, lpVtblPortEvents);
DPRINT1("IPortEvents_fnQueryInterface entered\n");
DPRINT1("IPortEvents_fnRelease entered\n");
InterlockedDecrement(&This->ref);
if (This->ref == 0)
@ -272,7 +272,7 @@ IPortWaveCyclic_fnInit(
PPOWERNOTIFY PowerNotify;
IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)iface;
DPRINT1("IPortWaveCyclic_Init entered\n");
DPRINT1("IPortWaveCyclic_Init entered %p\n", This);
if (This->bInitialized)
{
@ -537,12 +537,21 @@ ISubDevice_fnNewIrpTarget(
IN PUNKNOWN Unknown,
IN POOL_TYPE PoolType,
IN PDEVICE_OBJECT * DeviceObject,
IN PIRP Irp,
IN PIRP Irp,
IN KSOBJECT_CREATE *CreateObject)
{
NTSTATUS Status;
IPortFilterWaveCyclic * Filter;
IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, lpVtblSubDevice);
DPRINT1("ISubDevice_NewIrpTarget this %p\n", This);
Status = NewPortFilterWaveCyclic(&Filter, (IPortWaveCyclic*)This);
if (NT_SUCCESS(Status))
{
*OutTarget = (IIrpTarget*)Filter;
}
return STATUS_UNSUCCESSFUL;
}
@ -567,9 +576,11 @@ ISubDevice_fnGetDescriptor(
{
IPortWaveCyclicImpl * This = (IPortWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortWaveCyclicImpl, lpVtblSubDevice);
ASSERT(This->SubDeviceDescriptor != NULL);
*Descriptor = This->SubDeviceDescriptor;
DPRINT1("ISubDevice_GetDescriptor this %p\n", This);
DPRINT1("ISubDevice_GetDescriptor this %p desc %p\n", This, This->SubDeviceDescriptor);
return STATUS_SUCCESS;
}

View file

@ -26,6 +26,7 @@
<file>resource.c</file>
<file>registry.c</file>
<file>service_group.c</file>
<file>pin_wavecyclic.c</file>
<file>pool.c</file>
<file>port.c</file>
<file>power.c</file>

View file

@ -83,7 +83,11 @@ NTSTATUS NewPortClsVersion(
OUT PPORTCLSVERSION * OutVersion);
NTSTATUS NewPortFilterWaveCyclic(
OUT IPortFilterWaveCyclic ** OutFilter);
OUT IPortFilterWaveCyclic ** OutFilter,
IN IPortWaveCyclic* iface);
NTSTATUS NewPortPinWaveCyclic(
OUT IPortPinWaveCyclic ** OutPin);
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag);
@ -177,6 +181,13 @@ PcCreateSubdeviceDescriptor(
IN KSEVENT_SET * EventSet,
IN PPCFILTER_DESCRIPTOR FilterDescription);
NTSTATUS
NTAPI
PcValidateConnectRequest(
IN PIRP Irp,
IN KSPIN_FACTORY * Descriptor,
OUT PKSPIN_CONNECT* Connect);
NTSTATUS
NTAPI
PcCreateItemDispatch(

View file

@ -37,7 +37,8 @@ IServiceGroup_fnQueryInterface(
{
IServiceGroupImpl * This = (IServiceGroupImpl*)iface;
if (IsEqualGUIDAligned(refiid, &IID_IServiceGroup) ||
IsEqualGUIDAligned(refiid, &IID_IServiceSink))
IsEqualGUIDAligned(refiid, &IID_IServiceSink) ||
IsEqualGUIDAligned(refiid, &IID_IUnknown))
{
*Output = &This->lpVtbl;
InterlockedIncrement(&This->ref);

View file

@ -102,6 +102,7 @@ PcCreateSubdeviceDescriptor(
IN PPCFILTER_DESCRIPTOR FilterDescription)
{
SUBDEVICE_DESCRIPTOR * Descriptor;
ULONG Index;
NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
Descriptor = AllocateItem(NonPagedPool, sizeof(SUBDEVICE_DESCRIPTOR), TAG_PORTCLASS);
@ -116,6 +117,24 @@ PcCreateSubdeviceDescriptor(
RtlCopyMemory(Descriptor->Interfaces, InterfaceGuids, sizeof(GUID) * InterfaceCount);
Descriptor->InterfaceCount = InterfaceCount;
if (FilterDescription->PinCount)
{
/// FIXME
/// handle extra size
ASSERT(FilterDescription->PinSize == sizeof(KSPIN_DESCRIPTOR));
Descriptor->Factory.KsPinDescriptor = AllocateItem(NonPagedPool, sizeof(KSPIN_DESCRIPTOR) * FilterDescription->PinCount, TAG_PORTCLASS);
if (!Descriptor->Factory.KsPinDescriptor)
goto cleanup;
Descriptor->Factory.PinDescriptorCount = FilterDescription->PinCount;
Descriptor->Factory.PinDescriptorSize = FilterDescription->PinSize;
/* copy pin factories */
for(Index = 0; Index < FilterDescription->PinCount; Index++)
RtlMoveMemory(&Descriptor->Factory.KsPinDescriptor[Index], &FilterDescription->Pins[Index].KsPinDescriptor, sizeof(KSPIN_DESCRIPTOR));
}
*OutSubdeviceDescriptor = Descriptor;
return STATUS_SUCCESS;
@ -125,11 +144,29 @@ cleanup:
if (Descriptor->Interfaces)
FreeItem(Descriptor->Interfaces, TAG_PORTCLASS);
if (Descriptor->Factory.KsPinDescriptor)
FreeItem(Descriptor->Factory.KsPinDescriptor, TAG_PORTCLASS);
FreeItem(Descriptor, TAG_PORTCLASS);
}
return Status;
}
/*
* @implemented
*/
NTSTATUS
NTAPI
PcValidateConnectRequest(
IN PIRP Irp,
IN KSPIN_FACTORY * Factory,
OUT PKSPIN_CONNECT * Connect)
{
return KsValidateConnectRequest(Irp, Factory->PinDescriptorCount, Factory->KsPinDescriptor, Connect);
}
/* PcDeleteSubdeviceDescriptor */
/* PcFreeEventTable */