CmpNotifyChangeKey

__int64 __fastcall CmpNotifyChangeKey(__int64 a1, _QWORD *a2, __int64 a3, char a4, __int64 a5, __int64 a6, __int64 a7){
  int v7; 
  _CM_NOTIFY_BLOCK *v11; 
  __int64 v12; 
  _LIST_ENTRY *Flink; 
  _LIST_ENTRY *p_PostList; 
  _QWORD *v15; 
  wchar_t *Buffer; 
  _UNICODE_STRING *v17; 
  _QWORD *v18; 
  _CM_NOTIFY_BLOCK *PoolWithQuotaTag; 
  _CM_NOTIFY_BLOCK **v21; 
  _LIST_ENTRY *v22; 
  unsigned __int8 CurrentIrql; 
  _ETHREAD *CurrentThread; 
  _ETHREAD *v25; 
  _UNICODE_STRING **v26; 
  _UNICODE_STRING ***v27; 
  _QWORD *v28; 
  wchar_t *v29; 
  int v30[8]; 
  v7 = a3;
  if( (*(_DWORD *)(a1 + 48) & 9) != 0 )
  {
    CmpFreePostBlock(a2);
    return 3221225852i64;
  }
  v11 = *(_CM_NOTIFY_BLOCK **)(a1 + 16);
  v12 = *(_QWORD *)(*(_QWORD *)(a1 + 8) + 32i64);
  if( !v11 )
  {
    PoolWithQuotaTag = (_CM_NOTIFY_BLOCK *)ExAllocatePoolWithQuotaTag((POOL_TYPE)9, 0x58ui64, 0x626E4D43ui64);
    v11 = PoolWithQuotaTag;
    if( !PoolWithQuotaTag )
    {
      CmpFreePostBlock(a2);
      return 3221225626i64;
    }
    PoolWithQuotaTag->KeyControlBlock = *(_CM_KEY_CONTROL_BLOCK **)(a1 + 8);
    *((_DWORD *)PoolWithQuotaTag + 12) = v7 & 0x3FFFFFFF | ((a4 & 1) << 30);
    PoolWithQuotaTag->PostList.Blink = &PoolWithQuotaTag->PostList;
    PoolWithQuotaTag->PostList.Flink = &PoolWithQuotaTag->PostList;
    *(_QWORD *)(a1 + 16) = PoolWithQuotaTag;
    PoolWithQuotaTag->KeyBody = (_CM_KEY_BODY *)a1;
    SeCaptureSubjectContext(&PoolWithQuotaTag->SubjectContext);
    v21 = (_CM_NOTIFY_BLOCK **)(v12 + 1584);
    v22 = *(_LIST_ENTRY **)(v12 + 1584);
    if( v22 )
    {
      a3 = (*(_DWORD *)(*(_QWORD *)(a1 + 8) + 8i64) >> 21) & 0x3FF;
      while( 1 )
      {
        v21 = (_CM_NOTIFY_BLOCK **)v22;
        if( ((LODWORD(v22[2].Flink->Blink) >> 21) & 0x3FF) > (unsigned int)a3 )
          break;
        v22 = v22->Flink;
        if( !*v21 )
          goto LABEL_18;
      }
      v11->HiveList.Flink = v22;
      v22->Blink->Flink = &v11->HiveList;
      v11->HiveList.Blink = v22->Blink;
      v22->Blink = &v11->HiveList;
    }
    else
    {
LABEL_18:
      *v21 = v11;
      v11->HiveList.Flink = 0i64;
      v11->HiveList.Blink = (_LIST_ENTRY *)v21;
    }
  }
  Flink = v11->PostList.Flink;
  p_PostList = &v11->PostList;
  if( Flink->Blink != &v11->PostList )
    goto LABEL_30;
  *a2 = Flink;
  a2[1] = p_PostList;
  Flink->Blink = (_LIST_ENTRY *)a2;
  v15 = a2 + 4;
  p_PostList->Flink = (_LIST_ENTRY *)a2;
  if( (a2[7] & 0x10000) != 0 )
  {
    a2[5] = a2 + 4;
    *v15 = v15;
  }
  else
  {
    v28 = *(_QWORD **)(a7 + 40);
    if( *v28 != a7 + 32 )
      goto LABEL_30;
    *v15 = a7 + 32;
    a2[5] = v28;
    *v28 = v15;
    *(_QWORD *)(a7 + 40) = v15;
  }
  if( (unsigned int)(unsigned __int16)*((_DWORD *)a2 + 14) - 3 <= 1 )
  {
    Buffer = CmpAsyncKernelPostList.Buffer;
    v17 = &CmpAsyncKernelPostList;
    v18 = a2 + 2;
    if( *(_UNICODE_STRING **)CmpAsyncKernelPostList.Buffer == &CmpAsyncKernelPostList )
    {
      *v18 = &CmpAsyncKernelPostList;
      a2[3] = Buffer;
      *(_QWORD *)Buffer = v18;
      CmpAsyncKernelPostList.Buffer = (wchar_t *)(a2 + 2);
      goto LABEL_9;
    }
LABEL_30:
    __fastfail(3u);
  }
  CurrentIrql = KeGetCurrentIrql();
  __writecr8(1ui64);
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  if( (*((_BYTE *)CurrentThread + 1304) & 8) == 0 )
  {
    *((_BYTE *)CurrentThread + 1304) |= 8u;
    _InterlockedOr(v30, 0);
    *((_QWORD *)CurrentThread + 138) = (char *)CurrentThread + 1096;
    *((_QWORD *)CurrentThread + 137) = (char *)CurrentThread + 1096;
  }
  v25 = (_ETHREAD *)KeGetCurrentThread();
  v26 = (_UNICODE_STRING **)(a2 + 2);
  if( (a2[7] & 0x10000) != 0 )
  {
    v27 = (_UNICODE_STRING ***)((char *)v25 + 1096);
    v17 = (_UNICODE_STRING *)*((_QWORD *)v25 + 137);
    if( (_UNICODE_STRING ***)v17->Buffer != v27 )
      goto LABEL_30;
    *v26 = v17;
    a2[3] = v27;
    v17->Buffer = (wchar_t *)v26;
    *v27 = v26;
  }
  else
  {
    v17 = (_UNICODE_STRING *)((char *)v25 + 1096);
    v29 = v17->Buffer;
    if( *(_UNICODE_STRING **)v29 != v17 )
      goto LABEL_30;
    *v26 = v17;
    a2[3] = v29;
    *(_QWORD *)v29 = v26;
    v17->Buffer = (wchar_t *)v26;
  }
  __writecr8(CurrentIrql);
LABEL_9:
  if( *((int *)v11 + 12) >= 0 )
    return 259i64;
  CmpPostNotify(v11, v17, a3, 268i64, 1u, 0i64, 0i64);
  return 0i64;
}

Referenced by:

NtNotifyChangeMultipleKeys