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
23 PFNKSSETTIMER SetTimer
;
24 PFNKSCANCELTIMER CancelTimer
;
25 PFNKSCORRELATEDTIME CorrelatedTime
;
30 }KSIDEFAULTCLOCK
, *PKSIDEFAULTCLOCK
;
35 PKSCLOCK_CREATE ClockCreate
;
36 PKSIDEFAULTCLOCK DefaultClock
;
37 PKSIOBJECT_HEADER ObjectHeader
;
38 }KSICLOCK
, *PKSICLOCK
;
40 NTSTATUS NTAPI
ClockPropertyTime(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
41 NTSTATUS NTAPI
ClockPropertyPhysicalTime(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
42 NTSTATUS NTAPI
ClockPropertyCorrelatedTime(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
43 NTSTATUS NTAPI
ClockPropertyCorrelatedPhysicalTime(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
44 NTSTATUS NTAPI
ClockPropertyResolution(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
45 NTSTATUS NTAPI
ClockPropertyState(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
46 NTSTATUS NTAPI
ClockPropertyFunctionTable(IN PIRP Irp
, IN PKSIDENTIFIER Request
, IN OUT PVOID Data
);
48 DEFINE_KSPROPERTY_CLOCKSET(ClockPropertyTable
, ClockPropertyTime
, ClockPropertyPhysicalTime
, ClockPropertyCorrelatedTime
, ClockPropertyCorrelatedPhysicalTime
, ClockPropertyResolution
, ClockPropertyState
, ClockPropertyFunctionTable
);
50 KSPROPERTY_SET ClockPropertySet
[] =
54 sizeof(ClockPropertyTable
) / sizeof(KSPROPERTY_ITEM
),
55 (const KSPROPERTY_ITEM
*)&ClockPropertyTable
,
64 IN PFILE_OBJECT FileObject
)
72 ClockGetCorrelatedTime(
73 IN PFILE_OBJECT FileObject
,
74 OUT PLONGLONG SystemTime
)
83 IN PFILE_OBJECT FileObject
)
91 ClockGetCorrelatedPhysicalTime(
92 IN PFILE_OBJECT FileObject
,
93 OUT PLONGLONG SystemTime
)
103 IN PKSIDENTIFIER Request
,
106 PLONGLONG Time
= (PLONGLONG
)Data
;
107 PIO_STACK_LOCATION IoStack
= IoGetCurrentIrpStackLocation(Irp
);
109 DPRINT("ClockPropertyTime\n");
111 *Time
= ClockGetTime(IoStack
->FileObject
);
113 Irp
->IoStatus
.Information
= sizeof(LONGLONG
);
114 return STATUS_SUCCESS
;
119 ClockPropertyPhysicalTime(
121 IN PKSIDENTIFIER Request
,
124 PLONGLONG Time
= (PLONGLONG
)Data
;
125 PIO_STACK_LOCATION IoStack
= IoGetCurrentIrpStackLocation(Irp
);
127 DPRINT("ClockPropertyPhysicalTime\n");
129 *Time
= ClockGetPhysicalTime(IoStack
->FileObject
);
131 Irp
->IoStatus
.Information
= sizeof(LONGLONG
);
132 return STATUS_SUCCESS
;
137 ClockPropertyCorrelatedTime(
139 IN PKSIDENTIFIER Request
,
142 PKSCORRELATED_TIME Time
= (PKSCORRELATED_TIME
)Data
;
143 PIO_STACK_LOCATION IoStack
= IoGetCurrentIrpStackLocation(Irp
);
145 DPRINT("ClockPropertyCorrelatedTime\n");
147 Time
->Time
= ClockGetCorrelatedTime(IoStack
->FileObject
, &Time
->SystemTime
);
149 Irp
->IoStatus
.Information
= sizeof(KSCORRELATED_TIME
);
150 return STATUS_SUCCESS
;
155 ClockPropertyCorrelatedPhysicalTime(
157 IN PKSIDENTIFIER Request
,
160 PKSCORRELATED_TIME Time
= (PKSCORRELATED_TIME
)Data
;
161 PIO_STACK_LOCATION IoStack
= IoGetCurrentIrpStackLocation(Irp
);
163 DPRINT("ClockPropertyCorrelatedPhysicalTime\n");
165 Time
->Time
= ClockGetCorrelatedPhysicalTime(IoStack
->FileObject
, &Time
->SystemTime
);
167 Irp
->IoStatus
.Information
= sizeof(KSCORRELATED_TIME
);
168 return STATUS_SUCCESS
;
173 ClockPropertyResolution(
175 IN PKSIDENTIFIER Request
,
179 PKSIOBJECT_HEADER ObjectHeader
;
180 PIO_STACK_LOCATION IoStack
;
181 PKSRESOLUTION Resolution
= (PKSRESOLUTION
)Data
;
183 DPRINT("ClockPropertyResolution\n");
185 /* get stack location */
186 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
188 /* get the object header */
189 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
192 ASSERT(ObjectHeader
);
194 /* locate ks pin implemention from KSPIN offset */
195 Clock
= (PKSICLOCK
)ObjectHeader
->ObjectType
;
197 Resolution
->Error
= Clock
->DefaultClock
->Error
;
198 Resolution
->Granularity
= Clock
->DefaultClock
->Granularity
;
200 Irp
->IoStatus
.Information
= sizeof(KSRESOLUTION
);
201 return STATUS_SUCCESS
;
208 IN PKSIDENTIFIER Request
,
212 PKSIOBJECT_HEADER ObjectHeader
;
213 PKSSTATE State
= (PKSSTATE
)Data
;
214 PIO_STACK_LOCATION IoStack
;
216 DPRINT("ClockPropertyState\n");
218 /* get stack location */
219 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
221 /* get the object header */
222 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
225 ASSERT(ObjectHeader
);
227 /* locate ks pin implemention from KSPIN offset */
228 Clock
= (PKSICLOCK
)ObjectHeader
->ObjectType
;
230 *State
= Clock
->DefaultClock
->State
;
231 Irp
->IoStatus
.Information
= sizeof(KSSTATE
);
233 return STATUS_SUCCESS
;
238 ClockPropertyFunctionTable(
240 IN PKSIDENTIFIER Request
,
243 PKSCLOCK_FUNCTIONTABLE Table
= (PKSCLOCK_FUNCTIONTABLE
)Data
;
245 DPRINT("ClockPropertyFunctionTable\n");
247 Table
->GetCorrelatedPhysicalTime
= ClockGetCorrelatedPhysicalTime
;
248 Table
->GetCorrelatedTime
= ClockGetCorrelatedTime
;
249 Table
->GetPhysicalTime
= ClockGetPhysicalTime
;
250 Table
->GetTime
= ClockGetTime
;
252 return STATUS_SUCCESS
;
259 KSDDKAPI NTSTATUS NTAPI
261 IN HANDLE ConnectionHandle
,
262 IN PKSCLOCK_CREATE ClockCreate
,
263 OUT PHANDLE ClockHandle
)
265 return KspCreateObjectType(ConnectionHandle
,
268 sizeof(KSCLOCK_CREATE
),
279 KsValidateClockCreateRequest(
281 OUT PKSCLOCK_CREATE
* OutClockCreate
)
283 PKSCLOCK_CREATE ClockCreate
;
287 /* minimum request size */
288 Size
= sizeof(KSCLOCK_CREATE
);
290 /* copy create request */
291 Status
= KspCopyCreateRequest(Irp
,
294 (PVOID
*)&ClockCreate
);
296 if (!NT_SUCCESS(Status
))
299 if (ClockCreate
->CreateFlags
!= 0)
301 /* flags must be zero */
302 FreeItem(ClockCreate
);
303 return STATUS_INVALID_PARAMETER
;
306 *OutClockCreate
= ClockCreate
;
307 return STATUS_SUCCESS
;
312 IKsClock_DispatchDeviceIoControl(
313 IN PDEVICE_OBJECT DeviceObject
,
316 PIO_STACK_LOCATION IoStack
;
317 UNICODE_STRING GuidString
;
318 PKSPROPERTY Property
;
321 DPRINT("IKsClock_DispatchDeviceIoControl\n");
323 /* get current io stack */
324 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
326 /* FIXME support events */
327 ASSERT(IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_PROPERTY
);
330 ASSERT(IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
>= sizeof(KSPROPERTY
));
332 /* call property handler */
333 Status
= KsPropertyHandler(Irp
, 1, ClockPropertySet
);
335 /* get property from input buffer */
336 Property
= (PKSPROPERTY
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
338 RtlStringFromGUID(&Property
->Set
, &GuidString
);
339 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
);
340 RtlFreeUnicodeString(&GuidString
);
343 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
344 CompleteRequest(Irp
, IO_NO_INCREMENT
);
346 return STATUS_SUCCESS
;
351 IKsClock_DispatchClose(
352 IN PDEVICE_OBJECT DeviceObject
,
357 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
358 CompleteRequest(Irp
, IO_NO_INCREMENT
);
360 return STATUS_SUCCESS
;
363 static KSDISPATCH_TABLE DispatchTable
=
365 IKsClock_DispatchDeviceIoControl
,
366 KsDispatchInvalidDeviceRequest
,
367 KsDispatchInvalidDeviceRequest
,
368 KsDispatchInvalidDeviceRequest
,
369 IKsClock_DispatchClose
,
370 KsDispatchQuerySecurity
,
371 KsDispatchSetSecurity
,
372 KsDispatchFastIoDeviceControlFailure
,
373 KsDispatchFastReadFailure
,
374 KsDispatchFastReadFailure
,
383 KsCreateDefaultClock(
385 IN PKSDEFAULTCLOCK DefaultClock
)
388 PKSCLOCK_CREATE ClockCreate
;
391 Status
= KsValidateClockCreateRequest(Irp
, &ClockCreate
);
392 if (!NT_SUCCESS(Status
))
395 /* let's allocate the clock struct */
396 Clock
= AllocateItem(NonPagedPool
, sizeof(KSICLOCK
));
398 return STATUS_INSUFFICIENT_RESOURCES
;
400 /* now allocate the object header */
401 Status
= KsAllocateObjectHeader((PVOID
*)&Clock
->ObjectHeader
, 0, NULL
, Irp
, &DispatchTable
);
404 if (!NT_SUCCESS(Status
))
411 /* initialize clock */
413 Clock
->ObjectHeader
->ObjectType
= (PVOID
)Clock
;
415 Clock
->ClockCreate
= ClockCreate
;
416 Clock
->DefaultClock
= (PKSIDEFAULTCLOCK
)DefaultClock
;
418 /* increment reference count */
419 InterlockedIncrement(&Clock
->DefaultClock
->ReferenceCount
);
430 KsAllocateDefaultClock(
431 OUT PKSDEFAULTCLOCK
* DefaultClock
)
433 return KsAllocateDefaultClockEx(DefaultClock
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
442 KsAllocateDefaultClockEx(
443 OUT PKSDEFAULTCLOCK
* DefaultClock
,
444 IN PVOID Context OPTIONAL
,
445 IN PFNKSSETTIMER SetTimer OPTIONAL
,
446 IN PFNKSCANCELTIMER CancelTimer OPTIONAL
,
447 IN PFNKSCORRELATEDTIME CorrelatedTime OPTIONAL
,
448 IN
const KSRESOLUTION
* Resolution OPTIONAL
,
451 PKSIDEFAULTCLOCK Clock
;
454 return STATUS_INVALID_PARAMETER_1
;
456 /* allocate default clock */
457 Clock
= AllocateItem(NonPagedPool
, sizeof(KSIDEFAULTCLOCK
));
459 return STATUS_INSUFFICIENT_RESOURCES
;
461 /* initialize default clock */
462 KeInitializeSpinLock(&Clock
->TimeLock
);
463 KeInitializeTimer(&Clock
->Timer
);
464 Clock
->ReferenceCount
= 1;
465 Clock
->Context
= Context
;
466 Clock
->SetTimer
= SetTimer
;
467 Clock
->CancelTimer
= CancelTimer
;
468 Clock
->CorrelatedTime
= CorrelatedTime
;
469 Clock
->Flags
= Flags
;
475 Clock
->Error
= Resolution
->Error
;
480 Clock
->Granularity
= Resolution
->Granularity
;
484 *DefaultClock
= (PKSDEFAULTCLOCK
)Clock
;
485 return STATUS_SUCCESS
;
495 IN PKSDEFAULTCLOCK DefaultClock
)
497 PKSIDEFAULTCLOCK Clock
= (PKSIDEFAULTCLOCK
)DefaultClock
;
499 InterlockedDecrement(&Clock
->ReferenceCount
);
501 if (Clock
->ReferenceCount
== 0)
503 /* free default clock */
514 KsGetDefaultClockState(
515 IN PKSDEFAULTCLOCK DefaultClock
)
517 PKSIDEFAULTCLOCK Clock
= (PKSIDEFAULTCLOCK
)DefaultClock
;
527 KsSetDefaultClockState(
528 IN PKSDEFAULTCLOCK DefaultClock
,
531 PKSIDEFAULTCLOCK Clock
= (PKSIDEFAULTCLOCK
)DefaultClock
;
533 if (State
!= Clock
->State
)
535 /* FIXME set time etc */
536 Clock
->State
= State
;
547 KsGetDefaultClockTime(
548 IN PKSDEFAULTCLOCK DefaultClock
)
551 PKSIDEFAULTCLOCK Clock
= (PKSIDEFAULTCLOCK
)DefaultClock
;
553 Time
= ExInterlockedCompareExchange64(&Clock
->Time
, &Time
, &Time
, &Clock
->TimeLock
);
564 KsSetDefaultClockTime(
565 IN PKSDEFAULTCLOCK DefaultClock
,
568 PKSIDEFAULTCLOCK Clock
= (PKSIDEFAULTCLOCK
)DefaultClock
;
570 /* set the time safely */
571 ExInterlockedCompareExchange64(&Clock
->Time
, &Time
, &Clock
->Time
, &Clock
->TimeLock
);