RegRtlCopyTreeInternal
__int64 __fastcall RegRtlCopyTreeInternal(
VOID *a1,
const WCHAR *a2,
VOID *a3,
const WCHAR *a4,
char arg20,
VOID *a6,
char arg30){
UINT64 PoolWithTag;
unsigned int v9;
VOID **v10;
VOID **v11;
NTSTATUS v14;
unsigned int v15;
unsigned __int64 v16;
UINT64 v17;
unsigned int v18;
unsigned int v19;
NTSTATUS v20;
ULONG v21;
unsigned int v22;
NTSTATUS v23;
VOID **phkResult;
VOID **phkResulta;
VOID *hTransaction;
VOID *hTransactiona;
INT64 a7;
UINT64 *lpRegDisposition;
INT64 a5;
UINT64 KeyNameLength;
VOID *hKey;
UINT64 LengthNeeded;
UINT64 RegDisposition;
VOID *Handle;
UINT64 ResultLength;
VOID *v38;
UINT64 HighLimit;
UINT64 LowLimit;
VOID *v41;
__int64 KeyInformation;
int v43;
v38 = a6;
hKey = 0i64;
Handle = 0i64;
PoolWithTag = 0i64;
LODWORD(ResultLength) = 0;
v9 = 0;
LengthNeeded = 0i64;
v10 = 0i64;
LODWORD(RegDisposition) = 0;
v11 = 0i64;
LODWORD(KeyNameLength) = 0;
a5 = 0i64;
HighLimit = 0i64;
LowLimit = 0i64;
KeyInformation = 0i64;
v43 = 0;
v41 = a3;
IoGetStackLimits(&LowLimit, &HighLimit);
if( (unsigned __int64)&HighLimit - LowLimit < 0x400 )
{
v14 = -1073741670;
goto LABEL_79;
}
v14 = RegRtlOpenKeyTransacted(a1, a2, 8ui64, 0x20019ui64, &hKey, v38);
if( v14 >= 0 )
{
if( !ZwQueryKey(hKey, KeyFlagsInformation, &KeyInformation, 0xCui64, &ResultLength) )
{
if( (KeyInformation & 0x200000000i64) != 0 )
{
v14 = -2147483603;
goto LABEL_79;
}
if( (KeyInformation & 0x100000000i64) != 0 )
v9 = 1;
}
if( !arg20 )
goto LABEL_88;
while( ZwQuerySecurityObject((UINT64)hKey, 4i64, PoolWithTag, (unsigned int)LengthNeeded, (UINT64)&LengthNeeded) == -1073741789 )
{
if( PoolWithTag )
ExFreePoolWithTag((PVOID)PoolWithTag, 0);
PoolWithTag = (UINT64)ExAllocatePoolWithTag(1ui64, (unsigned int)LengthNeeded, 1279739218i64);
if( !PoolWithTag )
{
v14 = -1073741801;
break;
}
}
if( v14 >= 0 )
{
LABEL_88:
LOBYTE(hTransaction) = 0;
v14 = RegRtlCreateKeyTransacted(
v41,
a4,
v9,
393247i64,
(VOID *)(PoolWithTag & -(__int64)(arg20 != 0)),
(INT64)hTransaction,
&Handle,
&RegDisposition,
v38);
if( v14 >= 0 )
{
if( arg20 && PoolWithTag && (_DWORD)RegDisposition == 2 )
ZwSetSecurityObject((UINT64)Handle, 4ui64, PoolWithTag);
if( (unsigned int)RegRtlQueryInfoKey(hKey, 0i64, (unsigned int *)&KeyNameLength, 0i64, &a5, (_DWORD *)&a5 + 1) )
{
LODWORD(v16) = 0;
LODWORD(v17) = 0;
}
else
{
v15 = KeyNameLength;
if( (unsigned int)KeyNameLength <= (unsigned int)a5 )
v15 = a5;
if( v15 )
{
if( v15 + 1 < v15 )
{
v14 = -1073741675;
v15 = -1;
}
else
{
v14 = 0;
++v15;
}
if( v14 < 0 )
goto LABEL_79;
}
v16 = 2i64 * v15;
if( v16 > 0xFFFFFFFF )
{
v14 = -1073741675;
goto LABEL_79;
}
LODWORD(v17) = HIDWORD(a5);
v14 = 0;
}
if( !(_DWORD)v16 || (v10 = ExAllocatePoolWithTag(1ui64, (unsigned int)v16, 1279739218i64)) != 0i64 )
{
if( !(_DWORD)v17 || (v11 = ExAllocatePoolWithTag(1ui64, (unsigned int)v17, 1279739218i64)) != 0i64 )
{
v18 = 0;
LABEL_40:
LODWORD(a5) = v18;
while( 1 )
{
v19 = (unsigned int)v16 >> 1;
LODWORD(KeyNameLength) = (unsigned int)v16 >> 1;
v20 = RegRtlEnumKey(
hKey,
v18,
(WCHAR *)v10,
&KeyNameLength,
(INT64)phkResult,
(INT64)hTransactiona,
a7,
(INT64)lpRegDisposition);
if( v20 == -2147483622 )
break;
if( v20 != -1073741789 )
{
if( !v20 )
{
*((_WORD *)v10 + ((unsigned __int64)(unsigned int)v16 >> 1) - 1) = 0;
v20 = RegRtlCopyTreeInternal(hKey, (const WCHAR *)v10, Handle, (const WCHAR *)v10, arg20, v38, arg30);
if( !v20 || v20 == -2147483603 )
{
v18 = a5 + 1;
goto LABEL_40;
}
}
v14 = v20;
break;
}
v16 = 2i64 * (unsigned int)KeyNameLength;
if( v16 > 0xFFFFFFFF )
{
LABEL_52:
v14 = -1073741675;
goto LABEL_75;
}
v14 = 0;
if( v10 )
ExFreePoolWithTag(v10, 0);
v10 = ExAllocatePoolWithTag(1ui64, (unsigned int)v16, 1279739218i64);
if( !v10 )
{
LABEL_73:
v14 = -1073741801;
goto LABEL_75;
}
v18 = a5;
}
if( v14 >= 0 )
{
LODWORD(KeyNameLength) = 0;
v21 = 0;
while( 1 )
{
a5 = __PAIR64__(v17, v19);
v23 = RegRtlEnumValue((_HANDLE)hKey, v21, v10, (INT64)&a5, (char *)&LengthNeeded + 4, (INT64)v11);
if( v23 == -2147483622 )
break;
if( v23 == -1073741789 )
{
if( (unsigned int)a5 > v19 )
{
v16 = 2i64 * (unsigned int)a5;
if( v16 > 0xFFFFFFFF )
goto LABEL_52;
v14 = 0;
if( v10 )
ExFreePoolWithTag(v10, 0);
v10 = ExAllocatePoolWithTag(1ui64, (unsigned int)v16, 1279739218i64);
if( !v10 )
goto LABEL_73;
}
if( HIDWORD(a5) > (unsigned int)v17 )
{
v17 = HIDWORD(a5);
if( v11 )
ExFreePoolWithTag(v11, 0);
v11 = ExAllocatePoolWithTag(1ui64, v17, 1279739218i64);
if( !v11 )
goto LABEL_38;
}
}
else
{
if( v23
|| (v22 = HIDWORD(LengthNeeded),
*((_WORD *)v10 + ((unsigned __int64)(unsigned int)v16 >> 1) - 1) = 0,
LODWORD(phkResulta) = HIDWORD(a5),
(v23 = RegRtlSetValue(Handle, (const wchar_t *)v10, v22, v11, (UINT64)phkResulta)) != 0) )
{
v14 = v23;
break;
}
LODWORD(KeyNameLength) = KeyNameLength + 1;
}
v21 = KeyNameLength;
v19 = (unsigned int)v16 >> 1;
}
}
LABEL_75:
if( v11 )
ExFreePoolWithTag(v11, 0);
}
else
{
LABEL_38:
v14 = -1073741801;
}
if( v10 )
ExFreePoolWithTag(v10, 0);
}
else
{
v14 = -1073741801;
}
}
}
}
LABEL_79:
if( hKey )
ZwClose((_HANDLE)hKey);
if( Handle )
ZwClose((_HANDLE)Handle);
if( PoolWithTag )
ExFreePoolWithTag((PVOID)PoolWithTag, 0);
return(unsigned int)v14;
}Referenced by:
PiDevCfgConfigureDeviceFilters
PiDevCfgConfigureSoftwareDevices
PnpCtxRegCopyTree
RegRtlCopyTreeInternal