VrpLoadDifferencingHive

NTSTATUS __stdcall VrpLoadDifferencingHive(
        UNICODE_STRING *TargetKeyPath,
        UNICODE_STRING *TargetHivePath,
        UNICODE_STRING *NextLayerKeyPath,
        INT64 NextLayerIsHost,
        UINT64 LoadFlags,
        PVOID *LoadedDiffHive){
  char v8; 
  HANDLE v9; 
  int v10; 
  NTSTATUS DiffHiveEntryForMountPoint; 
  _DWORD *v12; 
  char v13; 
  unsigned int i; 
  HANDLE LowerLayerKey; 
  UINT64 DesiredAccess; 
  HANDLE Handle; 
  _OWORD KeyHandle[4]; 
  struct _OBJECT_ATTRIBUTES v20; 
  _OBJECT_ATTRIBUTES SourceFile; 
  _OBJECT_ATTRIBUTES TargetKey; 
  unsigned int Flags; 
  int v26; 
  Flags = NextLayerIsHost;
  v8 = 0;
  v9 = 0i64;
  Handle = 0i64;
  memset(&SourceFile, 0, sizeof(SourceFile));
  memset(KeyHandle, 0, sizeof(KeyHandle));
  memset(&v20, 0, sizeof(v20));
  memset(&TargetKey, 0, sizeof(TargetKey));
  if( !v26 )
  {
LABEL_6:
    DiffHiveEntryForMountPoint = VrpFindOrCreateDiffHiveEntryForMountPoint(TargetKeyPath);
    v12 = (_DWORD *)*((_QWORD *)&KeyHandle[0] + 1);
    v10 = DiffHiveEntryForMountPoint;
    if( DiffHiveEntryForMountPoint < 0 )
      goto LABEL_31;
    VrpLockDiffHiveEntry(*((INT64 *)&KeyHandle[0] + 1));
    VrpIncrementDiffHiveEntryHardRefCount((INT64)v12);
    v13 = 1;
    if( (v12[14] & 1) != 0 )
    {
      v10 = 0;
LABEL_30:
      VrpUnlockDiffHiveEntry((INT64)v12);
LABEL_31:
      if( v12 )
        VrpDereferenceDiffHiveEntry(v12);
      goto LABEL_33;
    }
    for( i = 0; i < 2; ++i )
    {
      if( (v12[14] & 1) != 0 )
        break;
      v8 = VrpBecomeDiffHiveEntryTransitionOwner((__int64)v12);
      if( v8 )
        goto LABEL_15;
      VrpWaitForDiffHiveEntryTransitionOwnerToLeave((INT64)v12);
    }
    if( (v12[14] & 1) == 0 )
    {
      v10 = v12[15];
      goto LABEL_29;
    }
LABEL_15:
    if( (v12[14] & 1) != 0 )
    {
LABEL_25:
      v10 = 0;
      v13 = 0;
LABEL_26:
      if( v8 )
        VrpRelinquishDiffHiveEntryTransitionOwner((INT64)v12);
      if( !v13 )
        goto LABEL_30;
LABEL_29:
      VrpDecrementDiffHiveEntryHardRefCount((INT64)v12);
      goto LABEL_30;
    }
    VrpUnlockDiffHiveEntry((INT64)v12);
    if( NextLayerKeyPath->Length )
    {
      v20.Length = 48;
      v20.RootDirectory = 0i64;
      v20.Attributes = 576;
      v20.ObjectName = NextLayerKeyPath;
      *(_OWORD *)&v20.SecurityDescriptor = 0i64;
      v10 = ZwOpenKey(&Handle, 0x20019u, &v20);
      if( v10 < 0 )
        goto LABEL_24;
      LowerLayerKey = Handle;
      if( (_DWORD)LoadFlags )
        v9 = Handle;
    }
    else
    {
      LowerLayerKey = Handle;
    }
    TargetKey.ObjectName = TargetKeyPath;
    TargetKey.Length = 48;
    SourceFile.Length = 48;
    SourceFile.ObjectName = TargetHivePath;
    TargetKey.Attributes = 576;
    SourceFile.Attributes = 576;
    LODWORD(DesiredAccess) = 0;
    TargetKey.RootDirectory = 0i64;
    *(_OWORD *)&TargetKey.SecurityDescriptor = 0i64;
    SourceFile.RootDirectory = 0i64;
    *(_OWORD *)&SourceFile.SecurityDescriptor = 0i64;
    v10 = CmLoadDifferencingKey(
            &TargetKey,
            &SourceFile,
            Flags,
            v9,
            0i64,
            DesiredAccess,
            0i64,
            0i64,
            LowerLayerKey,
            (_DWORD)LoadedDiffHive != 0);
    if( v10 >= 0 )
      v10 = 0;
LABEL_24:
    VrpLockDiffHiveEntry((INT64)v12);
    v12[14] = v12[14] & 0xFFFFFFFE | (v10 >= 0);
    v12[15] = v10;
    if( v10 < 0 )
      goto LABEL_26;
    goto LABEL_25;
  }
  if( (_DWORD)LoadFlags )
    return -1073741811;
  *((_QWORD *)&KeyHandle[1] + 1) = 0i64;
  LODWORD(KeyHandle[1]) = 48;
  *(_QWORD *)&KeyHandle[2] = L"\"$";
  DWORD2(KeyHandle[2]) = 576;
  KeyHandle[3] = 0i64;
  v10 = ZwOpenKey((PHANDLE)KeyHandle, 0x20019u, (POBJECT_ATTRIBUTES)&KeyHandle[1]);
  if( v10 >= 0 )
  {
    v9 = *(HANDLE *)&KeyHandle[0];
    goto LABEL_6;
  }
LABEL_33:
  if( Handle )
    ZwClose(Handle);
  if( *(_QWORD *)&KeyHandle[0] )
    ZwClose(*(HANDLE *)&KeyHandle[0]);
  return v10;
}

Referenced by:

VrpHandleIoctlLoadDifferencingHive
VrpHandleIoctlLoadDifferencingHiveForHost