2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/ksfilter/ks/clocks.c
5 * PURPOSE: KS Clocks functions
6 * PROGRAMMER: Johannes Anderwald
21 PFNKSSETTIMER SetTimer
;
22 PFNKSCANCELTIMER CancelTimer
;
23 PFNKSCORRELATEDTIME CorrelatedTime
;
28 }KSIDEFAULTCLOCK
, *PKSIDEFAULTCLOCK
;
33 PKSCLOCK_CREATE ClockCreate
;
34 PKSIDEFAULTCLOCK DefaultClock
;
35 PKSIOBJECT_HEADER ObjectHeader
;
36 }KSICLOCK
, *PKSICLOCK
;
38 NTSTATUS NTAPI
ClockPropertyTime(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
39 NTSTATUS NTAPI
ClockPropertyPhysicalTime(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
40 NTSTATUS NTAPI
ClockPropertyCorrelatedTime(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
41 NTSTATUS NTAPI
ClockPropertyCorrelatedPhysicalTime(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
42 NTSTATUS NTAPI
ClockPropertyResolution(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
43 NTSTATUS NTAPI
ClockPropertyState(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
44 NTSTATUS NTAPI
ClockPropertyFunctionTable(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
46 DEFINE_KSPROPERTY_CLOCKSET(ClockPropertyTable
, ClockPropertyTime
, ClockPropertyPhysicalTime
, ClockPropertyCorrelatedTime
, ClockPropertyCorrelatedPhysicalTime
, ClockPropertyResolution
, ClockPropertyState
, ClockPropertyFunctionTable
);
48 KSPROPERTY_SET ClockPropertySet
[] =
52 sizeof(ClockPropertyTable
) / sizeof(KSPROPERTY_ITEM
),
53 (const KSPROPERTY_ITEM
*)&ClockPropertyTable
,
62 IN PFILE_OBJECT FileObject
)
70 ClockGetCorrelatedTime(
71 IN PFILE_OBJECT FileObject
,
72 OUT PLONGLONG SystemTime
)
81 IN PFILE_OBJECT FileObject
)
89 ClockGetCorrelatedPhysicalTime(
90 IN PFILE_OBJECT FileObject
,
91 OUT PLONGLONG SystemTime
)
101 IN PKSIDENTIFIER Request
,
104 PLONGLONG Time
= (PLONGLONG
)Data
;
105 PIO_STACK_LOCATION IoStack
= IoGetCurrentIrpStackLocation(Irp
);
107 DPRINT("ClockPropertyTime\n");
109 *Time
= ClockGetTime(IoStack
->FileObject
);
111 Irp
->IoStatus
.Information
= sizeof(LONGLONG
);
112 return STATUS_SUCCESS
;
117 ClockPropertyPhysicalTime(
119 IN PKSIDENTIFIER Request
,
122 PLONGLONG Time
= (PLONGLONG
)Data
;
123 PIO_STACK_LOCATION IoStack
= IoGetCurrentIrpStackLocation(Irp
);
125 DPRINT("ClockPropertyPhysicalTime\n");
127 *Time
= ClockGetPhysicalTime(IoStack
->FileObject
);
129 Irp
->IoStatus
.Information
= sizeof(LONGLONG
);
130 return STATUS_SUCCESS
;
135 ClockPropertyCorrelatedTime(
137 IN PKSIDENTIFIER Request
,
140 PKSCORRELATED_TIME Time
= (PKSCORRELATED_TIME
)Data
;
141 PIO_STACK_LOCATION IoStack
= IoGetCurrentIrpStackLocation(Irp
);
143 DPRINT("ClockPropertyCorrelatedTime\n");
145 Time
->Time
= ClockGetCorrelatedTime(IoStack
->FileObject
, &Time
->SystemTime
);
147 Irp
->IoStatus
.Information
= sizeof(KSCORRELATED_TIME
);
148 return STATUS_SUCCESS
;
153 ClockPropertyCorrelatedPhysicalTime(
155 IN PKSIDENTIFIER Request
,
158 PKSCORRELATED_TIME Time
= (PKSCORRELATED_TIME
)Data
;
159 PIO_STACK_LOCATION IoStack
= IoGetCurrentIrpStackLocation(Irp
);
161 DPRINT("ClockPropertyCorrelatedPhysicalTime\n");
163 Time
->Time
= ClockGetCorrelatedPhysicalTime(IoStack
->FileObject
, &Time
->SystemTime
);
165 Irp
->IoStatus
.Information
= sizeof(KSCORRELATED_TIME
);
166 return STATUS_SUCCESS
;
171 ClockPropertyResolution(
173 IN PKSIDENTIFIER Request
,
177 PKSIOBJECT_HEADER ObjectHeader
;
178 PIO_STACK_LOCATION IoStack
;
179 PKSRESOLUTION Resolution
= (PKSRESOLUTION
)Data
;
181 DPRINT("ClockPropertyResolution\n");
183 /* get stack location */
184 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
186 /* get the object header */
187 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
190 ASSERT(ObjectHeader
);
192 /* locate ks pin implemention from KSPIN offset */
193 Clock
= (PKSICLOCK
)ObjectHeader
->ObjectType
;
195 Resolution
->Error
= Clock
->DefaultClock
->Error
;
196 Resolution
->Granularity
= Clock
->DefaultClock
->Granularity
;
198 Irp
->IoStatus
.Information
= sizeof(KSRESOLUTION
);
199 return STATUS_SUCCESS
;
206 IN PKSIDENTIFIER Request
,
210 PKSIOBJECT_HEADER ObjectHeader
;
211 PKSSTATE State
= (PKSSTATE
)Data
;
212 PIO_STACK_LOCATION IoStack
;
214 DPRINT("ClockPropertyState\n");
216 /* get stack location */
217 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
219 /* get the object header */
220 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
223 ASSERT(ObjectHeader
);
225 /* locate ks pin implemention from KSPIN offset */
226 Clock
= (PKSICLOCK
)ObjectHeader
->ObjectType
;
228 *State
= Clock
->DefaultClock
->State
;
229 Irp
->IoStatus
.Information
= sizeof(KSSTATE
);
231 return STATUS_SUCCESS
;
236 ClockPropertyFunctionTable(
238 IN PKSIDENTIFIER Request
,
241 PKSCLOCK_FUNCTIONTABLE Table
= (PKSCLOCK_FUNCTIONTABLE
)Data
;
243 DPRINT("ClockPropertyFunctionTable\n");
245 Table
->GetCorrelatedPhysicalTime
= ClockGetCorrelatedPhysicalTime
;
246 Table
->GetCorrelatedTime
= ClockGetCorrelatedTime
;
247 Table
->GetPhysicalTime
= ClockGetPhysicalTime
;
248 Table
->GetTime
= ClockGetTime
;
250 return STATUS_SUCCESS
;
257 KSDDKAPI NTSTATUS NTAPI
259 IN HANDLE ConnectionHandle
,
260 IN PKSCLOCK_CREATE ClockCreate
,
261 OUT PHANDLE ClockHandle
)
263 return KspCreateObjectType(ConnectionHandle
,
266 sizeof(KSCLOCK_CREATE
),
277 KsValidateClockCreateRequest(
279 OUT PKSCLOCK_CREATE
* OutClockCreate
)
281 PKSCLOCK_CREATE ClockCreate
;
285 /* minimum request size */
286 Size
= sizeof(KSCLOCK_CREATE
);
288 /* copy create request */
289 Status
= KspCopyCreateRequest(Irp
,
292 (PVOID
*)&ClockCreate
);
294 if (!NT_SUCCESS(Status
))
297 if (ClockCreate
->CreateFlags
!= 0)
299 /* flags must be zero */
300 FreeItem(ClockCreate
);
301 return STATUS_INVALID_PARAMETER
;
304 *OutClockCreate
= ClockCreate
;
305 return STATUS_SUCCESS
;
310 IKsClock_DispatchDeviceIoControl(
311 IN PDEVICE_OBJECT DeviceObject
,
314 PIO_STACK_LOCATION IoStack
;
315 UNICODE_STRING GuidString
;
316 PKSPROPERTY Property
;
319 DPRINT("IKsClock_DispatchDeviceIoControl\n");
321 /* get current io stack */
322 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
324 /* FIXME support events */
325 ASSERT(IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_PROPERTY
);
328 ASSERT(IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
>= sizeof(KSPROPERTY
));
330 /* call property handler */
331 Status
= KsPropertyHandler(Irp
, 1, ClockPropertySet
);
333 /* get property from input buffer */
334 Property
= (PKSPROPERTY
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
336 RtlStringFromGUID(&Property
->Set
, &GuidString
);
337 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
);
338 RtlFreeUnicodeString(&GuidString
);
341 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
342 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
344 return STATUS_SUCCESS
;
349 IKsClock_DispatchClose(
350 IN PDEVICE_OBJECT DeviceObject
,
355 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
356 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
358 return STATUS_SUCCESS
;
361 static KSDISPATCH_TABLE DispatchTable
=
363 IKsClock_DispatchDeviceIoControl
,
364 KsDispatchInvalidDeviceRequest
,
365 KsDispatchInvalidDeviceRequest
,
366 KsDispatchInvalidDeviceRequest
,
367 IKsClock_DispatchClose
,
368 KsDispatchQuerySecurity
,
369 KsDispatchSetSecurity
,
370 KsDispatchFastIoDeviceControlFailure
,
371 KsDispatchFastReadFailure
,
372 KsDispatchFastReadFailure
,
381 KsCreateDefaultClock(
383 IN PKSDEFAULTCLOCK DefaultClock
)
386 PKSCLOCK_CREATE ClockCreate
;
389 Status
= KsValidateClockCreateRequest(Irp
, &ClockCreate
);
390 if (!NT_SUCCESS(Status
))
393 /* let's allocate the clock struct */
394 Clock
= AllocateItem(NonPagedPool
, sizeof(KSICLOCK
));
396 return STATUS_INSUFFICIENT_RESOURCES
;
398 /* now allocate the object header */
399 Status
= KsAllocateObjectHeader((PVOID
*)&Clock
->ObjectHeader
, 0, NULL
, Irp
, &DispatchTable
);
402 if (!NT_SUCCESS(Status
))
409 /* initialize clock */
411 Clock
->ObjectHeader
->ObjectType
= (PVOID
)Clock
;
413 Clock
->ClockCreate
= ClockCreate
;
414 Clock
->DefaultClock
= (PKSIDEFAULTCLOCK
)DefaultClock
;
416 /* increment reference count */
417 InterlockedIncrement(&Clock
->DefaultClock
->ReferenceCount
);
428 KsAllocateDefaultClock(
429 OUT PKSDEFAULTCLOCK
* DefaultClock
)
431 return KsAllocateDefaultClockEx(DefaultClock
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
440 KsAllocateDefaultClockEx(
441 OUT PKSDEFAULTCLOCK
* DefaultClock
,
442 IN PVOID Context OPTIONAL
,
443 IN PFNKSSETTIMER SetTimer OPTIONAL
,
444 IN PFNKSCANCELTIMER CancelTimer OPTIONAL
,
445 IN PFNKSCORRELATEDTIME CorrelatedTime OPTIONAL
,
446 IN
const KSRESOLUTION
* Resolution OPTIONAL
,
449 PKSIDEFAULTCLOCK Clock
;
452 return STATUS_INVALID_PARAMETER_1
;
454 /* allocate default clock */
455 Clock
= AllocateItem(NonPagedPool
, sizeof(KSIDEFAULTCLOCK
));
457 return STATUS_INSUFFICIENT_RESOURCES
;
459 /* initialize default clock */
460 KeInitializeSpinLock(&Clock
->TimeLock
);
461 KeInitializeTimer(&Clock
->Timer
);
462 Clock
->ReferenceCount
= 1;
463 Clock
->Context
= Context
;
464 Clock
->SetTimer
= SetTimer
;
465 Clock
->CancelTimer
= CancelTimer
;
466 Clock
->CorrelatedTime
= CorrelatedTime
;
467 Clock
->Flags
= Flags
;
473 Clock
->Error
= Resolution
->Error
;
478 Clock
->Granularity
= Resolution
->Granularity
;
482 *DefaultClock
= (PKSDEFAULTCLOCK
)Clock
;
483 return STATUS_SUCCESS
;
493 IN PKSDEFAULTCLOCK DefaultClock
)
495 PKSIDEFAULTCLOCK Clock
= (PKSIDEFAULTCLOCK
)DefaultClock
;
497 InterlockedDecrement(&Clock
->ReferenceCount
);
499 if (Clock
->ReferenceCount
== 0)
501 /* free default clock */
512 KsGetDefaultClockState(
513 IN PKSDEFAULTCLOCK DefaultClock
)
515 PKSIDEFAULTCLOCK Clock
= (PKSIDEFAULTCLOCK
)DefaultClock
;
525 KsSetDefaultClockState(
526 IN PKSDEFAULTCLOCK DefaultClock
,
529 PKSIDEFAULTCLOCK Clock
= (PKSIDEFAULTCLOCK
)DefaultClock
;
531 if (State
!= Clock
->State
)
533 /* FIXME set time etc */
534 Clock
->State
= State
;
545 KsGetDefaultClockTime(
546 IN PKSDEFAULTCLOCK DefaultClock
)
549 PKSIDEFAULTCLOCK Clock
= (PKSIDEFAULTCLOCK
)DefaultClock
;
551 Time
= ExInterlockedCompareExchange64(&Clock
->Time
, &Time
, &Time
, &Clock
->TimeLock
);
562 KsSetDefaultClockTime(
563 IN PKSDEFAULTCLOCK DefaultClock
,
566 PKSIDEFAULTCLOCK Clock
= (PKSIDEFAULTCLOCK
)DefaultClock
;
568 /* set the time safely */
569 ExInterlockedCompareExchange64(&Clock
->Time
, &Time
, &Clock
->Time
, &Clock
->TimeLock
);