CmpQueryKeyValueData

__int64 __fastcall CmpQueryKeyValueData(
        _CM_KEY_CONTROL_BLOCK *KeyControlBlock,
        unsigned int ValueKeyCell,
        _CM_KEY_VALUE *ValueKey,
        _KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
        void *KeyValueInformation,
        unsigned int Length,
        unsigned int *ResultLength){
  _CM_KEY_CONTROL_BLOCK *v9; 
  unsigned int v10; 
  size_t v11; 
  _DWORD *v12; 
  unsigned __int16 NameLength; 
  unsigned int DataLength; 
  unsigned int v15; 
  unsigned int v16; 
  size_t v17; 
  __int32 v19; 
  unsigned int v20; 
  unsigned int v21; 
  unsigned int v22; 
  unsigned int v23; 
  unsigned int v24; 
  size_t v25; 
  unsigned int v26; 
  unsigned int i; 
  size_t v28; 
  wchar_t *v29; 
  __int32 v30; 
  unsigned int v31; 
  unsigned int v32; 
  unsigned int v33; 
  size_t v34; 
  VOID *Src; 
  INT64 v36[2]; 
  _HHIVE *KeyHive; 
  unsigned int v40; 
  INT64 v41; 

  v9 = KeyControlBlock;
  v10 = Length;
  v11 = 0;
  Src = 0i64;
  LOBYTE(v41) = 0;
  v36[0] = 0xFFFFFFFFi64;
  KeyHive = KeyControlBlock->KeyHash.KeyHive;
  v12 = KeyValueInformation;
  v36[1] = (INT64)ValueKey;
  NameLength = 2 * ValueKey->NameLength;
  if( (ValueKey->Flags & 1) == 0 )
    NameLength = ValueKey->NameLength;
  if( KeyValueInformationClass == KeyValuePartialInformation )
  {
    DataLength = ValueKey->DataLength;
    v15 = DataLength + 0x80000000;
    if( DataLength < 0x80000000 )
      v15 = ValueKey->DataLength;
    LODWORD(KeyValueInformation) = v15;
    v16 = 0;
    *ResultLength = v15 + 12;
    if( v10 < 0xC )
    {
      v16 = -1073741789;
    }
    else
    {
      *v12 = 0;
      v12[1] = ValueKey->Type;
      v12[2] = v15;
      v17 = v10 - 12;
      if( v10 - 12 < v15 )
        v16 = -2147483643;
      if( v17 >= v15 )
        v17 = v15;
      if( v15 )
      {
        if( DataLength >= 0x80000000 )
        {
          Src = &ValueKey->Data;
        }
        else if( !CmpGetValueData(
                     v9->KeyHash.KeyHive,
                     ValueKeyCell,
                     ValueKey,
                     (unsigned int *)&KeyValueInformation,
                     &Src,
                     (unsigned __int8 *)&v41,
                     (_HV_GET_CELL_CONTEXT *)v36) )
        {
          v16 = -1073741670;
        }
        if( Src )
          memmove(v12 + 3, Src, v17);
      }
    }
  }
  else if( KeyValueInformationClass )
  {
    v19 = KeyValueInformationClass - 1;
    if( v19 && (v30 = v19 - 2) != 0 )
    {
      if( v30 == 1 )
      {
        v31 = ValueKey->DataLength;
        v32 = v31 + 0x80000000;
        if( v31 < 0x80000000 )
          v32 = ValueKey->DataLength;
        LODWORD(KeyValueInformation) = v32;
        v16 = 0;
        *ResultLength = v32 + 8;
        if( v10 < 8 )
        {
          v16 = -1073741789;
        }
        else
        {
          *v12 = ValueKey->Type;
          v12[1] = v32;
          v33 = v10 - 8;
          v34 = v32;
          if( v33 < v32 )
          {
            v34 = v33;
            v16 = -2147483643;
          }
          if( v32 )
          {
            if( v31 < 0x80000000 )
            {
              if( !CmpGetValueData(
                      v9->KeyHash.KeyHive,
                      ValueKeyCell,
                      ValueKey,
                      (unsigned int *)&KeyValueInformation,
                      &Src,
                      (unsigned __int8 *)&v41,
                      (_HV_GET_CELL_CONTEXT *)v36) )
                v16 = -1073741670;
            }
            else
            {
              Src = &ValueKey->Data;
            }
            if( Src )
              memmove(v12 + 2, Src, v34);
          }
        }
      }
      else
      {
        v16 = -1073741811;
      }
    }
    else
    {
      v20 = ValueKey->DataLength;
      v40 = v20;
      if( v20 >= 0x80000000 )
        v21 = v20 + 0x80000000;
      else
        v21 = ValueKey->DataLength;
      LODWORD(KeyValueInformation) = v21;
      v22 = NameLength;
      v23 = v21 + NameLength + 20;
      v24 = 0;
      if( v21 )
      {
        v24 = (v23 - v21 + 7) & 0xFFFFFFF8;
        if( v24 > v23 - v21 )
          v23 = v24 + v21;
      }
      v16 = 0;
      *ResultLength = v23;
      if( v10 < 0x14 )
      {
        v16 = -1073741789;
      }
      else
      {
        *v12 = 0;
        v12[1] = ValueKey->Type;
        v12[3] = v21;
        v12[4] = v22;
        v25 = v10 - 20;
        if( v10 - 20 < v22 )
          v16 = -2147483643;
        if( v25 >= v22 )
          v25 = v22;
        if( (ValueKey->Flags & 1) != 0 )
        {
          v26 = v25 >> 1;
          if( v26 >= ValueKey->NameLength )
            v26 = ValueKey->NameLength;
          for( i = 0; i < v26; ++i )
            *((_WORD *)v12 + i + 10) = *((unsigned __int8 *)ValueKey->Name + i);
        }
        else
        {
          memmove(v12 + 5, ValueKey->Name, v25);
          v20 = v40;
          v9 = KeyControlBlock;
        }
        if( v21 )
        {
          if( v20 >= 0x80000000 )
          {
            Src = &ValueKey->Data;
          }
          else
          {
            if( !CmpGetValueData(
                    v9->KeyHash.KeyHive,
                    ValueKeyCell,
                    ValueKey,
                    (unsigned int *)&KeyValueInformation,
                    &Src,
                    (unsigned __int8 *)&v41,
                    (_HV_GET_CELL_CONTEXT *)v36) )
              v16 = -1073741670;
            v21 = (unsigned int)KeyValueInformation;
          }
          v12[2] = v24;
          if( v10 >= v24 )
            v11 = v10 - v24;
          if( v11 < v21 )
            v16 = -2147483643;
          if( v11 >= v21 )
            v11 = v21;
          if( Src )
            memmove((char *)v12 + v24, Src, v11);
        }
        else
        {
          v12[2] = -1;
        }
      }
    }
  }
  else
  {
    v16 = 0;
    *ResultLength = NameLength + 12;
    if( v10 < 0xC )
    {
      v16 = -1073741789;
    }
    else
    {
      *v12 = 0;
      v12[1] = ValueKey->Type;
      v12[2] = NameLength;
      v28 = v10 - 12;
      if( v28 < NameLength )
        v16 = -2147483643;
      if( v28 >= NameLength )
        v28 = NameLength;
      v29 = (wchar_t *)(v12 + 3);
      if( (ValueKey->Flags & 1) != 0 )
        CmpCopyCompressedName(v29, v28, ValueKey->Name, ValueKey->NameLength);
      else
        memmove(v29, ValueKey->Name, v28);
    }
  }
  if( Src && Src != &ValueKey->Data )
  {
    if( (_BYTE)v41 == 1 )
      ExFreePoolWithTag(Src, 0);
    else
      KeyHive->ReleaseCellRoutine(KeyHive, (_HV_GET_CELL_CONTEXT *)v36);
  }
  return v16;
}

Referenced by:

CmEnumerateValueFromLayeredKey
CmEnumerateValueKey
CmEnumerateValueKeyFromMergedView