CmpCloneHwProfile

INT64 __stdcall CmpCloneHwProfile(
        PVOID IDConfigDB,
        PVOID Parent,
        PVOID OldProfile,
        UINT64 OldProfileNumber,
        UINT16 DockingState,
        PVOID *NewProfile,
        UINT64 *NewProfileNumber){
  VOID *v8; 
  int v10; 
  INT64 v11; 
  NTSTATUS Key; 
  VOID **PoolWithTag; 
  INT64 v14; 
  unsigned int v15; 
  unsigned int v16; 
  unsigned int v17; 
  INT64 v18; 
  _UNICODE_STRING *v19; 
  VOID *v20; 
  PVOID v21; 
  __int64 v22; 
  __int64 v23; 
  __int64 v24; 
  __int64 v25; 
  UINT64 *LengthNeeded; 
  UINT64 *LengthNeededa; 
  UINT64 *LengthNeededb; 
  UINT64 CreateOptions; 
  UINT64 CreateOptionsa; 
  INT64 CreateOptionsb; 
  UINT64 CreateOptionsc; 
  UINT64 CreateOptionsd; 
  UINT64 CreateOptionsg; 
  UINT64 CreateOptionse; 
  INT64 CreateOptionsf; 
  UINT64 *Disposition; 
  UINT64 *Dispositiona; 
  UINT64 *Dispositionb; 
  INT64 v41; 
  INT64 v42; 
  unsigned int Data; 
  _UNICODE_STRING ValueName; 
  UINT64 NumberOfBytes; 
  UINT64 v46; 
  PVOID Object; 
  UINT64 ResultLength; 
  VOID *Handle; 
  UINT64 v50; 
  _UNICODE_STRING UnicodeString; 
  _OBJECT_ATTRIBUTES ObjectAttributes; 
  _UNICODE_STRING GuidString; 
  _UNICODE_STRING DestinationString; 
  _QWORD a1[2]; 
  UUID Uuid; 
  int KeyInformation[2]; 
  unsigned int v58; 
  unsigned int v59; 
  __int16 Str[2]; 
  unsigned int v61; 
  WCHAR Dst[64]; 

  Object = OldProfile;
  LODWORD(NumberOfBytes) = 0;
  *NewProfile = 0i64;
  *(_DWORD *)NewProfileNumber = OldProfileNumber;
  v8 = OldProfile;
  v46 = 0i64;
  DestinationString = 0i64;
  ResultLength = 0i64;
  ValueName = 0i64;
  Data = 0;
  UnicodeString = 0i64;
  GuidString = 0i64;
  v50 = 0i64;
  memset(&ObjectAttributes, 0, sizeof(ObjectAttributes));
  Handle = 0i64;
  Uuid = 0i64;
  *(_OWORD *)a1 = 0i64;
  CmpInitializeDelayDerefContext(a1);
  v10 = *(_DWORD *)NewProfileNumber;
  if( *(_DWORD *)NewProfileNumber >= 0xC8u )
    goto LABEL_8;
  while( 1 )
  {
    *(_DWORD *)NewProfileNumber = v10 + 1;
    swprintf_s(Dst, 0x40ui64, (WCHAR *)L"%04d");
    RtlInitUnicodeString(&DestinationString, Dst);
    ObjectAttributes.Length = 48;
    ObjectAttributes.ObjectName = &DestinationString;
    ObjectAttributes.RootDirectory = Parent;
    ObjectAttributes.Attributes = 576;
    *(_OWORD *)&ObjectAttributes.SecurityDescriptor = 0i64;
    Key = ZwOpenKey(
            NewProfile,
            0x2001Fui64,
            &ObjectAttributes,
            v11,
            (INT64)LengthNeeded,
            CreateOptions,
            (INT64)Disposition,
            v41);
    if( Key < 0 )
      break;
    ZwClose((_HANDLE)*NewProfile);
    v10 = *(_DWORD *)NewProfileNumber;
    if( *(_DWORD *)NewProfileNumber >= 0xC8u )
      goto LABEL_7;
  }
  if( Key == -1073741772 )
    Key = 0;
LABEL_7:
  if( Key >= 0 )
  {
LABEL_8:
    if( ZwQuerySecurityObject((UINT64)v8, 4i64, 0i64, 0i64, (UINT64)&NumberOfBytes) == -1073741789 )
    {
      PoolWithTag = ExAllocatePoolWithTag(1ui64, (unsigned int)NumberOfBytes, 538987843i64);
      if( !PoolWithTag
        || ZwQuerySecurityObject(
             (UINT64)v8,
             4i64,
             (UINT64)PoolWithTag,
             (unsigned int)NumberOfBytes,
             (UINT64)&NumberOfBytes) >= 0 )
      {
        goto LABEL_13;
      }
      ExFreePoolWithTag(PoolWithTag, 0);
    }
    PoolWithTag = 0i64;
LABEL_13:
    ObjectAttributes.RootDirectory = Parent;
    ObjectAttributes.ObjectName = &DestinationString;
    ObjectAttributes.Length = 48;
    LODWORD(CreateOptions) = 0;
    ObjectAttributes.Attributes = 576;
    ObjectAttributes.SecurityDescriptor = PoolWithTag;
    ObjectAttributes.SecurityQualityOfService = 0i64;
    Key = ZwCreateKey(NewProfile, 0x2001Fui64, &ObjectAttributes, 0i64, 0i64, CreateOptions, &ResultLength);
    if( PoolWithTag )
      ExFreePoolWithTag(PoolWithTag, 0);
    if( Key >= 0 )
    {
      if( (_DWORD)ResultLength == 1 )
      {
        swprintf_s(Dst, 0x40ui64, (WCHAR *)L"Hardware Profiles\\%04d", *(unsigned int *)NewProfileNumber);
        RtlInitUnicodeString(&ValueName, Dst);
        ObjectAttributes.RootDirectory = IDConfigDB;
        ObjectAttributes.ObjectName = &ValueName;
        ObjectAttributes.Attributes = 576;
        LODWORD(CreateOptionsa) = 0;
        ObjectAttributes.Length = 48;
        *(_OWORD *)&ObjectAttributes.SecurityDescriptor = 0i64;
        Key = ZwCreateKey((VOID **)&v46, 0x2001Fui64, &ObjectAttributes, 0i64, 0i64, CreateOptionsa, &ResultLength);
        if( Key >= 0 )
        {
          RtlInitUnicodeString(&ValueName, L"Hardware Profiles");
          ObjectAttributes.Length = 48;
          ObjectAttributes.ObjectName = &ValueName;
          ObjectAttributes.RootDirectory = IDConfigDB;
          ObjectAttributes.Attributes = 576;
          *(_OWORD *)&ObjectAttributes.SecurityDescriptor = 0i64;
          Key = ZwOpenKey(
                  (VOID **)&v50,
                  0x20019ui64,
                  &ObjectAttributes,
                  v14,
                  (INT64)LengthNeededa,
                  CreateOptionsb,
                  (INT64)Dispositiona,
                  v41);
          if( Key >= 0 )
          {
            Key = ZwQueryKey(
                    (VOID *)v50,
                    KeyFullInformation,
                    KeyInformation,
                    0x100ui64,
                    (UINT64 *)((char *)&ResultLength + 4));
            if( Key >= 0 )
            {
              v15 = v61;
              v16 = -1;
              Data = -1;
              v17 = 0;
              if( v61 )
              {
                do
                {
                  LODWORD(LengthNeededb) = 254;
                  if( ZwEnumerateKey(
                         (VOID *)v50,
                         v17,
                         KeyBasicInformation,
                         KeyInformation,
                         (UINT64)LengthNeededb,
                         (UINT64 *)((char *)&ResultLength + 4)) < 0 )
                    break;
                  Str[(unsigned __int64)v59 >> 1] = 0;
                  if( wtoi((const wchar_t *)Str) && wtoi((const wchar_t *)Str) != *(_DWORD *)NewProfileNumber )
                  {
                    ValueName.Length = v59;
                    ObjectAttributes.Length = 48;
                    ValueName.MaximumLength = v59 + 2;
                    ObjectAttributes.Attributes = 576;
                    ValueName.Buffer = (wchar_t *)Str;
                    ObjectAttributes.RootDirectory = (void *)v50;
                    ObjectAttributes.ObjectName = &ValueName;
                    *(_OWORD *)&ObjectAttributes.SecurityDescriptor = 0i64;
                    if( ZwOpenKey(
                           &Handle,
                           0x20019ui64,
                           &ObjectAttributes,
                           v18,
                           (INT64)LengthNeededb,
                           CreateOptionsc,
                           (INT64)Dispositionb,
                           v42) >= 0 )
                    {
                      RtlInitUnicodeString(&ValueName, L"PreferenceOrder");
                      LODWORD(LengthNeededb) = 256;
                      if( ZwQueryValueKey(
                             Handle,
                             &ValueName,
                             KeyValueFullInformation,
                             KeyInformation,
                             (UINT64)LengthNeededb,
                             (UINT64 *)((char *)&ResultLength + 4)) >= 0
                        && KeyInformation[1] == 4
                        && (*(int *)((char *)KeyInformation + v58) > Data || Data == -1) )
                      {
                        Data = *(int *)((char *)KeyInformation + v58);
                      }
                      ZwClose((_HANDLE)Handle);
                    }
                    Handle = 0i64;
                  }
                  ++v17;
                }
                while( v17 < v15 );
                v16 = Data;
                v8 = Object;
              }
              Data = v16 + 1;
              RtlInitUnicodeString(&ValueName, L"PreferenceOrder");
              LODWORD(CreateOptionsc) = 4;
              ZwSetValueKey((VOID *)v46, &ValueName, 0i64, 4ui64, &Data, CreateOptionsc);
              if( (int)CmpCreateHwProfileFriendlyName(
                          IDConfigDB,
                          DockingState,
                          *(unsigned int *)NewProfileNumber,
                          &UnicodeString) >= 0 )
              {
                RtlInitUnicodeString(&ValueName, L"FriendlyName");
                LODWORD(CreateOptionsd) = UnicodeString.Length + 2;
                ZwSetValueKey((VOID *)v46, &ValueName, 0i64, 1ui64, UnicodeString.Buffer, CreateOptionsd);
                RtlFreeAnsiString(&UnicodeString);
              }
              Data = 0;
              RtlInitUnicodeString(&ValueName, L"Aliasable");
              LODWORD(CreateOptionsd) = 4;
              ZwSetValueKey((VOID *)v46, &ValueName, 0i64, 4ui64, &Data, CreateOptionsd);
              Data = 1;
              RtlInitUnicodeString(&ValueName, L"Cloned");
              LODWORD(CreateOptionsg) = 4;
              ZwSetValueKey((VOID *)v46, &ValueName, 0i64, 4ui64, &Data, CreateOptionsg);
              if( ExUuidCreate(&Uuid) >= 0 && RtlStringFromGUID(&Uuid, &GuidString, v19) >= 0 )
              {
                RtlInitUnicodeString(&ValueName, L"HwProfileGuid");
                LODWORD(CreateOptionse) = GuidString.MaximumLength;
                ZwSetValueKey((VOID *)v46, &ValueName, 0i64, 1ui64, GuidString.Buffer, CreateOptionse);
                RtlFreeAnsiString(&GuidString);
              }
              *(_QWORD *)&UnicodeString.Length = 0i64;
              Key = ObReferenceObjectByHandle(
                      v8,
                      0x20019ui64,
                      (_OBJECT_TYPE *)CmKeyObjectType,
                      0,
                      (VOID **)&UnicodeString,
                      0i64);
              if( Key >= 0 )
              {
                v20 = *NewProfile;
                Object = 0i64;
                Key = ObReferenceObjectByHandle(v20, 0x20006ui64, (_OBJECT_TYPE *)CmKeyObjectType, 0, &Object, 0i64);
                if( Key >= 0 )
                {
                  CmpLockRegistryExclusive();
                  v21 = Object;
                  v22 = *(_QWORD *)&UnicodeString.Length;
                  LODWORD(CreateOptionsf) = 0;
                  if( CmpCopySyncTree(
                         *(_QWORD *)(*(_QWORD *)(*(_QWORD *)&UnicodeString.Length + 8i64) + 32i64),
                         *(unsigned int *)(*(_QWORD *)(*(_QWORD *)&UnicodeString.Length + 8i64) + 40i64),
                         *(_QWORD *)(*((_QWORD *)Object + 1) + 32i64),
                         *(unsigned int *)(*((_QWORD *)Object + 1) + 40i64),
                         2,
                         CreateOptionsf) )
                  {
                    *(_DWORD *)(&UnicodeString.MaximumLength + 1) = 0;
                    v23 = *(_QWORD *)(v22 + 8);
                    Object = (PVOID)0xFFFFFFFFi64;
                    *(_DWORD *)&UnicodeString.Length = -1;
                    v24 = (*(__int64(__fastcall **)(_QWORD, _QWORD, PVOID *))(*(_QWORD *)(v23 + 32) + 8i64))(
                            *(_QWORD *)(v23 + 32),
                            *(unsigned int *)(v23 + 40),
                            &Object);
                    if( v24 )
                    {
                      v25 = (*(__int64(__fastcall **)(_QWORD, _QWORD, _UNICODE_STRING *))(*(_QWORD *)(*((_QWORD *)v21 + 1) + 32i64)
                                                                                         + 8i64))(
                              *(_QWORD *)(*((_QWORD *)v21 + 1) + 32i64),
                              *(unsigned int *)(*((_QWORD *)v21 + 1) + 40i64),
                              &UnicodeString);
                      if( v25 )
                      {
                        *(_WORD *)(v25 + 52) = *(_WORD *)(v24 + 52);
                        *(_DWORD *)(v25 + 56) = *(_DWORD *)(v24 + 56);
                        CmpRebuildKcbCache(*((PVOID *)v21 + 1), (__int64)a1);
                        (*(void(__fastcall **)(_QWORD, _UNICODE_STRING *))(*(_QWORD *)(*((_QWORD *)v21 + 1) + 32i64)
                                                                          + 16i64))(
                          *(_QWORD *)(*((_QWORD *)v21 + 1) + 32i64),
                          &UnicodeString);
                        Key = 0;
                      }
                      else
                      {
                        Key = -1073741670;
                      }
                      (*(void(__fastcall **)(_QWORD, PVOID *))(*(_QWORD *)(*(_QWORD *)(v22 + 8) + 32i64) + 16i64))(
                        *(_QWORD *)(*(_QWORD *)(v22 + 8) + 32i64),
                        &Object);
                    }
                    else
                    {
                      Key = -1073741670;
                    }
                  }
                  else
                  {
                    Key = -1073741492;
                  }
                  CmpDrainDelayDerefContext((UINT64 **)a1);
                  CmpUnlockRegistry();
                }
              }
            }
          }
          else
          {
            v50 = 0i64;
          }
        }
        else
        {
          v46 = 0i64;
        }
      }
      else
      {
        Key = 0;
      }
    }
  }
  ZwClose((_HANDLE)v8);
  if( v46 )
    ZwClose(v46);
  if( v50 )
    ZwClose(v50);
  if( Key < 0 && *NewProfile )
    ZwClose((_HANDLE)*NewProfile);
  return(unsigned int)Key;
}

Referenced by:

CmSetAcpiHwProfile
CmpCreateHardwareProfiles