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