CmpGetSymbolicLinkTarget

__int64 __fastcall CmpGetSymbolicLinkTarget(
        __int64 a1,
        __int64 a2,
        __int16 a3,
        __int16 a4,
        __int64 a5,
        __int64 a6,
        __int64 a7,
        struct _UNICODE_STRING *a8,
        ULONG_PTR *a9){
  unsigned int v11; 
  unsigned int v12; 
  _CM_KEY_CONTROL_BLOCK *v13; 
  char v14; 
  INT16 v15; 
  char v16; 
  INT64 KcbAtLayerHeight; 
  INT64 v18; 
  char v19; 
  unsigned __int64 v20; 
  char v21; 
  unsigned int v22; 
  unsigned int i; 
  unsigned __int16 *v24; 
  int v25; 
  WCHAR v26; 
  const _UNICODE_STRING *v27; 
  unsigned __int64 v28; 
  _UNICODE_STRING *v29; 
  wchar_t *v30; 
  int NameInListWithStatus; 
  wchar_t *Buffer; 
  UINT64 v34; 
  INT64 v35; 
  INT16 v36; 
  UINT64 v37; 
  __int64 v38; 
  __int64 v39; 
  INT64 v40; 
  INT64 v41; 
  unsigned int v42; 
  unsigned int v43; 
  unsigned __int16 *ComponentNameAtIndex; 
  int v45; 
  unsigned int v46; 
  INT64 v47; 
  void(__fastcall *v48)(INT64, __int64 *); 
  __int64 v49; 
  WCHAR v50; 
  _UNICODE_STRING v51; 
  unsigned __int16 v52; 
  _WORD *v53; 
  __int16 v54; 
  __int16 v55; 
  unsigned int v56; 
  UINT8 *v57; 
  int v58; 
  __int64 v59; 
  int v60; 
  unsigned int v61; 
  INT64 v62; 
  unsigned int v63; 
  unsigned int v64; 
  const _UNICODE_STRING *v65; 
  unsigned __int64 v66; 
  __int64 v67; 
  wchar_t *v68; 
  CHAR v69[4]; 
  _DWORD CellIndex[3]; 
  _UNICODE_STRING DestinationString; 
  __int16 v72[2]; 
  _WORD v73[2]; 
  __int16 v74; 
  unsigned int v75; 
  INT64 v76; 
  volatile INT64 *P2; 
  PVOID P; 
  UINT64 v79; 
  __int64 v80; 
  INT64 v81; 
  __int64 v82[2]; 
  __m128i v83; 
  INT64 v84; 
  INT64 v85; 
  UNICODE_STRING SourceString; 
  _UNICODE_STRING SourceName; 
  struct _UNICODE_STRING *v88; 
  ULONG_PTR *v89; 
  __int64 v90; 
  INT64 a2a; 
  INT64 v92[2]; 
  __int128 v93; 
  INT64 result[22]; 
  v79 = a6;
  a2a = a7;
  v88 = a8;
  v89 = a9;
  v11 = a4;
  v84 = a1;
  v72[0] = 0;
  v73[0] = 0;
  v74 = a4;
  v12 = a3;
  v90 = a5;
  DestinationString = 0i64;
  SourceString = 0i64;
  SourceName = 0i64;
  RtlInitUnicodeString(&DestinationString, 0i64, a3);
  CellIndex[1] = -1;
  v13 = 0i64;
  v14 = 0;
  P2 = 0i64;
  v69[3] = 0;
  v85 = 0i64;
  v76 = 0i64;
  P = 0i64;
  v75 = 0;
  v80 = 0xFFFFFFFFi64;
  v82[0] = 0xFFFFFFFFi64;
  LOBYTE(CellIndex[0]) = 0;
  v81 = 0xFFFFFFFFi64;
  memset((INT64)result, 0i64);
  v15 = *(_WORD *)(a1 + 2);
  *(_OWORD *)v92 = 0i64;
  WORD1(v92[0]) = -1;
  v93 = 0i64;
  if( a5 || v15 )
  {
    v16 = 0;
  }
  else
  {
    v16 = 1;
    v15 = 0;
  }
  KcbAtLayerHeight = CmpGetKcbAtLayerHeight(a1, v15);
  v18 = KcbAtLayerHeight;
  if( !v16 || (*(_DWORD *)(KcbAtLayerHeight + 8) & 8) == 0 )
  {
LABEL_30:
    v34 = v79;
    if( (*(_DWORD *)(v79 + 160) & 1) == 0 )
    {
      CmpAttachToRegistryProcess((KAPC_STATE *)(v79 + 168));
      *(_DWORD *)(v34 + 160) |= 1u;
    }
    v35 = v84;
    v36 = *(_WORD *)(v84 + 2);
    *(_WORD *)v69 = v36;
    if( v36 < 0 )
      goto LABEL_111;
    while( 1 )
    {
      v79 = CmpGetKcbAtLayerHeight(v35, v36);
      v37 = v79;
      if( (unsigned int)CmpGetEffectiveKcbSemantics((_CM_KEY_CONTROL_BLOCK *)v79) == 1 )
        goto LABEL_111;
      if( *(_DWORD *)(v38 + 40) != -1 )
      {
        if( CmEqualTrans(*(_QWORD *)(v38 + 288), v90) )
        {
          if( !*(_DWORD *)(v37 + 280) )
          {
            CellIndex[1] = -1;
            goto LABEL_95;
          }
          NameInListWithStatus = CmpFindNameInListWithStatus(
                                   *(_HHIVE **)(v37 + 32),
                                   (_CHILD_LIST *)(v37 + 280),
                                   &CmSymbolicLinkValueName,
                                   0i64,
                                   0i64,
                                   (UINT64 *)&CellIndex[1]);
        }
        else
        {
          v39 = (*(__int64(__fastcall **)(_QWORD, _QWORD, __int64 *))(*(_QWORD *)(v37 + 32) + 8i64))(
                  *(_QWORD *)(v37 + 32),
                  *(unsigned int *)(v37 + 40),
                  &v80);
          NameInListWithStatus = CmpFindNameInListWithStatus(
                                   *(_HHIVE **)(v37 + 32),
                                   (_CHILD_LIST *)(v39 + 36),
                                   &CmSymbolicLinkValueName,
                                   0i64,
                                   0i64,
                                   (UINT64 *)&CellIndex[1]);
          (*(void(__fastcall **)(_QWORD, __int64 *))(*(_QWORD *)(v79 + 32) + 16i64))(*(_QWORD *)(v79 + 32), &v80);
        }
        if( NameInListWithStatus >= 0 )
        {
          v40 = *(_QWORD *)(v79 + 32);
          v76 = v40;
          goto LABEL_39;
        }
        if( NameInListWithStatus != -1073741772 )
          goto LABEL_99;
      }
LABEL_95:
      v36 = --*(_WORD *)v69;
      if( *(__int16 *)v69 < 0 )
      {
        v40 = v76;
LABEL_39:
        if( CellIndex[1] != -1 )
        {
          v41 = (*(__int64(__fastcall **)(INT64, _QWORD, __int64 *))(v40 + 8))(v40, CellIndex[1], v82);
          v85 = v41;
          if( (*(_BYTE *)(v41 + 16) & 2) == 0 && *(_DWORD *)(v41 + 12) == 6 )
          {
            if( !CmpGetValueData(v76, CellIndex[1], v41, (UINT64 *)&v75, (INT64)&P, (INT64)CellIndex, (INT64)&v81) )
            {
              NameInListWithStatus = -1073741670;
              goto LABEL_99;
            }
            if( v75 <= 0xFFFF && (v75 & 1) == 0 )
            {
              v42 = v12;
              SourceString.Buffer = (wchar_t *)P;
              SourceString.Length = v75;
              SourceString.MaximumLength = v75;
              v43 = (unsigned __int16)v75;
              LODWORD(v79) = v12;
              if( v12 < v74 )
              {
                do
                {
                  ComponentNameAtIndex = (unsigned __int16 *)CmpGetComponentNameAtIndex(a2, v42);
                  v42 = v45 + 1;
                  v43 += *ComponentNameAtIndex + 2;
                }
                while( v42 < v46 );
              }
              if( v43 <= 0xFFFF )
              {
                DestinationString.Buffer = (wchar_t *)ExAllocatePoolWithTag(PagedPool, v43, 0x36364D43ui64);
                Buffer = DestinationString.Buffer;
                if( !DestinationString.Buffer )
                {
                  NameInListWithStatus = -1073741670;
                  v21 = 1;
                  goto LABEL_21;
                }
                DestinationString.Length = 0;
                DestinationString.MaximumLength = v43;
                RtlUnicodeStringCopy(&DestinationString, &SourceString);
                if( LOBYTE(CellIndex[0]) )
                {
                  ExFreePoolWithTag(P, 0);
                  v47 = v76;
                }
                else
                {
                  v47 = v76;
                  (*(void(__fastcall **)(INT64, INT64 *))(v76 + 16))(v76, &v81);
                }
                v48 = *(void(__fastcall **)(INT64, __int64 *))(v47 + 16);
                P = 0i64;
                v48(v47, v82);
                v85 = 0i64;
                v49 = v84;
                CmpUnlockKcbStack(v84);
                v51 = DestinationString;
                if( v16 )
                {
                  v21 = 0;
                  SourceName.Buffer = DestinationString.Buffer;
                  v52 = 0;
                  v83 = (__m128i)DestinationString;
                  SourceName.Length = 0;
                  SourceName.MaximumLength = DestinationString.MaximumLength;
                  if( DestinationString.Length )
                  {
                    v53 = (_WORD *)v83.m128i_i64[1];
                    v54 = v83.m128i_i16[1];
                    v55 = v83.m128i_i16[0];
                    while( *v53 == 92 )
                    {
                      ++v53;
                      v55 -= 2;
                      v54 -= 2;
                      v83.m128i_i64[1] = (__int64)v53;
                      v52 += 2;
                      v83.m128i_i16[0] = v55;
                      v83.m128i_i16[1] = v54;
                      SourceName.Length = v52;
                      if( !v55 )
                        goto LABEL_61;
                    }
                    if( v55 )
                    {
                      while( *v53 != 92 )
                      {
                        ++v53;
                        v55 -= 2;
                        v54 -= 2;
                        v83.m128i_i64[1] = (__int64)v53;
                        v52 += 2;
                        v83.m128i_i16[0] = v55;
                        v83.m128i_i16[1] = v54;
                        SourceName.Length = v52;
                        if( !v55 )
                          goto LABEL_61;
                      }
                      do
                      {
                        if( *v53 != 92 )
                          break;
                        ++v53;
                        v54 -= 2;
                        v55 -= 2;
                      }
                      while( v55 );
                      v83.m128i_i64[1] = (__int64)v53;
                      v83.m128i_i16[0] = v55;
                      v83.m128i_i16[1] = v54;
                    }
                  }
LABEL_61:
                  if( !CmpCompareUnicodeString(&SourceName, &CmRegistryRootName, 2ui64)
                    && (int)CmpComputeComponentHashes(&v83, v72, (INT64)result) >= 0 )
                  {
                    v56 = v72[0];
                    if( (int)CmpValidateComponents((unsigned int)v72[0], (INT64)result) >= 0 )
                    {
                      if( (int)CmpPerformCompleteKcbCacheLookup(
                                  *((_QWORD *)CmpRegistryRootObject + 1),
                                  0i64,
                                  v56,
                                  (INT64)result,
                                  0i64,
                                  (INT64 *)&P2,
                                  &v69[3],
                                  v73) < 0 )
                      {
                        v13 = (_CM_KEY_CONTROL_BLOCK *)P2;
                      }
                      else if( v73[0] == (_WORD)v56 )
                      {
                        v13 = (_CM_KEY_CONTROL_BLOCK *)P2;
                        if( (int)CmpStartKcbStackForTopLayerKcb((INT64)v92, (INT64)P2) >= 0 )
                        {
                          CmpLockKcbStackShared((INT64)v92);
                          v58 = CmpConstructAndCacheName(v13, 0i64, v57);
                          CmpUnlockKcbStack((__int64)v92);
                          if( v58 >= 0 )
                          {
                            if( v69[3] )
                            {
                              CmpUnlockHashEntryByKcb((INT64)v13);
                              v69[3] = 0;
                            }
                            CmpLockKcbStackTopExclusiveRestShared(v49);
                            v21 = 1;
                            if( !CmpIsKeyStackDeleted(v49, 0i64) )
                            {
                              v59 = (*(__int64(__fastcall **)(_QWORD, _QWORD, __int64 *))(*(_QWORD *)(v18 + 32) + 8i64))(
                                      *(_QWORD *)(v18 + 32),
                                      *(unsigned int *)(v18 + 40),
                                      &v80);
                              v60 = CmpFindNameInListWithStatus(
                                      *(_HHIVE **)(v18 + 32),
                                      (_CHILD_LIST *)(v59 + 36),
                                      &CmSymbolicLinkValueName,
                                      0i64,
                                      0i64,
                                      (UINT64 *)&CellIndex[1]);
                              (*(void(__fastcall **)(_QWORD, __int64 *))(*(_QWORD *)(v18 + 32) + 16i64))(
                                *(_QWORD *)(v18 + 32),
                                &v80);
                              if( v60 >= 0 )
                              {
                                v61 = CellIndex[1];
                                v76 = *(_QWORD *)(v18 + 32);
                                v62 = (*(__int64(__fastcall **)(INT64, _QWORD, __int64 *))(v76 + 8))(
                                        v76,
                                        CellIndex[1],
                                        v82);
                                v85 = v62;
                                if( *(_DWORD *)(v62 + 12) == 6 )
                                {
                                  if( CmpGetValueData(
                                         v76,
                                         v61,
                                         v62,
                                         (UINT64 *)&v75,
                                         (INT64)&P,
                                         (INT64)CellIndex,
                                         (INT64)&v81) )
                                  {
                                    if( v75 <= 0xFFFF && (v75 & 1) == 0 )
                                    {
                                      SourceString.Length = v75;
                                      SourceString.MaximumLength = v75;
                                      SourceString.Buffer = (wchar_t *)P;
                                      if( !CmpCompareUnicodeString(&DestinationString, &SourceString, 0i64) )
                                      {
                                        CmpCleanUpKcbCachedSymlink(v18, a2a);
                                        *(_QWORD *)(v18 + 104) = v13;
                                        CmpReferenceKeyControlBlockUnsafe((volatile INT64 *)v13);
                                        *(_WORD *)(v18 + 8) |= 8u;
                                        CmpUnlockKcbStack(v49);
                                        goto LABEL_78;
                                      }
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                      else
                      {
                        CmpDereferenceKeyControlBlock((UINT64)P2);
                        v13 = 0i64;
                      }
                    }
                  }
                }
                else
                {
LABEL_78:
                  v21 = 0;
                }
                v63 = v74;
                v64 = v79;
                if( (unsigned int)v79 < v74 )
                {
                  do
                  {
                    v65 = (const _UNICODE_STRING *)CmpGetComponentNameAtIndex(a2, v64);
                    v66 = (unsigned __int64)DestinationString.Length >> 1;
                    DestinationString.Length += 2;
                    DestinationString.Buffer[v66] = 92;
                    RtlUnicodeStringCat(&DestinationString, v65);
                    ++v64;
                  }
                  while( v64 < v63 );
                  v51 = DestinationString;
                  v14 = 0;
                }
                v67 = (__int64)v88;
                v68 = v88->Buffer;
                if( v68 )
                {
                  ExFreePoolWithTag(v68, 0);
                  *(_QWORD *)(v67 + 8) = 0i64;
                }
                if( v69[3] )
                  CmpUnlockHashEntryByKcb((INT64)v13);
                *v89 = (ULONG_PTR)v13;
                v13 = 0i64;
                *(_UNICODE_STRING *)v67 = v51;
                RtlInitUnicodeString(&DestinationString, 0i64, v50);
                NameInListWithStatus = 0;
                goto LABEL_19;
              }
            }
          }
        }
LABEL_111:
        NameInListWithStatus = -1073741772;
LABEL_99:
        v21 = 1;
LABEL_19:
        Buffer = DestinationString.Buffer;
        if( DestinationString.Buffer )
          ExFreePoolWithTag(DestinationString.Buffer, 0);
LABEL_21:
        if( P )
        {
          if( LOBYTE(CellIndex[0]) )
            ExFreePoolWithTag(P, 0);
          else(*(void(__fastcall **)(INT64, INT64 *))(v76 + 16))(v76, &v81);
        }
        if( v85 )
          (*(void(__fastcall **)(INT64, __int64 *))(v76 + 16))(v76, v82);
        if( Buffer )
          ExFreePoolWithTag(Buffer, 0);
        if( v21 )
          CmpUnlockKcbStack(v84);
        goto LABEL_28;
      }
      v35 = v84;
    }
  }
  v19 = 0;
  P2 = *(volatile INT64 **)(KcbAtLayerHeight + 104);
  v20 = *((_QWORD *)P2 + 37);
  if( (v20 & 1) != 0 )
  {
    v19 = 1;
    v20 &= ~1ui64;
  }
  if( !v20 || v19 )
  {
    v13 = (_CM_KEY_CONTROL_BLOCK *)P2;
    v14 = 0;
    goto LABEL_30;
  }
  v13 = (_CM_KEY_CONTROL_BLOCK *)P2;
  CmpReferenceKeyControlBlockUnsafe(P2);
  CmpUnlockKcbStack(v84);
  v21 = 0;
  CmpLockKcbShared(v13);
  v22 = *(unsigned __int16 *)v20;
  for( i = v12; i < v11; v22 += *v24 + 2 )
  {
    v24 = (unsigned __int16 *)CmpGetComponentNameAtIndex(a2, i);
    i = v25 + 1;
  }
  if( v22 > 0xFFFF )
  {
    v14 = 1;
    NameInListWithStatus = -1073741772;
    goto LABEL_19;
  }
  DestinationString.Buffer = (wchar_t *)ExAllocatePoolWithTag(PagedPool, v22, 0x36364D43ui64);
  if( DestinationString.Buffer )
  {
    DestinationString.MaximumLength = v22;
    DestinationString.Length = 0;
    RtlUnicodeStringCopy(&DestinationString, (UNICODE_STRING *)v20);
    for( ; v12 < v11; ++v12 )
    {
      v27 = (const _UNICODE_STRING *)CmpGetComponentNameAtIndex(a2, v12);
      v28 = (unsigned __int64)DestinationString.Length >> 1;
      DestinationString.Length += 2;
      DestinationString.Buffer[v28] = 92;
      RtlUnicodeStringCat(&DestinationString, v27);
    }
    v29 = v88;
    v30 = v88->Buffer;
    if( v30 )
      ExFreePoolWithTag(v30, 0);
    *v29 = DestinationString;
    RtlInitUnicodeString(&DestinationString, 0i64, v26);
    CmpUnlockKcb((UINT64)v13);
    v14 = 0;
    *v89 = (ULONG_PTR)v13;
    v13 = 0i64;
    NameInListWithStatus = 0;
    goto LABEL_19;
  }
  v14 = 1;
  NameInListWithStatus = -1073741670;
LABEL_28:
  if( v13 )
  {
    if( v14 )
      CmpUnlockKcb((UINT64)v13);
    CmpDereferenceKeyControlBlock((UINT64)v13);
  }
  CmpCleanupKcbStack((INT64)v92);
  CmpCleanupPathInfo((__int64)result);
  return(unsigned int)NameInListWithStatus;
}

Referenced by:

CmpDoParseKey