HalpTimerRegister
NTSTATUS __stdcall HalpTimerRegister(TIMER_INITIALIZATION_BLOCK *NewTimer, UNICODE_STRING *ResourceUnicodeId){
NTSTATUS v2;
UNICODE_STRING *p_DestinationString;
ULONG Capabilities;
WCHAR v6;
ULONG InternalDataSize;
unsigned int MaximumProcessorCount;
PSTR MemoryInternal;
__int64 v10;
UNICODE_STRING *v11;
unsigned __int64 v12;
unsigned __int64 v13;
__int128 v14;
unsigned int i;
__int64 *v16;
struct _UNICODE_STRING DestinationString;
WCHAR SourceString[80];
v2 = 0;
p_DestinationString = ResourceUnicodeId;
DestinationString = 0i64;
if( !HalpTimerRegistrationAllowed )
return -1073741431;
if( NewTimer->Header.TableVersion != 1 )
return -1073741811;
if( NewTimer->Header.TableSize != 144 )
return -1073741811;
Capabilities = NewTimer->Capabilities;
if( (Capabilities & 0xFE000000) != 0
|| (Capabilities & 0x400000) != 0
|| NewTimer->KnownType == TimerInvalid
|| (Capabilities & 0x400) != 0 && !NewTimer->FunctionTable.SetMessageInterruptRouting )
{
return -1073741811;
}
if( (Capabilities & 0x1000) != 0 || (Capabilities & 0x80u) != 0 )
return -1073741637;
if( (Capabilities & 0x800) != 0 && !NewTimer->FunctionTable.SetInterruptVector )
return -1073741811;
if( (Capabilities & 0x801) == 2048 )
return -1073741637;
if( (Capabilities & 0xF00) != 0 && !NewTimer->FunctionTable.Stop
|| (Capabilities & 2) != 0 && !NewTimer->FunctionTable.QueryCounter
|| (Capabilities & 0x10000) != 0 && (Capabilities & 1) == 0 )
{
return -1073741811;
}
if( !ResourceUnicodeId )
{
HalpTimerBuildKnownResourceIdString((INT64)NewTimer, 75i64, SourceString);
p_DestinationString = &DestinationString;
RtlInitUnicodeString(&DestinationString, SourceString, v6);
Capabilities = NewTimer->Capabilities;
}
if( (Capabilities & 0x10000) != 0 )
{
MaximumProcessorCount = HalQueryMaximumProcessorCount();
InternalDataSize = (NewTimer->InternalDataSize + 7) & 0xFFFFFFF8;
}
else
{
InternalDataSize = NewTimer->InternalDataSize;
MaximumProcessorCount = 1;
}
MemoryInternal = HalpMmAllocateMemoryInternal(
(((MaximumProcessorCount * InternalDataSize + 351) & 0xFFFFFFF8) + 9 + p_DestinationString->Length) & 0xFFFFFFF8,
MmCached);
v10 = (__int64)MemoryInternal;
if( !MemoryInternal )
return -1073741670;
memset((INT64)MemoryInternal, 0i64);
v12 = (v10 + 303) & 0xFFFFFFFFFFFFFFF8ui64;
*(_QWORD *)(v10 + 288) = v12;
v13 = (v12 + 55) & 0xFFFFFFFFFFFFFFF8ui64;
*(_QWORD *)(v10 + 72) = v13;
*(_QWORD *)(v12 + 32) = (MaximumProcessorCount * InternalDataSize + v13 + 7) & 0xFFFFFFFFFFFFFFF8ui64;
*(_QWORD *)(v10 + 192) = NewTimer->CounterFrequency;
*(_OWORD *)(v10 + 104) = *(_OWORD *)&NewTimer->FunctionTable.Initialize;
*(_OWORD *)(v10 + 120) = *(_OWORD *)&NewTimer->FunctionTable.AcknowledgeInterrupt;
*(_OWORD *)(v10 + 136) = *(_OWORD *)&NewTimer->FunctionTable.Stop;
*(_OWORD *)(v10 + 152) = *(_OWORD *)&NewTimer->FunctionTable.SetMessageInterruptRouting;
v14 = *(_OWORD *)&NewTimer->FunctionTable.SetInterruptVector;
*(_DWORD *)(v10 + 80) = InternalDataSize;
*(_OWORD *)(v10 + 168) = v14;
*(_DWORD *)(v10 + 220) = NewTimer->CounterBitWidth;
*(_DWORD *)(v10 + 224) = NewTimer->Capabilities;
*(_DWORD *)(v10 + 84) = NewTimer->Interrupt.LegacyIrq;
*(_DWORD *)(v10 + 88) = NewTimer->Interrupt.Gsi;
*(_DWORD *)(v10 + 96) = NewTimer->Interrupt.Mode;
*(_DWORD *)(v10 + 92) = NewTimer->Interrupt.Polarity;
*(_DWORD *)(v10 + 228) = NewTimer->KnownType;
*(_DWORD *)(v10 + 216) = NewTimer->MaxDivisor;
if( NewTimer->InternalDataSize )
{
if( NewTimer->InternalData )
{
for( i = 0; i < MaximumProcessorCount; ++i )
memmove(
(UINT8 *)(*(_QWORD *)(v10 + 72) + i * *(_DWORD *)(v10 + 80)),
(UINT8 *)NewTimer->InternalData,
NewTimer->InternalDataSize);
}
}
*(_DWORD *)(v10 + 284) = NewTimer->Identifier;
*(_WORD *)(v12 + 24) = 0;
*(_WORD *)(v12 + 26) = p_DestinationString->Length + 2;
RtlCopyUnicodeString((UNICODE_STRING *)(v12 + 24), p_DestinationString, v11);
if( (NewTimer->Capabilities & 0x400) != 0 )
{
*(_QWORD *)(v12 + 12) = 0i64;
*(_DWORD *)(v12 + 8) = 0;
*(_DWORD *)v12 = 0;
*(_DWORD *)(v12 + 4) = 0;
if( NewTimer->KnownType == TimerHpet )
HalpPciGetHpetInterruptSource(
BYTE2(NewTimer->Identifier),
v12 + 8,
(INT64 *)((v10 + 303) & 0xFFFFFFFFFFFFFFF8ui64),
(INT64 *)(v12 + 4));
}
v16 = (__int64 *)qword_140C4BEA8;
if( *(ULONG_PTR **)qword_140C4BEA8 != &HalpRegisteredTimers )
__fastfail(3u);
LODWORD(HalpRegisteredTimerCount) = HalpRegisteredTimerCount + 1;
*(_QWORD *)v10 = &HalpRegisteredTimers;
*(_QWORD *)(v10 + 8) = v16;
*v16 = v10;
qword_140C4BEA8 = v10;
if( (*(_DWORD *)(v10 + 224) & 0x100000) != 0 )
HalpTimerAuxiliaryClockEnabled = 1;
return v2;
}Referenced by:
HalpApicTimerDiscover
HalpArtDiscover
HalpHpetDiscover
HalpHvDiscover
HalpHvWatchdogDiscover
HalpPmTimerDiscover
HalpRtcDiscover
HalpSfiTimerDiscover
HalpTimerRegisterBuiltinPlugins
HalpTscDiscover
HalpVpptTimerRegister
HalpWdatDiscover