- Fix tons of bugs in KsMergeAutomationTable
- Implement removing instantiated filter from filter factory when filter is about to be closed
- Fix a memory corrupion bug in KspHandleDataIntersection

svn path=/trunk/; revision=46780
This commit is contained in:
Johannes Anderwald 2010-04-08 20:14:38 +00:00
parent 169a95782a
commit 0d672ad7cd
2 changed files with 118 additions and 23 deletions

View file

@ -2096,8 +2096,15 @@ KspCountMethodSets(
if (!AutomationTableB) if (!AutomationTableB)
return AutomationTableA->MethodSetsCount; return AutomationTableA->MethodSetsCount;
/* sanity check */
ASSERT(AutomationTableA->MethodItemSize == AutomationTableB->MethodItemSize); DPRINT("AutomationTableA MethodItemSize %lu MethodSetsCount %lu\n", AutomationTableA->MethodItemSize, AutomationTableA->MethodSetsCount);
DPRINT("AutomationTableB MethodItemSize %lu MethodSetsCount %lu\n", AutomationTableB->MethodItemSize, AutomationTableB->MethodSetsCount);
if (AutomationTableA->MethodItemSize && AutomationTableB->MethodItemSize)
{
/* sanity check */
ASSERT(AutomationTableA->MethodItemSize == AutomationTableB->MethodItemSize);
}
/* now iterate all property sets and compare their guids */ /* now iterate all property sets and compare their guids */
Count = AutomationTableA->MethodSetsCount; Count = AutomationTableA->MethodSetsCount;
@ -2138,8 +2145,14 @@ KspCountEventSets(
if (!AutomationTableB) if (!AutomationTableB)
return AutomationTableA->EventSetsCount; return AutomationTableA->EventSetsCount;
/* sanity check */ DPRINT("AutomationTableA EventItemSize %lu EventSetsCount %lu\n", AutomationTableA->EventItemSize, AutomationTableA->EventSetsCount);
ASSERT(AutomationTableA->EventItemSize == AutomationTableB->EventItemSize); DPRINT("AutomationTableB EventItemSize %lu EventSetsCount %lu\n", AutomationTableB->EventItemSize, AutomationTableB->EventSetsCount);
if (AutomationTableA->EventItemSize && AutomationTableB->EventItemSize)
{
/* sanity check */
ASSERT(AutomationTableA->EventItemSize == AutomationTableB->EventItemSize);
}
/* now iterate all Event sets and compare their guids */ /* now iterate all Event sets and compare their guids */
Count = AutomationTableA->EventSetsCount; Count = AutomationTableA->EventSetsCount;
@ -2182,6 +2195,8 @@ KspCountPropertySets(
return AutomationTableA->PropertySetsCount; return AutomationTableA->PropertySetsCount;
/* sanity check */ /* sanity check */
DPRINT("AutomationTableA EventItemSize %lu PropertySetsCount %lu\n", AutomationTableA->PropertyItemSize, AutomationTableA->PropertySetsCount);
DPRINT("AutomationTableB EventItemSize %lu PropertySetsCount %lu\n", AutomationTableB->PropertyItemSize, AutomationTableB->PropertySetsCount);
ASSERT(AutomationTableA->PropertyItemSize == AutomationTableB->PropertyItemSize); ASSERT(AutomationTableA->PropertyItemSize == AutomationTableB->PropertyItemSize);
/* now iterate all property sets and compare their guids */ /* now iterate all property sets and compare their guids */
@ -2221,18 +2236,18 @@ KspCopyMethodSets(
if (!AutomationTableA) if (!AutomationTableA)
{ {
/* copy of property set */ /* copy of property set */
RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableB->MethodSets, Table->MethodItemSize * AutomationTableB->MethodSetsCount); RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableB->MethodSets, sizeof(KSMETHOD_SET) * AutomationTableB->MethodSetsCount);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
else if (!AutomationTableB) else if (!AutomationTableB)
{ {
/* copy of property set */ /* copy of property set */
RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableA->MethodSets, Table->MethodItemSize * AutomationTableA->MethodSetsCount); RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableA->MethodSets, sizeof(KSMETHOD_SET) * AutomationTableA->MethodSetsCount);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
/* first copy all property items from dominant table */ /* first copy all property items from dominant table */
RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableA->MethodSets, Table->MethodItemSize * AutomationTableA->MethodSetsCount); RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableA->MethodSets, sizeof(KSMETHOD_SET) * AutomationTableA->MethodSetsCount);
/* set counter */ /* set counter */
Count = AutomationTableA->MethodSetsCount; Count = AutomationTableA->MethodSetsCount;
@ -2255,7 +2270,7 @@ KspCopyMethodSets(
if (!bFound) if (!bFound)
{ {
/* copy new property item set */ /* copy new property item set */
RtlMoveMemory((PVOID)&Table->MethodSets[Count], &AutomationTableB->MethodSets[Index], Table->MethodItemSize); RtlMoveMemory((PVOID)&Table->MethodSets[Count], &AutomationTableB->MethodSets[Index], sizeof(KSMETHOD_SET));
Count++; Count++;
} }
} }
@ -2276,18 +2291,18 @@ KspCopyPropertySets(
if (!AutomationTableA) if (!AutomationTableA)
{ {
/* copy of property set */ /* copy of property set */
RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableB->PropertySets, Table->PropertyItemSize * AutomationTableB->PropertySetsCount); RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableB->PropertySets, sizeof(KSPROPERTY_SET) * AutomationTableB->PropertySetsCount);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
else if (!AutomationTableB) else if (!AutomationTableB)
{ {
/* copy of property set */ /* copy of property set */
RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableA->PropertySets, Table->PropertyItemSize * AutomationTableA->PropertySetsCount); RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableA->PropertySets, sizeof(KSPROPERTY_SET) * AutomationTableA->PropertySetsCount);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
/* first copy all property items from dominant table */ /* first copy all property items from dominant table */
RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableA->PropertySets, Table->PropertyItemSize * AutomationTableA->PropertySetsCount); RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableA->PropertySets, sizeof(KSPROPERTY_SET) * AutomationTableA->PropertySetsCount);
/* set counter */ /* set counter */
Count = AutomationTableA->PropertySetsCount; Count = AutomationTableA->PropertySetsCount;
@ -2310,7 +2325,7 @@ KspCopyPropertySets(
if (!bFound) if (!bFound)
{ {
/* copy new property item set */ /* copy new property item set */
RtlMoveMemory((PVOID)&Table->PropertySets[Count], &AutomationTableB->PropertySets[Index], Table->PropertyItemSize); RtlMoveMemory((PVOID)&Table->PropertySets[Count], &AutomationTableB->PropertySets[Index], sizeof(KSPROPERTY_SET));
Count++; Count++;
} }
} }
@ -2330,18 +2345,18 @@ KspCopyEventSets(
if (!AutomationTableA) if (!AutomationTableA)
{ {
/* copy of Event set */ /* copy of Event set */
RtlMoveMemory((PVOID)Table->EventSets, AutomationTableB->EventSets, Table->EventItemSize * AutomationTableB->EventSetsCount); RtlMoveMemory((PVOID)Table->EventSets, AutomationTableB->EventSets, sizeof(KSEVENT_SET) * AutomationTableB->EventSetsCount);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
else if (!AutomationTableB) else if (!AutomationTableB)
{ {
/* copy of Event set */ /* copy of Event set */
RtlMoveMemory((PVOID)Table->EventSets, AutomationTableA->EventSets, Table->EventItemSize * AutomationTableA->EventSetsCount); RtlMoveMemory((PVOID)Table->EventSets, AutomationTableA->EventSets, sizeof(KSEVENT_SET) * AutomationTableA->EventSetsCount);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
/* first copy all Event items from dominant table */ /* first copy all Event items from dominant table */
RtlMoveMemory((PVOID)Table->EventSets, AutomationTableA->EventSets, Table->EventItemSize * AutomationTableA->EventSetsCount); RtlMoveMemory((PVOID)Table->EventSets, AutomationTableA->EventSets, sizeof(KSEVENT_SET) * AutomationTableA->EventSetsCount);
/* set counter */ /* set counter */
Count = AutomationTableA->EventSetsCount; Count = AutomationTableA->EventSetsCount;
@ -2364,7 +2379,7 @@ KspCopyEventSets(
if (!bFound) if (!bFound)
{ {
/* copy new Event item set */ /* copy new Event item set */
RtlMoveMemory((PVOID)&Table->EventSets[Count], &AutomationTableB->EventSets[Index], Table->EventItemSize); RtlMoveMemory((PVOID)&Table->EventSets[Count], &AutomationTableB->EventSets[Index], sizeof(KSEVENT_SET));
Count++; Count++;
} }
} }
@ -2428,7 +2443,7 @@ KsMergeAutomationTables(
} }
/* now allocate the property sets */ /* now allocate the property sets */
Table->PropertySets = AllocateItem(NonPagedPool, Table->PropertyItemSize * Table->PropertySetsCount); Table->PropertySets = AllocateItem(NonPagedPool, sizeof(KSPROPERTY_SET) * Table->PropertySetsCount);
if (!Table->PropertySets) if (!Table->PropertySets)
{ {
@ -2471,7 +2486,7 @@ KsMergeAutomationTables(
} }
/* now allocate the property sets */ /* now allocate the property sets */
Table->MethodSets = AllocateItem(NonPagedPool, Table->MethodItemSize * Table->MethodSetsCount); Table->MethodSets = AllocateItem(NonPagedPool, sizeof(KSMETHOD_SET) * Table->MethodSetsCount);
if (!Table->MethodSets) if (!Table->MethodSets)
{ {
@ -2514,7 +2529,7 @@ KsMergeAutomationTables(
} }
/* now allocate the property sets */ /* now allocate the property sets */
Table->EventSets = AllocateItem(NonPagedPool, Table->EventItemSize * Table->EventSetsCount); Table->EventSets = AllocateItem(NonPagedPool, sizeof(KSEVENT_SET) * Table->EventSetsCount);
if (!Table->EventSets) if (!Table->EventSets)
{ {

View file

@ -44,6 +44,11 @@ const GUID IID_IKsFilter = {0x3ef6ee44L, 0x0D41, 0x11d2, {0xbe, 0xDA, 0x00, 0xc
const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
const GUID KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}}; const GUID KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
VOID
IKsFilter_RemoveFilterFromFilterFactory(
IKsFilterImpl * This,
PKSFILTERFACTORY FilterFactory);
DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet, KspTopologyPropertyHandler); DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet, KspTopologyPropertyHandler);
DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet, KspPinPropertyHandler, KspPinPropertyHandler, KspPinPropertyHandler); DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet, KspPinPropertyHandler, KspPinPropertyHandler, KspPinPropertyHandler);
@ -506,8 +511,8 @@ IKsFilter_DispatchClose(
/* complete irp */ /* complete irp */
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
/* FIXME remove our instance from the filter factory */ /* remove our instance from the filter factory */
ASSERT(0); IKsFilter_RemoveFilterFromFilterFactory(This, This->Factory);
/* free object header */ /* free object header */
KsFreeObjectHeader(This->ObjectHeader); KsFreeObjectHeader(This->ObjectHeader);
@ -605,6 +610,9 @@ KspHandleDataIntersection(
MultipleItem = (PKSMULTIPLE_ITEM)(Pin + 1); MultipleItem = (PKSMULTIPLE_ITEM)(Pin + 1);
DataRange = (PKSDATARANGE)(MultipleItem + 1); DataRange = (PKSDATARANGE)(MultipleItem + 1);
/* FIXME make sure its 64 bit aligned */
ASSERT(((ULONG_PTR)DataRange & 0x3F) == 0);
if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount) if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount)
{ {
/* no filter / pin descriptor */ /* no filter / pin descriptor */
@ -632,7 +640,7 @@ KspHandleDataIntersection(
Irp, Irp,
Pin, Pin,
DataRange, DataRange,
(PKSDATAFORMAT)This->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges, (PKSDATAFORMAT)This->PinDescriptorsEx[Pin->PinId].PinDescriptor.DataRanges,
DataLength, DataLength,
Data, Data,
&Length); &Length);
@ -643,6 +651,8 @@ KspHandleDataIntersection(
break; break;
} }
DataRange = UlongToPtr(PtrToUlong(DataRange) + DataRange->FormatSize); DataRange = UlongToPtr(PtrToUlong(DataRange) + DataRange->FormatSize);
/* FIXME make sure its 64 bit aligned */
ASSERT(((ULONG_PTR)DataRange & 0x3F) == 0);
} }
IoStatus->Status = Status; IoStatus->Status = Status;
@ -718,6 +728,8 @@ IKsFilter_DispatchDeviceIoControl(
IKsFilterImpl * This; IKsFilterImpl * This;
NTSTATUS Status; NTSTATUS Status;
PKSFILTER FilterInstance; PKSFILTER FilterInstance;
UNICODE_STRING GuidString;
PKSPROPERTY Property;
/* obtain filter from object header */ /* obtain filter from object header */
Status = IKsFilter_GetFilterFromIrp(Irp, &Filter); Status = IKsFilter_GetFilterFromIrp(Irp, &Filter);
@ -730,6 +742,14 @@ IKsFilter_DispatchDeviceIoControl(
/* current irp stack */ /* current irp stack */
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
/* property was not handled */
Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
RtlStringFromGUID(&Property->Set, &GuidString);
DPRINT("IKsFilter_DispatchDeviceIoControl property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
RtlFreeUnicodeString(&GuidString);
if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY) if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
@ -1126,12 +1146,72 @@ IKsFilter_AttachFilterToFilterFactory(
/* found last entry */ /* found last entry */
break; break;
} }
}while(FilterFactory); }while(TRUE);
/* attach filter factory */ /* attach filter factory */
BasicHeader->Next.Filter = &This->Filter; BasicHeader->Next.Filter = &This->Filter;
} }
VOID
IKsFilter_RemoveFilterFromFilterFactory(
IKsFilterImpl * This,
PKSFILTERFACTORY FilterFactory)
{
PKSBASIC_HEADER BasicHeader;
PKSFILTER Filter, LastFilter;
/* get filter factory basic header */
BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)FilterFactory - sizeof(KSBASIC_HEADER));
/* sanity check */
ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory);
ASSERT(BasicHeader->FirstChild.Filter != NULL);
/* set to first entry */
Filter = BasicHeader->FirstChild.Filter;
LastFilter = NULL;
do
{
if (Filter == &This->Filter)
{
if (LastFilter)
{
/* get basic header */
BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)LastFilter - sizeof(KSBASIC_HEADER));
/* remove filter instance */
BasicHeader->Next.Filter = This->Header.Next.Filter;
break;
}
else
{
/* remove filter instance */
BasicHeader->FirstChild.Filter = This->Header.Next.Filter;
break;
}
}
/* get basic header */
BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Filter - sizeof(KSBASIC_HEADER));
/* sanity check */
ASSERT(BasicHeader->Type == KsObjectTypeFilter);
LastFilter = Filter;
if (BasicHeader->Next.Filter)
{
/* iterate to next filter factory */
Filter = BasicHeader->Next.Filter;
}
else
{
/* filter is not in list */
ASSERT(0);
break;
}
}while(TRUE);
}
NTSTATUS NTSTATUS
NTAPI NTAPI
KspCreateFilter( KspCreateFilter(