Author: janderwald
Date: Fri Apr 9 20:31:53 2010
New Revision: 46794
URL:
http://svn.reactos.org/svn/reactos?rev=46794&view=rev
Log:
[KS]
- Return status success from unimplemented IKsClock_DispatchClose
- Implement handling of KSPROPERTY_PIN_CONSTRAINEDDATARANGES property
- Forward unhandled irps to lower device object
- Fix asserts in KspHandleDataIntersection. The function is still a grotesk hack
- Simply handling of property requests by merging filter properties into filter
descriptor
- Implement KsMethodHandler, KsMethodHandlerWithAllocator, KsFastMethodHandler
- Fix a bug in KsPinGetFirstCloneStreamPointer
- Implement handling of KSPROPSETID_Topology (KspTopologyHandler)
Modified:
trunk/reactos/drivers/ksfilter/ks/api.c
trunk/reactos/drivers/ksfilter/ks/clocks.c
trunk/reactos/drivers/ksfilter/ks/connectivity.c
trunk/reactos/drivers/ksfilter/ks/device.c
trunk/reactos/drivers/ksfilter/ks/filter.c
trunk/reactos/drivers/ksfilter/ks/irp.c
trunk/reactos/drivers/ksfilter/ks/ksfunc.h
trunk/reactos/drivers/ksfilter/ks/methods.c
trunk/reactos/drivers/ksfilter/ks/pin.c
trunk/reactos/drivers/ksfilter/ks/topology.c
Modified: trunk/reactos/drivers/ksfilter/ks/api.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/api.c?…
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/api.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/api.c [iso-8859-1] Fri Apr 9 20:31:53 2010
@@ -2195,8 +2195,8 @@
return AutomationTableA->PropertySetsCount;
/* sanity check */
- DPRINT("AutomationTableA EventItemSize %lu PropertySetsCount %lu\n",
AutomationTableA->PropertyItemSize, AutomationTableA->PropertySetsCount);
- DPRINT("AutomationTableB EventItemSize %lu PropertySetsCount %lu\n",
AutomationTableB->PropertyItemSize, AutomationTableB->PropertySetsCount);
+ DPRINT("AutomationTableA PropertyItemSize %lu PropertySetsCount %lu\n",
AutomationTableA->PropertyItemSize, AutomationTableA->PropertySetsCount);
+ DPRINT("AutomationTableB PropertyItemSize %lu PropertySetsCount %lu\n",
AutomationTableB->PropertyItemSize, AutomationTableB->PropertySetsCount);
ASSERT(AutomationTableA->PropertyItemSize ==
AutomationTableB->PropertyItemSize);
/* now iterate all property sets and compare their guids */
Modified: trunk/reactos/drivers/ksfilter/ks/clocks.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/clocks…
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/clocks.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/clocks.c [iso-8859-1] Fri Apr 9 20:31:53 2010
@@ -112,13 +112,11 @@
{
UNIMPLEMENTED
- Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_NOT_IMPLEMENTED;
-}
-
-
+ return STATUS_SUCCESS;
+}
static KSDISPATCH_TABLE DispatchTable =
{
Modified: trunk/reactos/drivers/ksfilter/ks/connectivity.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/connec…
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/connectivity.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/connectivity.c [iso-8859-1] Fri Apr 9 20:31:53
2010
@@ -287,11 +287,13 @@
PKSDATAFORMAT_WAVEFORMATEX WaveFormatIn;
PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
NTSTATUS Status = STATUS_NOT_SUPPORTED;
+ ULONG Count;
+ const PKSDATARANGE* DataRanges;
IoStack = IoGetCurrentIrpStackLocation(Irp);
Buffer = Irp->UserBuffer;
- DPRINT("KsPinPropertyHandler Irp %p Property %p Data %p DescriptorsCount %u
Descriptor %p OutputLength %u Id %u\n", Irp, Property, Data, DescriptorsCount,
Descriptor, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Property->Id);
+ //DPRINT("KsPinPropertyHandler Irp %p Property %p Data %p DescriptorsCount %u
Descriptor %p OutputLength %u Id %u\n", Irp, Property, Data, DescriptorsCount,
Descriptor, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Property->Id);
switch(Property->Id)
{
@@ -322,6 +324,7 @@
break;
case KSPROPERTY_PIN_DATARANGES:
+ case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
Pin = (KSP_PIN*)Property;
if (Pin->PinId >= DescriptorsCount)
{
@@ -330,9 +333,20 @@
break;
}
Size = sizeof(KSMULTIPLE_ITEM);
- for (Index = 0; Index < Descriptor[Pin->PinId].DataRangesCount;
Index++)
- {
- Size += Descriptor[Pin->PinId].DataRanges[Index]->FormatSize;
+ if (Property->Id == KSPROPERTY_PIN_DATARANGES ||
Descriptor[Pin->PinId].ConstrainedDataRangesCount == 0)
+ {
+ DataRanges = Descriptor[Pin->PinId].DataRanges;
+ Count = Descriptor[Pin->PinId].DataRangesCount;
+ }
+ else
+ {
+ DataRanges = Descriptor[Pin->PinId].ConstrainedDataRanges;
+ Count = Descriptor[Pin->PinId].ConstrainedDataRangesCount;
+ }
+
+ for (Index = 0; Index < Count; Index++)
+ {
+ Size += ((DataRanges[Index]->FormatSize + 0x7) & ~0x7);
}
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == 0)
@@ -354,16 +368,9 @@
break;
}
- if (IoStack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(KSMULTIPLE_ITEM))
- {
- /* buffer too small */
- Status = STATUS_BUFFER_TOO_SMALL;
- break;
- }
-
/* store descriptor size */
Item->Size = Size;
- Item->Count = Descriptor[Pin->PinId].DataRangesCount;
+ Item->Count = Count;
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength ==
sizeof(KSMULTIPLE_ITEM))
{
@@ -374,10 +381,29 @@
/* now copy all dataranges */
Data = (PUCHAR)(Item +1);
- for (Index = 0; Index < Descriptor[Pin->PinId].DataRangesCount;
Index++)
- {
- RtlMoveMemory(Data, Descriptor[Pin->PinId].DataRanges[Index],
Descriptor[Pin->PinId].DataRanges[Index]->FormatSize);
- Data = ((PUCHAR)Data +
Descriptor[Pin->PinId].DataRanges[Index]->FormatSize);
+
+ /* alignment assert */
+ ASSERT(((ULONG_PTR)Data & 0x7) == 0);
+
+ for (Index = 0; Index < Count; Index++)
+ {
+ UNICODE_STRING GuidString;
+ /* convert the guid to string */
+ RtlStringFromGUID(&DataRanges[Index]->MajorFormat,
&GuidString);
+ DPRINT("Index %lu MajorFormat %S\n", Index,
GuidString.Buffer);
+ RtlStringFromGUID(&DataRanges[Index]->SubFormat,
&GuidString);
+ DPRINT("Index %lu SubFormat %S\n", Index, GuidString.Buffer);
+ RtlStringFromGUID(&DataRanges[Index]->Specifier,
&GuidString);
+ DPRINT("Index %lu Specifier %S\n", Index, GuidString.Buffer);
+ RtlStringFromGUID(&DataRanges[Index]->Specifier,
&GuidString);
+ DPRINT("Index %lu FormatSize %lu Flags %lu SampleSize %lu Reserved
%lu KSDATAFORMAT %lu\n", Index,
+ DataRanges[Index]->FormatSize, DataRanges[Index]->Flags,
DataRanges[Index]->SampleSize, DataRanges[Index]->Reserved, sizeof(KSDATAFORMAT));
+
+ RtlMoveMemory(Data, DataRanges[Index],
DataRanges[Index]->FormatSize);
+ Data = ((PUCHAR)Data + DataRanges[Index]->FormatSize);
+ /* alignment assert */
+ ASSERT(((ULONG_PTR)Data & 0x7) == 0);
+ Data = (PVOID)(((ULONG_PTR)Data + 0x7) & ~0x7);
}
Status = STATUS_SUCCESS;
@@ -442,7 +468,9 @@
break;
}
+ //DPRINT("Pin %lu Communication %lu\n", Pin->PinId,
Descriptor[Pin->PinId].Communication);
*((KSPIN_COMMUNICATION*)Buffer) = Descriptor[Pin->PinId].Communication;
+
Status = STATUS_SUCCESS;
Irp->IoStatus.Information = Size;
break;
Modified: trunk/reactos/drivers/ksfilter/ks/device.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/device…
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/device.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/device.c [iso-8859-1] Fri Apr 9 20:31:53 2010
@@ -567,8 +567,12 @@
}
default:
DPRINT1("unhandled function %u\n", IoStack->MinorFunction);
+ /* pass the irp down the driver stack */
+ Status = KspForwardIrpSynchronous(DeviceObject, Irp);
+
+ Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_NOT_SUPPORTED;
+ return Status;
}
}
Modified: trunk/reactos/drivers/ksfilter/ks/filter.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/filter…
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/filter.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/filter.c [iso-8859-1] Fri Apr 9 20:31:53 2010
@@ -611,7 +611,7 @@
DataRange = (PKSDATARANGE)(MultipleItem + 1);
/* FIXME make sure its 64 bit aligned */
- ASSERT(((ULONG_PTR)DataRange & 0x3F) == 0);
+ ASSERT(((ULONG_PTR)DataRange & 0x7) == 0);
if (!This->Factory->FilterDescriptor || !This->PinDescriptorCount)
{
@@ -635,29 +635,63 @@
for(Index = 0; Index < MultipleItem->Count; Index++)
{
+ UNICODE_STRING MajorFormat, SubFormat, Specifier;
+ /* convert the guid to string */
+ RtlStringFromGUID(&DataRange->MajorFormat, &MajorFormat);
+ RtlStringFromGUID(&DataRange->SubFormat, &SubFormat);
+ RtlStringFromGUID(&DataRange->Specifier, &Specifier);
+
+ DPRINT("Index %lu MajorFormat %S SubFormat %S Specifier %S FormatSize %lu
SampleSize %lu Align %lu Flags %lx Reserved %lx DataLength %lu\n", Index,
MajorFormat.Buffer, SubFormat.Buffer, Specifier.Buffer,
+ DataRange->FormatSize, DataRange->SampleSize, DataRange->Alignment,
DataRange->Flags, DataRange->Reserved, DataLength);
+
+ /* FIXME implement KsPinDataIntersectionEx */
/* Call miniport's properitary handler */
- Status = This->PinDescriptorsEx[Pin->PinId].IntersectHandler(NULL, /*
context */
+ Status =
This->PinDescriptorsEx[Pin->PinId].IntersectHandler(&This->Filter,
Irp,
Pin,
DataRange,
-
(PKSDATAFORMAT)This->PinDescriptorsEx[Pin->PinId].PinDescriptor.DataRanges,
+
This->PinDescriptorsEx[Pin->PinId].PinDescriptor.DataRanges[0], /* HACK */
DataLength,
Data,
&Length);
- if (Status == STATUS_SUCCESS || Status == STATUS_BUFFER_OVERFLOW)
- {
+ if (Status == STATUS_SUCCESS || Status == STATUS_BUFFER_OVERFLOW || Status ==
STATUS_BUFFER_TOO_SMALL)
+ {
+ ASSERT(Length);
IoStatus->Information = Length;
+ if (Status != STATUS_SUCCESS)
+ Status = STATUS_MORE_ENTRIES;
break;
}
+
DataRange = UlongToPtr(PtrToUlong(DataRange) + DataRange->FormatSize);
/* FIXME make sure its 64 bit aligned */
- ASSERT(((ULONG_PTR)DataRange & 0x3F) == 0);
+ ASSERT(((ULONG_PTR)DataRange & 0x7) == 0);
}
IoStatus->Status = Status;
return Status;
}
+
+NTSTATUS
+NTAPI
+KspTopologyPropertyHandler(
+ IN PIRP Irp,
+ IN PKSIDENTIFIER Request,
+ IN OUT PVOID Data)
+{
+ IKsFilterImpl * This;
+
+ /* get filter implementation */
+ This = (IKsFilterImpl*)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
+
+ /* sanity check */
+ ASSERT(This);
+
+ return KsTopologyPropertyHandler(Irp, Request, Data, &This->Topology);
+
+}
+
NTSTATUS
NTAPI
@@ -672,6 +706,9 @@
/* get filter implementation */
This = (IKsFilterImpl*)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
+
+ /* sanity check */
+ ASSERT(This);
/* get current stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
@@ -686,7 +723,7 @@
case KSPROPERTY_PIN_COMMUNICATION:
case KSPROPERTY_PIN_CATEGORY:
case KSPROPERTY_PIN_NAME:
- case KSPROPERTY_PIN_PROPOSEDATAFORMAT:
+ case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
Status = KsPinPropertyHandler(Irp, Request, Data,
This->PinDescriptorCount, This->PinDescriptors);
break;
case KSPROPERTY_PIN_GLOBALCINSTANCES:
@@ -702,16 +739,11 @@
case KSPROPERTY_PIN_DATAINTERSECTION:
Status = KspHandleDataIntersection(Irp, &Irp->IoStatus, Request, Data,
IoStack->Parameters.DeviceIoControl.OutputBufferLength, This);
break;
- case KSPROPERTY_PIN_PHYSICALCONNECTION:
- case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
- UNIMPLEMENTED
- Status = STATUS_NOT_IMPLEMENTED;
- break;
default:
UNIMPLEMENTED
- Status = STATUS_UNSUCCESSFUL;
- }
- DPRINT("KspPinPropertyHandler Pins %lu Request->Id %lu Status %lx\n",
This->PinDescriptorCount, Request->Id, Status);
+ Status = STATUS_NOT_FOUND;
+ }
+ //DPRINT("KspPinPropertyHandler Pins %lu Request->Id %lu Status %lx\n",
This->PinDescriptorCount, Request->Id, Status);
return Status;
@@ -730,6 +762,7 @@
PKSFILTER FilterInstance;
UNICODE_STRING GuidString;
PKSPROPERTY Property;
+ ULONG SetCount = 0;
/* obtain filter from object header */
Status = IKsFilter_GetFilterFromIrp(Irp, &Filter);
@@ -742,47 +775,70 @@
/* current irp stack */
IoStack = IoGetCurrentIrpStackLocation(Irp);
- /* property was not handled */
+ /* get property from input buffer */
Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
+
+ /* sanity check */
+ ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >=
sizeof(KSIDENTIFIER));
+
+ /* get filter instance */
+ FilterInstance = Filter->lpVtbl->GetStruct(Filter);
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_METHOD)
+ {
+ const KSMETHOD_SET *MethodSet = NULL;
+ ULONG MethodItemSize = 0;
+
+ /* check if the driver supports method sets */
+ if (FilterInstance->Descriptor->AutomationTable &&
FilterInstance->Descriptor->AutomationTable->MethodSetsCount)
+ {
+ SetCount =
FilterInstance->Descriptor->AutomationTable->MethodSetsCount;
+ MethodSet =
FilterInstance->Descriptor->AutomationTable->MethodSets;
+ MethodItemSize =
FilterInstance->Descriptor->AutomationTable->MethodItemSize;
+ }
+
+ /* call method set handler */
+ Status = KspMethodHandlerWithAllocator(Irp, SetCount, MethodSet, NULL,
MethodItemSize);
+ }
+ else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY)
+ {
+ const KSPROPERTY_SET *PropertySet = NULL;
+ ULONG PropertyItemSize = 0;
+
+ /* check if the driver supports method sets */
+ if (FilterInstance->Descriptor->AutomationTable &&
FilterInstance->Descriptor->AutomationTable->PropertySetsCount)
+ {
+ SetCount =
FilterInstance->Descriptor->AutomationTable->PropertySetsCount;
+ PropertySet =
FilterInstance->Descriptor->AutomationTable->PropertySets;
+ PropertyItemSize =
FilterInstance->Descriptor->AutomationTable->PropertyItemSize;
+ }
+
+ /* needed for our property handlers */
+ KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (KSPROPERTY_ITEM*)This;
+
+ /* call property handler */
+ Status = KspPropertyHandler(Irp, SetCount, PropertySet, NULL, PropertyItemSize);
+ }
+ else
+ {
+ /* sanity check */
+ ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode ==
IOCTL_KS_ENABLE_EVENT ||
+ IoStack->Parameters.DeviceIoControl.IoControlCode ==
IOCTL_KS_DISABLE_EVENT);
+
+ Status = STATUS_NOT_FOUND;
UNIMPLEMENTED;
-
- /* release filter interface */
- Filter->lpVtbl->Release(Filter);
-
- /* complete and forget irp */
- Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_NOT_IMPLEMENTED;
- }
-
- /* call property handler supported by ks */
- KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (KSPROPERTY_ITEM*)This;
- Status = KspPropertyHandler(Irp, 2, FilterPropertySet, NULL,
sizeof(KSPROPERTY_ITEM));
-
- if (Status == STATUS_NOT_FOUND)
- {
- /* get filter instance */
- FilterInstance = Filter->lpVtbl->GetStruct(Filter);
-
- /* check if the driver supports property sets */
- if (FilterInstance->Descriptor->AutomationTable &&
FilterInstance->Descriptor->AutomationTable->PropertySetsCount)
- {
- /* call driver's filter property handler */
- Status = KspPropertyHandler(Irp,
-
FilterInstance->Descriptor->AutomationTable->PropertySetsCount,
-
FilterInstance->Descriptor->AutomationTable->PropertySets,
- NULL,
-
FilterInstance->Descriptor->AutomationTable->PropertyItemSize);
- }
- }
+ }
+
+ RtlStringFromGUID(&Property->Set, &GuidString);
+ DPRINT("IKsFilter_DispatchDeviceIoControl property Set |%S| Id %u Flags %x
Status %lx ResultLength %lu\n", GuidString.Buffer, Property->Id,
Property->Flags, Status, Irp->IoStatus.Information);
+ RtlFreeUnicodeString(&GuidString);
+
+ /* release filter */
+ Filter->lpVtbl->Release(Filter);
if (Status != STATUS_PENDING)
{
@@ -953,6 +1009,7 @@
const KSFILTER_DESCRIPTOR* FilterDescriptor)
{
NTSTATUS Status;
+ KSAUTOMATION_TABLE AutomationTable;
This->Filter.Descriptor = AllocateItem(NonPagedPool,
sizeof(KSFILTER_DESCRIPTOR));
if (!This->Filter.Descriptor)
@@ -968,6 +1025,17 @@
/* copy filter descriptor fields */
RtlMoveMemory((PVOID)This->Filter.Descriptor, FilterDescriptor,
sizeof(KSFILTER_DESCRIPTOR));
+
+ /* zero automation table */
+ RtlZeroMemory(&AutomationTable, sizeof(KSAUTOMATION_TABLE));
+
+ /* setup filter property sets */
+ AutomationTable.PropertyItemSize = sizeof(KSPROPERTY_ITEM);
+ AutomationTable.PropertySetsCount = 2;
+ AutomationTable.PropertySets = FilterPropertySet;
+
+ /* merge filter automation table */
+ Status =
KsMergeAutomationTables((PKSAUTOMATION_TABLE*)&This->Filter.Descriptor->AutomationTable,
(PKSAUTOMATION_TABLE)FilterDescriptor->AutomationTable, &AutomationTable,
This->Filter.Bag);
return Status;
}
@@ -1303,7 +1371,6 @@
This->lpVtbl = &vt_IKsFilter;
This->lpVtblKsControl = &vt_IKsControl;
- This->Filter.Descriptor = Factory->FilterDescriptor;
This->Factory = Factory;
This->FilterFactory = iface;
This->FileObject = IoStack->FileObject;
Modified: trunk/reactos/drivers/ksfilter/ks/irp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/irp.c?…
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/irp.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/irp.c [iso-8859-1] Fri Apr 9 20:31:53 2010
@@ -1720,9 +1720,11 @@
PLIST_ENTRY Entry;
PCREATE_ITEM_ENTRY CreateItemEntry;
+#ifndef MS_KSUSER
/* remove '\' slash */
Buffer++;
BufferSize -= sizeof(WCHAR);
+#endif
/* point to first entry */
Entry = ListHead->Flink;
Modified: trunk/reactos/drivers/ksfilter/ks/ksfunc.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/ksfunc…
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/ksfunc.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/ksfunc.h [iso-8859-1] Fri Apr 9 20:31:53 2010
@@ -156,3 +156,12 @@
IN PKSIDEVICE_HEADER DeviceHeader,
IN BOOLEAN NewState);
+NTSTATUS
+NTAPI
+KspMethodHandlerWithAllocator(
+ IN PIRP Irp,
+ IN ULONG MethodSetsCount,
+ IN const KSMETHOD_SET *MethodSet,
+ IN PFNKSALLOCATOR Allocator OPTIONAL,
+ IN ULONG MethodItemSize OPTIONAL);
+
Modified: trunk/reactos/drivers/ksfilter/ks/methods.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/method…
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/methods.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/methods.c [iso-8859-1] Fri Apr 9 20:31:53 2010
@@ -8,8 +8,186 @@
#include "priv.h"
+NTSTATUS
+FindMethodHandler(
+ IN PIO_STATUS_BLOCK IoStatus,
+ IN const KSMETHOD_SET* MethodSet,
+ IN ULONG MethodSetCount,
+ IN PKSMETHOD Method,
+ IN ULONG InputBufferLength,
+ IN ULONG OutputBufferLength,
+ OUT PVOID OutputBuffer,
+ OUT PFNKSHANDLER *MethodHandler,
+ OUT PKSMETHOD_SET * Set)
+{
+ ULONG Index, ItemIndex;
+
+ /* TODO */
+ ASSERT((Method->Flags & KSMETHOD_TYPE_SETSUPPORT) == 0);
+
+ for(Index = 0; Index < MethodSetCount; Index++)
+ {
+ ASSERT(MethodSet[Index].Set);
+
+ if (IsEqualGUIDAligned(&Method->Set, MethodSet[Index].Set))
+ {
+ for(ItemIndex = 0; ItemIndex < MethodSet[Index].MethodsCount;
ItemIndex++)
+ {
+ if (MethodSet[Index].MethodItem[ItemIndex].MethodId == Method->Id)
+ {
+ if (MethodSet[Index].MethodItem[ItemIndex].MinMethod >
InputBufferLength)
+ {
+ /* too small input buffer */
+ IoStatus->Information =
MethodSet[Index].MethodItem[ItemIndex].MinMethod;
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if (MethodSet[Index].MethodItem[ItemIndex].MinData >
OutputBufferLength)
+ {
+ /* too small output buffer */
+ IoStatus->Information =
MethodSet[Index].MethodItem[ItemIndex].MinData;
+ return STATUS_MORE_ENTRIES;
+ }
+ if (Method->Flags & KSMETHOD_TYPE_BASICSUPPORT)
+ {
+ PULONG Flags;
+ PKSPROPERTY_DESCRIPTION Description;
+
+ if (sizeof(ULONG) > OutputBufferLength)
+ {
+ /* too small buffer */
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* get output buffer */
+ Flags = (PULONG)OutputBuffer;
+
+ /* set flags flags */
+ *Flags = MethodSet[Index].MethodItem[ItemIndex].Flags;
+
+ IoStatus->Information = sizeof(ULONG);
+
+ if (OutputBufferLength >= sizeof(KSPROPERTY_DESCRIPTION))
+ {
+ /* get output buffer */
+ Description = (PKSPROPERTY_DESCRIPTION)OutputBuffer;
+
+ /* store result */
+ Description->DescriptionSize =
sizeof(KSPROPERTY_DESCRIPTION);
+ Description->PropTypeSet.Set = KSPROPTYPESETID_General;
+ Description->PropTypeSet.Id = 0;
+ Description->PropTypeSet.Flags = 0;
+ Description->MembersListCount = 0;
+ Description->Reserved = 0;
+
+ IoStatus->Information = sizeof(KSPROPERTY_DESCRIPTION);
+ }
+ return STATUS_SUCCESS;
+ }
+ *MethodHandler =
MethodSet[Index].MethodItem[ItemIndex].MethodHandler;
+ *Set = (PKSMETHOD_SET)&MethodSet[Index];
+ return STATUS_SUCCESS;
+ }
+ }
+ }
+ }
+ return STATUS_NOT_FOUND;
+}
+
+NTSTATUS
+NTAPI
+KspMethodHandlerWithAllocator(
+ IN PIRP Irp,
+ IN ULONG MethodSetsCount,
+ IN const KSMETHOD_SET *MethodSet,
+ IN PFNKSALLOCATOR Allocator OPTIONAL,
+ IN ULONG MethodItemSize OPTIONAL)
+{
+ PKSMETHOD Method;
+ PKSMETHOD_SET Set;
+ PIO_STACK_LOCATION IoStack;
+ NTSTATUS Status;
+ PFNKSHANDLER MethodHandler = NULL;
+ ULONG Index;
+ LPGUID Guid;
+
+ /* get current irp stack */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ /* check if inputbuffer at least holds KSMETHOD item */
+ if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSMETHOD))
+ {
+ /* invalid parameter */
+ Irp->IoStatus.Information = sizeof(KSPROPERTY);
+ return STATUS_INVALID_BUFFER_SIZE;
+ }
+
+ /* FIXME probe the input / output buffer if from user mode */
+
+ /* get input property request */
+ Method = (PKSMETHOD)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
+
+// DPRINT("KspMethodHandlerWithAllocator Irp %p PropertySetsCount %u PropertySet
%p Allocator %p PropertyItemSize %u ExpectedPropertyItemSize %u\n", Irp,
PropertySetsCount, PropertySet, Allocator, PropertyItemSize, sizeof(KSPROPERTY_ITEM));
+
+ /* sanity check */
+ ASSERT(MethodItemSize == 0 || MethodItemSize == sizeof(KSMETHOD_ITEM));
+
+ /* find the method handler */
+ Status = FindMethodHandler(&Irp->IoStatus, MethodSet, MethodSetsCount, Method,
IoStack->Parameters.DeviceIoControl.InputBufferLength,
IoStack->Parameters.DeviceIoControl.OutputBufferLength, Irp->UserBuffer,
&MethodHandler, &Set);
+
+ if (NT_SUCCESS(Status) && MethodHandler)
+ {
+ /* call method handler */
+ KSMETHOD_SET_IRP_STORAGE(Irp) = Set;
+ Status = MethodHandler(Irp, Method, Irp->UserBuffer);
+
+ if (Status == STATUS_BUFFER_TOO_SMALL)
+ {
+ /* output buffer is too small */
+ if (Allocator)
+ {
+ /* allocate the requested amount */
+ Status = Allocator(Irp, Irp->IoStatus.Information, FALSE);
+
+ /* check if the block was allocated */
+ if (!NT_SUCCESS(Status))
+ {
+ /* no memory */
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* re-call method handler */
+ Status = MethodHandler(Irp, Method, Irp->UserBuffer);
+ }
+ }
+ }
+ else if (IsEqualGUIDAligned(&Method->Set, &GUID_NULL) &&
Method->Id == 0 && Method->Flags == KSMETHOD_TYPE_SETSUPPORT)
+ {
+ // store output size
+ Irp->IoStatus.Information = sizeof(GUID) * MethodSetsCount;
+ if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GUID) *
MethodSetsCount)
+ {
+ // buffer too small
+ return STATUS_MORE_ENTRIES;
+ }
+
+ // get output buffer
+ Guid = (LPGUID)Irp->UserBuffer;
+
+ // copy property guids from property sets
+ for(Index = 0; Index < MethodSetsCount; Index++)
+ {
+ RtlMoveMemory(&Guid[Index], MethodSet[Index].Set, sizeof(GUID));
+ }
+ return STATUS_SUCCESS;
+ }
+
+ /* done */
+ return Status;
+}
+
/*
- @unimplemented
+ @implemented
*/
KSDDKAPI
NTSTATUS
@@ -19,12 +197,11 @@
IN ULONG MethodSetsCount,
IN PKSMETHOD_SET MethodSet)
{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
+ return KspMethodHandlerWithAllocator(Irp, MethodSetsCount, MethodSet, NULL, 0);
}
/*
- @unimplemented
+ @implemented
*/
KSDDKAPI
NTSTATUS
@@ -36,12 +213,39 @@
IN PFNKSALLOCATOR Allocator OPTIONAL,
IN ULONG MethodItemSize OPTIONAL)
{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
-}
+ return KspMethodHandlerWithAllocator(Irp, MethodSetsCount, MethodSet, Allocator,
MethodItemSize);
+}
+
+
+NTSTATUS
+FindFastMethodHandler(
+ IN ULONG FastIoCount,
+ IN const KSFASTMETHOD_ITEM * FastIoTable,
+ IN PKSMETHOD MethodId,
+ OUT PFNKSFASTHANDLER * FastPropertyHandler)
+{
+ ULONG Index;
+
+ /* iterate through all items */
+ for(Index = 0; Index < FastIoCount; Index++)
+ {
+ if (MethodId->Id == FastIoTable[Index].MethodId)
+ {
+ if (FastIoTable[Index].MethodSupported)
+ {
+ *FastPropertyHandler = FastIoTable[Index].MethodHandler;
+ return STATUS_SUCCESS;
+ }
+ }
+
+ }
+ /* no fast property handler found */
+ return STATUS_NOT_FOUND;
+}
+
/*
- @unimplemented
+ @implemented
*/
KSDDKAPI
BOOLEAN
@@ -56,6 +260,68 @@
IN ULONG MethodSetsCount,
IN const KSMETHOD_SET* MethodSet)
{
- UNIMPLEMENTED;
+ KSMETHOD MethodRequest;
+ KPROCESSOR_MODE Mode;
+ NTSTATUS Status = STATUS_SUCCESS;
+ ULONG Index;
+ PFNKSFASTHANDLER FastMethodHandler;
+
+ if (MethodLength < sizeof(KSPROPERTY))
+ {
+ /* invalid request */
+ return FALSE;
+ }
+
+ /* get previous mode */
+ Mode = ExGetPreviousMode();
+
+ if (Mode == KernelMode)
+ {
+ /* just copy it */
+ RtlMoveMemory(&MethodRequest, Method, sizeof(KSMETHOD));
+ }
+ else
+ {
+ /* need to probe the buffer */
+ _SEH2_TRY
+ {
+ ProbeForRead(Method, sizeof(KSPROPERTY), sizeof(UCHAR));
+ RtlMoveMemory(&MethodRequest, Method, sizeof(KSMETHOD));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Exception, get the error code */
+ Status = _SEH2_GetExceptionCode();
+ }_SEH2_END;
+
+ if (!NT_SUCCESS(Status))
+ return FALSE;
+ }
+
+ /* are there any property sets provided */
+ if (MethodSetsCount)
+ {
+ /* iterate through all property sets count */
+ Index = 0;
+ do
+ {
+ /* does the property id match */
+ if (IsEqualGUIDAligned(MethodSet[Index].Set, &MethodRequest.Set))
+ {
+ /* try to find a fast property handler */
+ Status = FindFastMethodHandler(MethodSet[Index].FastIoCount,
MethodSet[Index].FastIoTable, &MethodRequest, &FastMethodHandler);
+
+ if (NT_SUCCESS(Status))
+ {
+ /* call fast property handler */
+ ASSERT(MethodLength == sizeof(KSMETHOD)); /* FIXME check if property
length is bigger -> copy params */
+ ASSERT(Mode == KernelMode); /* FIXME need to probe usermode output
buffer */
+ return FastMethodHandler(FileObject, &MethodRequest,
sizeof(KSMETHOD), Data, DataLength, IoStatus);
+ }
+ }
+ /* move to next item */
+ Index++;
+ }while(Index < MethodSetsCount);
+ }
return FALSE;
}
Modified: trunk/reactos/drivers/ksfilter/ks/pin.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/pin.c?…
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/pin.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/pin.c [iso-8859-1] Fri Apr 9 20:31:53 2010
@@ -21,6 +21,7 @@
ULONG Offset;
ULONG Length;
KSSTREAM_POINTER StreamPointer;
+ KSPIN_LOCK Lock;
}KSISTREAM_POINTER, *PKSISTREAM_POINTER;
typedef struct
@@ -307,6 +308,7 @@
/* revert to old state */
This->Pin.ClientState = OldState;
This->Pin.DeviceState = OldState;
+ DPRINT("IKsPin_PinStatePropertyHandler failed to set state %lx
Result %lx\n", *NewState, Status);
DbgBreakPoint();
}
else
@@ -429,6 +431,7 @@
_InterlockedIncrement(&This->ref);
return STATUS_SUCCESS;
}
+DPRINT("IKsPin_fnQueryInterface\n");
DbgBreakPoint();
return STATUS_UNSUCCESSFUL;
}
@@ -674,6 +677,9 @@
IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl,
lpVtblReferenceClock);
+
+ DPRINT1("IKsReferenceClock_fnGetTime\n");
+
if (!This->ClockFileObject || !This->ClockTable.GetTime)
{
Result = 0;
@@ -694,6 +700,9 @@
LONGLONG Result;
IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl,
lpVtblReferenceClock);
+
+ DPRINT1("IKsReferenceClock_fnGetPhysicalTime\n");
+
if (!This->ClockFileObject || !This->ClockTable.GetPhysicalTime)
{
@@ -718,6 +727,8 @@
IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl,
lpVtblReferenceClock);
+ DPRINT1("IKsReferenceClock_fnGetCorrelatedTime\n");
+
if (!This->ClockFileObject || !This->ClockTable.GetCorrelatedTime)
{
Result = 0;
@@ -740,6 +751,8 @@
LONGLONG Result;
IKsPinImpl * This = (IKsPinImpl*)CONTAINING_RECORD(iface, IKsPinImpl,
lpVtblReferenceClock);
+
+ DPRINT1("IKsReferenceClock_fnGetCorrelatedPhysicalTime\n");
if (!This->ClockFileObject || !This->ClockTable.GetCorrelatedPhysicalTime)
{
@@ -1226,6 +1239,7 @@
}
InterlockedDecrement(&This->IrpCount);
+ KsDecrementCountedWorker(This->PinWorker);
/* get stream header */
if (StreamPointer->Irp->RequestorMode == UserMode)
@@ -1374,9 +1388,11 @@
IN PKSSTREAM_POINTER StreamPointer,
IN BOOLEAN Eject)
{
- UNIMPLEMENTED
+ PKSISTREAM_POINTER Pointer = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer,
KSISTREAM_POINTER, StreamPointer);
+
DPRINT("KsStreamPointerUnlock StreamPointer %pEject %lu\n", StreamPointer,
Eject);
- DbgBreakPoint();
+
+ Pointer->Irp = NULL;
}
/*
@@ -1687,8 +1703,12 @@
IKsPinImpl * This;
DPRINT("KsPinGetFirstCloneStreamPointer %p\n", Pin);
-DbgBreakPoint();
+
This = (IKsPinImpl*)CONTAINING_RECORD(Pin, IKsPinImpl, Pin);
+
+ if (!This->ClonedStreamPointer)
+ return NULL;
+
/* return first cloned stream pointer */
return &This->ClonedStreamPointer->StreamPointer;
}
@@ -1708,7 +1728,6 @@
DbgBreakPoint();
/* get stream pointer */
Pointer = (PKSISTREAM_POINTER)CONTAINING_RECORD(StreamPointer, KSISTREAM_POINTER,
StreamPointer);
-
/* is there a another cloned stream pointer */
if (!Pointer->Next)
Modified: trunk/reactos/drivers/ksfilter/ks/topology.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/topolo…
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/topology.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/topology.c [iso-8859-1] Fri Apr 9 20:31:53 2010
@@ -270,13 +270,3 @@
return Status;
}
-NTSTATUS
-NTAPI
-KspTopologyPropertyHandler(
- IN PIRP Irp,
- IN PKSIDENTIFIER Request,
- IN OUT PVOID Data)
-{
-
- return STATUS_NOT_IMPLEMENTED;
-}