PiDrvDbOverlayCopyKeys

NTSTATUS __stdcall PiDrvDbOverlayCopyKeys(
        VOID *a1,
        const WCHAR *a2,
        VOID *a3,
        const WCHAR *a4,
        INT64 a5,
        const WCHAR **arg28,
        UINT64 arg30,
        VOID *arg38){
  unsigned int v10; 
  VOID **PoolWithTag; 
  VOID **v12; 
  NTSTATUS v13; 
  NTSTATUS v14; 
  __int64 v15; 
  ULONG v16; 
  unsigned int v17; 
  unsigned int v18; 
  unsigned int i; 
  NTSTATUS v20; 
  __int64 v21; 
  unsigned int v22; 
  __int64 v23; 
  unsigned int v24; 
  const wchar_t **v25; 
  __int64 v26; 
  __int16 v27; 
  unsigned int v28; 
  VOID *v29; 
  NTSTATUS v30; 
  unsigned int v31; 
  NTSTATUS v32; 
  UINT64 v33; 
  UINT64 *ResultLength; 
  UINT64 *ResultLengtha; 
  UINT64 *ResultLengthb; 
  INT64 a6; 
  INT64 a7; 
  INT64 a8; 
  unsigned int v41; 
  unsigned int NumberOfBytes; 
  unsigned int NumberOfBytes_4; 
  INT64 v44; 
  _HANDLE v45[3]; 
  VOID *Handle; 
  unsigned int v47; 
  int v48; 
  INT64 v49; 
  VOID *KeyHandle; 
  PVOID P; 
  const WCHAR **v52; 
  VOID *v53; 
  __int64 KeyInformation; 
  int v55; 

  v52 = arg28;
  v10 = 0;
  v53 = arg38;
  PoolWithTag = 0i64;
  KeyInformation = 0i64;
  v55 = 0;
  v12 = 0i64;
  KeyHandle = 0i64;
  P = 0i64;
  Handle = 0i64;
  v48 = 0;
  v49 = 0i64;
  v41 = 0;
  v44 = 0i64;
  NumberOfBytes = 0;
  memset(v45, 0, sizeof(v45));
  v47 = arg30;
  v13 = SysCtxRegOpenKey(0i64, a1, a2, 8u, 0x20019u, (VOID **)&v45[1]);
  if( v13 >= 0 )
  {
    if( ZwQueryKey(*(VOID **)&v45[1], KeyFlagsInformation, &KeyInformation, 0xCui64, (UINT64 *)v45) >= 0 )
    {
      if( (KeyInformation & 0x200000000i64) != 0 )
      {
        v13 = -2147483603;
        goto LABEL_85;
      }
      if( (KeyInformation & 0x100000000i64) != 0 )
        v10 = 1;
    }
    LODWORD(ResultLength) = 393247;
    v14 = PnpCtxRegCreateKey(0i64, a3, (WCHAR *)a4, v10, (UINT64)ResultLength, 0i64, &KeyHandle, (UINT64 *)&v49);
    v16 = 0;
    v13 = v14;
    if( v14 >= 0 )
    {
      if( (int)PnpCtxRegQueryInfoKey(v15, *(VOID **)&v45[1], 0i64, &v41, 0i64, &v44, &NumberOfBytes) < 0 )
      {
        v18 = 0;
      }
      else
      {
        v17 = v44;
        if( v41 > (unsigned int)v44 )
          v17 = v41;
        v18 = 2 * v17 + 2;
        HIDWORD(v44) = v18;
        if( 2 * v17 != -2 )
        {
          PoolWithTag = ExAllocatePoolWithTag(1ui64, v18, 1650749520i64);
          if( !PoolWithTag )
          {
            v13 = -1073741670;
            goto LABEL_85;
          }
        }
      }
      if( (!NumberOfBytes || (v12 = ExAllocatePoolWithTag(1ui64, NumberOfBytes, 1650749520i64)) != 0i64)
        && (!v52
         || !(_DWORD)arg30
         || (P = ExAllocatePoolWithTag(1ui64, 8i64 * (unsigned int)arg30, 1650749520i64)) != 0i64) )
      {
        for( i = 0; ; ++i )
        {
          LODWORD(v44) = i;
          NumberOfBytes_4 = v18 >> 1;
          v20 = RegRtlEnumKey(
                  *(VOID **)&v45[1],
                  i,
                  (WCHAR *)PoolWithTag,
                  (UINT64 *)&NumberOfBytes_4,
                  (INT64)ResultLengtha,
                  a6,
                  a7,
                  a8);
          if( v20 == -2147483622 )
            goto LABEL_60;
          if( v20 == -1073741789 )
          {
            v18 = 2 * NumberOfBytes_4;
            HIDWORD(v44) = 2 * NumberOfBytes_4;
            if( PoolWithTag )
              ExFreePoolWithTag(PoolWithTag, 0);
            PoolWithTag = ExAllocatePoolWithTag(1ui64, v18, 1650749520i64);
            if( PoolWithTag )
            {
              --i;
              continue;
            }
LABEL_58:
            v13 = -1073741670;
            goto LABEL_81;
          }
          if( v20 < 0 )
            goto LABEL_59;
          v22 = 0;
          v41 = 0;
          if( !v52 )
            goto LABEL_44;
          v23 = NumberOfBytes_4;
          if( !NumberOfBytes_4 )
            goto LABEL_43;
          v24 = 0;
          if( !v47 )
            goto LABEL_42;
          v25 = v52;
          while( wcsnicmp(*v25, (const wchar_t *)PoolWithTag, v23 - 1) )
          {
LABEL_38:
            ++v24;
            ++v25;
            if( v24 >= v47 )
              goto LABEL_41;
          }
          v26 = (__int64)&(*v25)[v23];
          v27 = *(_WORD *)(v26 - 2);
          if( v27 )
            break;
          LODWORD(v23) = 0;
LABEL_41:
          i = v44;
          v22 = v41;
LABEL_42:
          v18 = HIDWORD(v44);
          if( !(_DWORD)v23 )
          {
            v16 = 0;
            continue;
          }
LABEL_43:
          v16 = 0;
LABEL_44:
          if( !v53 )
            goto LABEL_51;
          v20 = SysCtxRegOpenKey(0i64, v53, (const WCHAR *)PoolWithTag, 0, 0x20019u, &Handle);
          if( v20 == -1073741772 )
          {
            Handle = 0i64;
            continue;
          }
          if( v20 < 0 )
          {
LABEL_59:
            v13 = v20;
LABEL_60:
            if( v13 >= 0 )
            {
              v31 = NumberOfBytes;
              while( 1 )
              {
                NumberOfBytes_4 = v18 >> 1;
                NumberOfBytes = v31;
                v32 = PnpCtxRegEnumValue(
                        v21,
                        v45[1],
                        v16,
                        PoolWithTag,
                        (INT64)&NumberOfBytes_4,
                        (char *)&v49 + 4,
                        (INT64)v12);
                if( v32 == -2147483622 )
                  break;
                if( v32 == -1073741789 )
                {
                  if( NumberOfBytes_4 > v18 >> 1 )
                  {
                    v18 = 2 * NumberOfBytes_4;
                    if( PoolWithTag )
                      ExFreePoolWithTag(PoolWithTag, 0);
                    PoolWithTag = ExAllocatePoolWithTag(1ui64, v18, 1650749520i64);
                    if( !PoolWithTag )
                      goto LABEL_58;
                  }
                  v33 = NumberOfBytes;
                  if( NumberOfBytes > v31 )
                  {
                    v31 = NumberOfBytes;
                    if( v12 )
                      ExFreePoolWithTag(v12, 0);
                    v12 = ExAllocatePoolWithTag(1ui64, v33, 1650749520i64);
                    if( !v12 )
                      goto LABEL_17;
                  }
                  --v16;
                }
                else
                {
                  if( v32 < 0 )
                  {
                    v13 = v32;
                    goto LABEL_79;
                  }
                  if( (_DWORD)v49 != 2
                    || (v45[0] = 0,
                        (unsigned int)RegRtlQueryValue(
                                        KeyHandle,
                                        (const wchar_t *)PoolWithTag,
                                        0i64,
                                        0i64,
                                        (__int64)v45) != -1073741789) )
                  {
                    LODWORD(ResultLengthb) = NumberOfBytes;
                    v13 = RegRtlSetValue(
                            KeyHandle,
                            (const wchar_t *)PoolWithTag,
                            HIDWORD(v49),
                            v12,
                            (UINT64)ResultLengthb);
                    if( v13 < 0 )
                      goto LABEL_79;
                  }
                }
                ++v16;
              }
            }
            goto LABEL_79;
          }
          v13 = PnpCtxRegQueryInfoKey(v21, Handle, &v48, 0i64, 0i64, 0i64, 0i64);
          if( v13 < 0 )
            goto LABEL_60;
          if( !v48 )
          {
            ZwClose((_HANDLE)Handle);
            v29 = 0i64;
            Handle = 0i64;
            goto LABEL_52;
          }
LABEL_51:
          v29 = Handle;
LABEL_52:
          LODWORD(a7) = v22;
          LODWORD(ResultLengtha) = 0;
          v30 = PiDrvDbOverlayCopyKeys(
                  *(VOID **)&v45[1],
                  (const WCHAR *)PoolWithTag,
                  KeyHandle,
                  (const WCHAR *)PoolWithTag,
                  (INT64)ResultLengtha,
                  (const WCHAR **)((unsigned __int64)P & -(__int64)(v22 != 0)),
                  a7,
                  v29);
          v13 = v30;
          if( v30 == -2147483603 )
          {
            v13 = 0;
            continue;
          }
          if( v30 < 0 )
            goto LABEL_79;
        }
        if( v27 == 92 && P )
        {
          v28 = v41;
          *((_QWORD *)P + v41) = v26;
          v41 = v28 + 1;
        }
        goto LABEL_38;
      }
LABEL_17:
      v13 = -1073741670;
LABEL_79:
      if( PoolWithTag )
        ExFreePoolWithTag(PoolWithTag, 0);
LABEL_81:
      if( v12 )
        ExFreePoolWithTag(v12, 0);
      if( P )
        ExFreePoolWithTag(P, 0);
    }
  }
LABEL_85:
  if( *(_QWORD *)&v45[1] )
    ZwClose(v45[1]);
  if( KeyHandle )
    ZwClose((_HANDLE)KeyHandle);
  if( Handle )
    ZwClose((_HANDLE)Handle);
  return v13;
}

Referenced by:

PiDrvDbOverlayCopyKeys
PiDrvDbOverlayNodeHive