HvpFindNextDirtyBlock

UINT8 __stdcall HvpFindNextDirtyBlock(
        PVOID Hive,
        _RTL_BITMAP *DirtyVector,
        UINT64 *Current,
        UINT8 **Address,
        UINT64 *Length,
        UINT64 *Offset,
        UINT8 Allocate){
  VOID **PoolWithTag; 
  unsigned int v10; 
  unsigned int v11; 
  _HMAP_ENTRY *CellMap; 
  __int64 FreeBin; 
  _QWORD *v14; 
  int v15; 
  int v16; 
  unsigned __int64 v17; 
  UINT8 *v18; 
  int v19; 
  unsigned int v20; 
  unsigned int v21; 
  size_t v22; 
  unsigned int v24; 
  int v25; 
  _HMAP_ENTRY *v26; 
  __int64 v27; 
  _QWORD *v28; 
  size_t v29; 
  const VOID *v30; 
  UINT64 *BugCheckParameter4; 
  UINT64 v32; 
  unsigned int v33; 
  int v34; 

  v32 = 0i64;
  PoolWithTag = 0i64;
  if( !HvpFindNextDirtyRun(DirtyVector, Current, &v32, (UINT64 *)((char *)&v32 + 4), BugCheckParameter4) )
    return 0;
  v10 = (_DWORD)v32 << 9;
  v11 = (HIDWORD(v32) << 9) - ((_DWORD)v32 << 9);
  v34 = HIDWORD(v32) << 9;
  if( Allocate && (PoolWithTag = ExAllocatePoolWithTag(1ui64, v11, 859131203i64)) == 0i64 )
  {
    *Address = 0i64;
    return 1;
  }
  else
  {
    CellMap = HvpGetCellMap((_HHIVE *)Hive, v10);
    if( !CellMap )
      KeBugCheckEx(0x51u, (PVOID)1, Hive, (PVOID)v10, (PVOID)0x1287);
    FreeBin = HvpMapEntryGetFreeBin(CellMap);
    if( FreeBin )
      v17 = (v14[1] & 0xFFFFFFFFFFFFFFF0ui64) + v10 - *(_DWORD *)(FreeBin + 20);
    else
      v17 = *v14 + (v14[1] & 0xFFFFFFFFFFFFFFF0ui64);
    if( Allocate )
      v18 = (UINT8 *)PoolWithTag;
    else
      v18 = (UINT8 *)(v17 + (v10 & 0xFFF));
    *Address = v18;
    v19 = v15 & 7;
    v20 = v16 - v15;
    v21 = v16 - v15;
    v33 = v16 - v15;
    *(_DWORD *)Offset = v10 + 4096;
    if( v16 - v15 >= (unsigned int)(8 - v19) )
      v21 = 8 - v19;
    v22 = v21 << 9;
    if( Allocate )
    {
      memmove(PoolWithTag, (const VOID *)(v17 + (unsigned int)(v19 << 9)), v22);
      v20 = v33;
      PoolWithTag = (VOID **)((char *)PoolWithTag + v22);
    }
    if( v20 > v21 )
    {
      v24 = (v10 + 4096) & 0xFFFFF000;
      if( v22 < v11 )
      {
        v25 = v34;
        do
        {
          v26 = HvpGetCellMap((_HHIVE *)Hive, v24);
          if( !v26 )
            KeBugCheckEx(0x51u, (PVOID)1, Hive, (PVOID)v24, (PVOID)0x12F1);
          if( !Allocate && (v26->PermanentBinAddress & 1) != 0 )
            break;
          v27 = HvpMapEntryGetFreeBin(v26);
          if( v27 )
            v30 = (const VOID *)((v28[1] & 0xFFFFFFFFFFFFFFF0ui64) + v24 - *(_DWORD *)(v27 + 20));
          else
            v30 = (const VOID *)(*v28 + (v28[1] & 0xFFFFFFFFFFFFFFF0ui64));
          if( v25 - v24 <= v29 )
          {
            if( Allocate )
              memmove(PoolWithTag, v30, v25 - v24);
            goto LABEL_13;
          }
          if( Allocate )
          {
            memmove(PoolWithTag, v30, v29);
            v29 = 4096;
            PoolWithTag += 512;
          }
          v22 += v29;
          v21 += 8;
          v24 += v29;
        }
        while( v22 < v11 );
      }
      *(_DWORD *)Length = v22;
      if( v21 + (_DWORD)v32 != HIDWORD(v32) )
        *(_DWORD *)Current = v21 + v32;
    }
    else
    {
LABEL_13:
      *(_DWORD *)Length = v11;
    }
    return 1;
  }
}

Referenced by:

HvStoreModifiedData
HvWriteHivePrimaryFile
HvpGenerateLogEntryDirtyData