[KS]
[reactos.git] / reactos / drivers / ksfilter / ks / clocks.c
index b117b73..05064be 100644 (file)
@@ -21,20 +21,235 @@ typedef struct
     PFNKSSETTIMER SetTimer;
     PFNKSCANCELTIMER CancelTimer;
     PFNKSCORRELATEDTIME CorrelatedTime;
-    KSRESOLUTION* Resolution;
+    LONGLONG Granularity;
+    LONGLONG Error;
     ULONG Flags;
 
 }KSIDEFAULTCLOCK, *PKSIDEFAULTCLOCK;
 
 typedef struct
 {
-    IKsClock *lpVtbl;
     LONG ref;
     PKSCLOCK_CREATE ClockCreate;
     PKSIDEFAULTCLOCK DefaultClock;
     PKSIOBJECT_HEADER ObjectHeader;
 }KSICLOCK, *PKSICLOCK;
 
+NTSTATUS NTAPI ClockPropertyTime(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI ClockPropertyPhysicalTime(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI ClockPropertyCorrelatedTime(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI ClockPropertyCorrelatedPhysicalTime(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI ClockPropertyResolution(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI ClockPropertyState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+NTSTATUS NTAPI ClockPropertyFunctionTable(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
+
+DEFINE_KSPROPERTY_CLOCKSET(ClockPropertyTable, ClockPropertyTime, ClockPropertyPhysicalTime, ClockPropertyCorrelatedTime, ClockPropertyCorrelatedPhysicalTime, ClockPropertyResolution, ClockPropertyState, ClockPropertyFunctionTable);
+
+KSPROPERTY_SET ClockPropertySet[] =
+{
+    {
+        &KSPROPSETID_Clock,
+        sizeof(ClockPropertyTable) / sizeof(KSPROPERTY_ITEM),
+        (const KSPROPERTY_ITEM*)&ClockPropertyTable,
+        0,
+        NULL
+    }
+};
+
+LONGLONG
+FASTCALL
+ClockGetPhysicalTime(
+    IN PFILE_OBJECT FileObject)
+{
+    UNIMPLEMENTED
+    return 0;
+}
+
+LONGLONG
+FASTCALL
+ClockGetCorrelatedTime(
+    IN PFILE_OBJECT FileObject,
+    OUT PLONGLONG SystemTime)
+{
+    UNIMPLEMENTED
+    return 0;
+}
+
+LONGLONG
+FASTCALL
+ClockGetTime(
+    IN PFILE_OBJECT FileObject)
+{
+    UNIMPLEMENTED
+    return 0;
+}
+
+LONGLONG
+FASTCALL
+ClockGetCorrelatedPhysicalTime(
+    IN PFILE_OBJECT FileObject,
+    OUT PLONGLONG SystemTime)
+{
+    UNIMPLEMENTED
+    return 0;
+}
+
+NTSTATUS
+NTAPI
+ClockPropertyTime(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PLONGLONG Time = (PLONGLONG)Data;
+    PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    DPRINT("ClockPropertyTime\n");
+
+    *Time = ClockGetTime(IoStack->FileObject);
+
+    Irp->IoStatus.Information = sizeof(LONGLONG);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+ClockPropertyPhysicalTime(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PLONGLONG Time = (PLONGLONG)Data;
+    PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    DPRINT("ClockPropertyPhysicalTime\n");
+
+    *Time = ClockGetPhysicalTime(IoStack->FileObject);
+
+    Irp->IoStatus.Information = sizeof(LONGLONG);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+ClockPropertyCorrelatedTime(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PKSCORRELATED_TIME Time = (PKSCORRELATED_TIME)Data;
+    PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    DPRINT("ClockPropertyCorrelatedTime\n");
+
+    Time->Time = ClockGetCorrelatedTime(IoStack->FileObject, &Time->SystemTime);
+
+    Irp->IoStatus.Information = sizeof(KSCORRELATED_TIME);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+ClockPropertyCorrelatedPhysicalTime(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PKSCORRELATED_TIME Time = (PKSCORRELATED_TIME)Data;
+    PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    DPRINT("ClockPropertyCorrelatedPhysicalTime\n");
+
+    Time->Time = ClockGetCorrelatedPhysicalTime(IoStack->FileObject, &Time->SystemTime);
+
+    Irp->IoStatus.Information = sizeof(KSCORRELATED_TIME);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+ClockPropertyResolution(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PKSICLOCK Clock;
+    PKSIOBJECT_HEADER ObjectHeader;
+    PIO_STACK_LOCATION IoStack;
+    PKSRESOLUTION Resolution = (PKSRESOLUTION)Data;
+
+    DPRINT("ClockPropertyResolution\n");
+
+    /* get stack location */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    /* get the object header */
+    ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
+
+    /* sanity check */
+    ASSERT(ObjectHeader);
+
+    /* locate ks pin implemention from KSPIN offset */
+    Clock = (PKSICLOCK)ObjectHeader->ObjectType;
+
+    Resolution->Error = Clock->DefaultClock->Error;
+    Resolution->Granularity = Clock->DefaultClock->Granularity;
+
+    Irp->IoStatus.Information = sizeof(KSRESOLUTION);
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+ClockPropertyState(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PKSICLOCK Clock;
+    PKSIOBJECT_HEADER ObjectHeader;
+    PKSSTATE State = (PKSSTATE)Data;
+    PIO_STACK_LOCATION IoStack;
+
+    DPRINT("ClockPropertyState\n");
+
+    /* get stack location */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    /* get the object header */
+    ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
+
+    /* sanity check */
+    ASSERT(ObjectHeader);
+
+    /* locate ks pin implemention from KSPIN offset */
+    Clock = (PKSICLOCK)ObjectHeader->ObjectType;
+
+    *State = Clock->DefaultClock->State;
+    Irp->IoStatus.Information = sizeof(KSSTATE);
+
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+ClockPropertyFunctionTable(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER Request,
+    IN OUT PVOID Data)
+{
+    PKSCLOCK_FUNCTIONTABLE Table = (PKSCLOCK_FUNCTIONTABLE)Data;
+
+    DPRINT("ClockPropertyFunctionTable\n");
+
+    Table->GetCorrelatedPhysicalTime = ClockGetCorrelatedPhysicalTime;
+    Table->GetCorrelatedTime = ClockGetCorrelatedTime;
+    Table->GetPhysicalTime = ClockGetPhysicalTime;
+    Table->GetTime = ClockGetTime;
+
+    return STATUS_SUCCESS;
+}
+
 
 /*
     @implemented
@@ -46,7 +261,7 @@ KsCreateClock(
     OUT PHANDLE ClockHandle)
 {
     return KspCreateObjectType(ConnectionHandle,
-                               L"{53172480-4791-11D0-A5D6-28DB04C10000}", /* KSName_Clock */
+                               KSSTRING_Clock,
                                ClockCreate,
                                sizeof(KSCLOCK_CREATE),
                                GENERIC_READ,
@@ -54,17 +269,40 @@ KsCreateClock(
 }
 
 /*
-    @unimplemented
+    @implemented
 */
 KSDDKAPI
 NTSTATUS
 NTAPI
 KsValidateClockCreateRequest(
     IN  PIRP Irp,
-    OUT PKSCLOCK_CREATE* ClockCreate)
+    OUT PKSCLOCK_CREATE* OutClockCreate)
 {
-    UNIMPLEMENTED;
-    return STATUS_UNSUCCESSFUL;
+    PKSCLOCK_CREATE ClockCreate;
+    NTSTATUS Status;
+    ULONG Size;
+
+    /* minimum request size */
+    Size = sizeof(KSCLOCK_CREATE);
+
+    /* copy create request */
+    Status = KspCopyCreateRequest(Irp, 
+                                  KSSTRING_Clock,
+                                  &Size,
+                                  (PVOID*)&ClockCreate);
+
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    if (ClockCreate->CreateFlags != 0)
+    {
+        /* flags must be zero */
+        FreeItem(ClockCreate);
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    *OutClockCreate = ClockCreate;
+    return STATUS_SUCCESS;
 }
 
 NTSTATUS
@@ -73,12 +311,37 @@ IKsClock_DispatchDeviceIoControl(
     IN PDEVICE_OBJECT DeviceObject,
     IN  PIRP Irp)
 {
-    UNIMPLEMENTED
+    PIO_STACK_LOCATION IoStack;
+    UNICODE_STRING GuidString;
+    PKSPROPERTY Property;
+    NTSTATUS Status;
+
+    DPRINT("IKsClock_DispatchDeviceIoControl\n");
+
+    /* get current io stack */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
 
-    Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+    /* FIXME support events */
+    ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY);
+
+    /* sanity check */
+    ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSPROPERTY));
+
+    /* call property handler */
+    Status = KsPropertyHandler(Irp, 1, ClockPropertySet);
+
+    /* get property from input buffer */
+    Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
+
+    RtlStringFromGUID(&Property->Set, &GuidString);
+    DPRINT("IKsClock_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);
+
+
+    Irp->IoStatus.Status = STATUS_SUCCESS;
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
-    return STATUS_NOT_IMPLEMENTED;
+    return STATUS_SUCCESS;
 }
 
 NTSTATUS
@@ -89,14 +352,12 @@ IKsClock_DispatchClose(
 {
     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 =
 {
     IKsClock_DispatchDeviceIoControl,
@@ -124,7 +385,6 @@ KsCreateDefaultClock(
     NTSTATUS Status;
     PKSCLOCK_CREATE ClockCreate;
     PKSICLOCK Clock;
-    PKSOBJECT_CREATE_ITEM CreateItem;
 
     Status = KsValidateClockCreateRequest(Irp, &ClockCreate);
     if (!NT_SUCCESS(Status))
@@ -148,7 +408,7 @@ KsCreateDefaultClock(
 
     /* initialize clock */
     /* FIXME IKsClock */
-    Clock->ObjectHeader->Unknown = (PUNKNOWN)&Clock->lpVtbl;
+    Clock->ObjectHeader->ObjectType = (PVOID)Clock;
     Clock->ref = 1;
     Clock->ClockCreate = ClockCreate;
     Clock->DefaultClock = (PKSIDEFAULTCLOCK)DefaultClock;
@@ -156,16 +416,6 @@ KsCreateDefaultClock(
     /* increment reference count */
     InterlockedIncrement(&Clock->DefaultClock->ReferenceCount);
 
-    /* get create item */
-    CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
-
-    if (CreateItem)
-    {
-        /* store create item */
-        Clock->ObjectHeader->CreateItem = CreateItem;
-        Clock->ObjectHeader->ItemCount = 1;
-    }
-
     return Status;
 }
 
@@ -214,9 +464,21 @@ KsAllocateDefaultClockEx(
     Clock->SetTimer = SetTimer;
     Clock->CancelTimer = CancelTimer;
     Clock->CorrelatedTime = CorrelatedTime;
-    Clock->Resolution = (PKSRESOLUTION)Resolution;
     Clock->Flags = Flags;
 
+    if (Resolution)
+    {
+        if (SetTimer)
+        {
+            Clock->Error = Resolution->Error;
+        }
+
+        if (CorrelatedTime)
+        {
+            Clock->Granularity = Resolution->Granularity;
+        }
+    }
+
     *DefaultClock = (PKSDEFAULTCLOCK)Clock;
     return STATUS_SUCCESS;
 }