HvpFindNextDirtyBlock

INT64 __fastcall HvpFindNextDirtyBlock(
        _HHIVE *Hive,
        _RTL_BITMAP *DirtyVector,
        UINT64 *Current,
        UINT8 **Address,
        UINT64 *Length,
        UINT64 *Offset,
        INT64 Allocate){
  UINT8 *PoolWithTag; 
  INT64 result; 
  unsigned int v11; 
  unsigned int v12; 
  _BYTE *CellMap; 
  __int64 FreeBin; 
  _QWORD *v15; 
  int v16; 
  int v17; 
  unsigned __int64 v18; 
  UINT8 *v19; 
  int v20; 
  unsigned int v21; 
  unsigned int v22; 
  unsigned int v23; 
  unsigned int v24; 
  int v25; 
  _BYTE *v26; 
  __int64 v27; 
  _QWORD *v28; 
  UINT64 v29; 
  UINT8 *v30; 
  UINT64 *BugCheckParameter4; 
  UINT64 v32; 
  unsigned int v33; 
  int v34; 
  v32 = 0i64;
  PoolWithTag = 0i64;
  if( HvpFindNextDirtyRun(DirtyVector, Current, &v32, (UINT64 *)((char *)&v32 + 4), BugCheckParameter4) )
  {
    v11 = (_DWORD)v32 << 9;
    v12 = (HIDWORD(v32) << 9) - ((_DWORD)v32 << 9);
    v34 = HIDWORD(v32) << 9;
    if( (_BYTE)Allocate && (PoolWithTag = (UINT8 *)ExAllocatePoolWithTag(PagedPool, v12, 0x33354D43ui64)) == 0i64 )
    {
      *Address = 0i64;
      return 1i64;
    }
    else
    {
      CellMap = (_BYTE *)HvpGetCellMap((INT64)Hive, v11);
      if( !CellMap )
        KeBugCheckEx(0x51u, 1ui64, (ULONG_PTR)Hive, v11, 0x1287ui64);
      FreeBin = HvpMapEntryGetFreeBin(CellMap);
      if( FreeBin )
        v18 = (v15[1] & 0xFFFFFFFFFFFFFFF0ui64) + v11 - *(_DWORD *)(FreeBin + 20);
      else
        v18 = *v15 + (v15[1] & 0xFFFFFFFFFFFFFFF0ui64);
      if( (_BYTE)Allocate )
        v19 = PoolWithTag;
      else
        v19 = (UINT8 *)(v18 + (v11 & 0xFFF));
      *Address = v19;
      v20 = v16 & 7;
      v21 = v17 - v16;
      v22 = v17 - v16;
      v33 = v17 - v16;
      *(_DWORD *)Offset = v11 + 4096;
      if( v17 - v16 >= (unsigned int)(8 - v20) )
        v22 = 8 - v20;
      v23 = v22 << 9;
      if( (_BYTE)Allocate )
      {
        memmove(PoolWithTag, (UINT8 *)(v18 + (unsigned int)(v20 << 9)), v23);
        v21 = v33;
        PoolWithTag += v23;
      }
      if( v21 > v22 )
      {
        v24 = (v11 + 4096) & 0xFFFFF000;
        if( v23 < v12 )
        {
          v25 = v34;
          do
          {
            v26 = (_BYTE *)HvpGetCellMap((INT64)Hive, v24);
            if( !v26 )
              KeBugCheckEx(0x51u, 1ui64, (ULONG_PTR)Hive, v24, 0x12F1ui64);
            if( !(_BYTE)Allocate && (v26[8] & 1) != 0 )
              break;
            v27 = HvpMapEntryGetFreeBin(v26);
            if( v27 )
              v30 = (UINT8 *)((v28[1] & 0xFFFFFFFFFFFFFFF0ui64) + v24 - *(_DWORD *)(v27 + 20));
            else
              v30 = (UINT8 *)(*v28 + (v28[1] & 0xFFFFFFFFFFFFFFF0ui64));
            if( v25 - v24 <= (unsigned int)v29 )
            {
              if( (_BYTE)Allocate )
                memmove(PoolWithTag, v30, v25 - v24);
              goto LABEL_13;
            }
            if( (_BYTE)Allocate )
            {
              memmove(PoolWithTag, v30, v29);
              LODWORD(v29) = 4096;
              PoolWithTag += 4096;
            }
            v23 += v29;
            v22 += 8;
            v24 += v29;
          }
          while( v23 < v12 );
        }
        *(_DWORD *)Length = v23;
        result = v22 + (unsigned int)v32;
        if( (_DWORD)result != HIDWORD(v32) )
          *(_DWORD *)Current = result;
      }
      else
      {
LABEL_13:
        result = (INT64)Length;
        *(_DWORD *)Length = v12;
      }
      LOBYTE(result) = 1;
    }
  }
  else
  {
    LOBYTE(result) = 0;
  }
  return result;
}

Referenced by:

HvStoreModifiedData
HvWriteHivePrimaryFile
HvpGenerateLogEntryDirtyData