PopRequestWrite

char __fastcall PopRequestWrite(INT64 a1, __int64 a2, CHAR a3){
  void *RemainingHibernateRangeDataSize; 
  CHAR v4; 
  __int64 v5; 
  __int64 v6; 
  INT64 v7; 
  int v8; 
  UINT64 v9; 
  __int64 v10; 
  POP_MCB_CONTEXT *v11; 
  _LARGE_INTEGER IoLocation; 
  __int64 v13; 
  UINT64 v14; 
  VOID *Buffer; 
  unsigned __int64 v16; 
  unsigned __int64 v18; 
  unsigned __int64 v19; 
  unsigned __int64 v20; 
  __int64 v21; 
  UINT64 v22; 
  UINT64 Size; 
  unsigned __int64 v24; 
  __int64 v25; 
  unsigned int v26; 
  unsigned __int64 v27; 
  unsigned __int64 v28; 
  void *v29; 
  unsigned __int64 v30; 
  void *v31; 
  unsigned __int64 v32; 
  void *v33; 
  unsigned __int64 v34; 
  __int64 v35; 
  UINT64 MaxTransferLength; 
  __int64 Address[2]; 
  __int64 v39; 
  UINT64 v42; 

  RemainingHibernateRangeDataSize = 0i64;
  v4 = a3;
  v5 = a2;
  v6 = *(_QWORD *)(a1 + 320);
  v7 = a1;
  Address[0] = 0i64;
  MaxTransferLength = 0i64;
  while( 1 )
  {
    while( 1 )
    {
      v8 = *(_DWORD *)(v7 + 328);
      if( !v8 )
        break;
      v18 = __rdtsc();
      v19 = v18;
      if( v8 == 1 )
      {
        v31 = (void *)(*(int(__fastcall **)(__int64, INT64, __int64))(*(_QWORD *)(v7 + 168) + 128i64))(
                        2i64,
                        v7 + 368,
                        v6);
        v32 = __rdtsc();
        *(&stru_140C23628 + 51) += (((unsigned __int64)HIDWORD(v32) << 32) | (unsigned int)v32) - v19;
        if( (int)v31 < 0 )
        {
          PopCheckpointSystemSleep(PopSleepCheckpointHiberWriteFailed);
          PopInternalAddToDumpFile((VOID *)v7, 0x1C8ui64, 0i64);
          PopInternalAddToDumpFile(*(VOID **)(v7 + 168), 0x178ui64, 0i64);
          KeBugCheckEx(0xA0u, (PVOID)0x10A, (PVOID)0xA, (PVOID)v7, v31);
        }
        if( (_DWORD)v31 == 259 )
          return(char)RemainingHibernateRangeDataSize;
        *(_DWORD *)(v7 + 328) = 2;
      }
      else
      {
        *(&stru_140C23628 + 50) += v18 - *(_QWORD *)(v7 + 336);
        ProducerConsumerBufferComplete(v5, v5 + 48, *(_QWORD *)(v7 + 384), *(_DWORD *)(v7 + 360));
        v20 = __rdtsc();
        *(&stru_140C23628 + 55) += (((unsigned __int64)HIDWORD(v20) << 32) | (unsigned int)v20) - v19;
        *(&stru_140C23628 + 108) += *(_QWORD *)(v7 + 360);
        *(&stru_140C23628 + 218) += (unsigned __int64)(*(_QWORD *)(v7 + 352) + 4095i64) >> 12;
        v21 = *(_QWORD *)(v7 + 352);
        *(_QWORD *)(v7 + 376) += v21;
        *(_QWORD *)(v7 + 344) += v21;
        *(_QWORD *)(v7 + 352) = 0i64;
        *(_DWORD *)(v7 + 328) = 0;
      }
    }
    if( (*(&stru_140C23628 + 2676) & 0x1F) == 0 )
      off_140C008C0[0]();
    v9 = *(_QWORD *)(v7 + 376);
    v10 = v7 + 368;
    v11 = *(POP_MCB_CONTEXT **)(v7 + 160);
    ++*(&stru_140C23628 + 669);
    v39 = v7 + 368;
    IoLocation = PopGetIoLocation(v11, v9, &MaxTransferLength);
    v13 = *(unsigned int *)(v7 + 408);
    *(_LARGE_INTEGER *)(v7 + 368) = IoLocation;
    v14 = (v13 << 12) - *(_QWORD *)(v7 + 344) % (unsigned __int64)(v13 << 12);
    if( v14 >= MaxTransferLength )
      v14 = MaxTransferLength;
    v42 = v14;
    Buffer = (VOID *)ConsumerGetBuffer(v5, &v42, v4);
    v16 = (unsigned __int64)Buffer;
    if( !Buffer )
      break;
    v22 = *(_QWORD *)(v7 + 376);
    Size = v42;
    *(_QWORD *)(v7 + 384) = Buffer;
    *(_QWORD *)(v7 + 360) = Size;
    if( v22 + v14 > (unsigned __int64)qword_140C23450 )
    {
      PopCheckpointSystemSleep(PopSleepCheckpointHiberFileTooSmall);
      if( (unsigned int)(*(_DWORD *)(v7 + 184) - 4) <= 1 )
        RemainingHibernateRangeDataSize = (void *)PopGetRemainingHibernateRangeDataSize((_POP_HIBER_CONTEXT *)v7);
      LODWORD(v35) = MmGetNumberOfPhysicalPages(0i64);
      Address[0] = v35;
      IoAddTriageDumpDataBlock(Address, (_BYTE *)8);
      PopRecordHibernateDiagnosticInfo(v7);
      IoAddTriageDumpDataBlock((char *)&stru_140C23628 + 2680, (_BYTE *)0x80);
      KeBugCheckEx(
        0xA0u,
        (PVOID)0xB,
        qword_140C23450,
        (PVOID)*(unsigned int *)(v7 + 184),
        RemainingHibernateRangeDataSize);
    }
    PopHiberChecksumHiberFileData((_POP_HIBER_CONTEXT *)v7, 1u, v22, Buffer, Size);
    *(_QWORD *)v6 = 0i64;
    *(_DWORD *)(v6 + 40) = v14;
    *(_QWORD *)(v6 + 24) = v16;
    v24 = ((v16 & 0xFFF) + v14 + 4095) >> 12;
    *(_DWORD *)(v6 + 44) = v16 & 0xFFF;
    Address[1] = v24;
    *(_WORD *)(v6 + 10) = 1;
    *(_WORD *)(v6 + 8) = 8 * (v24 + 6);
    *(_QWORD *)(v6 + 32) = v16 & 0xFFFFFFFFFFFFF000ui64;
    if( v24 )
    {
      v25 = 0i64;
      v26 = 0;
      do
      {
        LODWORD(v27) = MmGetPhysicalAddress(v16 + (v25 << 12));
        ++v26;
        *(_QWORD *)(v6 + 8 * v25 + 48) = v27 >> 12;
        v25 = v26;
      }
      while( v26 < ((v16 & 0xFFF) + v14 + 4095) >> 12 );
      v4 = a3;
      RemainingHibernateRangeDataSize = 0i64;
      v7 = a1;
      v10 = v39;
    }
    *(_QWORD *)(v7 + 352) = v14;
    if( !*(_BYTE *)(v7 + 392) )
      goto LABEL_18;
    v28 = __rdtsc();
    v33 = (void *)(*(int(__fastcall **)(__int64, __int64, __int64, _QWORD))(*(_QWORD *)(v7 + 168) + 128i64))(
                    1i64,
                    v10,
                    v6,
                    0i64);
    v34 = __rdtsc();
    *(&stru_140C23628 + 51) += (((unsigned __int64)HIDWORD(v34) << 32) | (unsigned int)v34) - v28;
    if( (_DWORD)v33 == -1073741637 )
    {
      *(_BYTE *)(v7 + 392) = 0;
    }
    else
    {
      if( (int)v33 < 0 || *(&stru_140C23628 + 583) == 2 )
      {
        PopCheckpointSystemSleep(PopSleepCheckpointHiberWriteFailed);
        PopInternalAddToDumpFile((VOID *)v7, 0x1C8ui64, 0i64);
        PopInternalAddToDumpFile(*(VOID **)(v7 + 168), 0x178ui64, 0i64);
        KeBugCheckEx(0xA0u, (PVOID)0x10A, (PVOID)0xA, (PVOID)v7, v33);
      }
      *(_DWORD *)(v7 + 328) = ((_DWORD)v33 != 259) + 1;
    }
    if( !*(_BYTE *)(v7 + 392) )
    {
LABEL_18:
      v28 = __rdtsc();
      v29 = (void *)(*(int(__fastcall **)(__int64, __int64))(*(_QWORD *)(v7 + 168) + 64i64))(v10, v6);
      v30 = __rdtsc();
      *(&stru_140C23628 + 51) += (((unsigned __int64)HIDWORD(v30) << 32) | (unsigned int)v30) - v28;
      if( (int)v29 < 0 )
      {
        PopCheckpointSystemSleep(PopSleepCheckpointHiberWriteFailed);
        PopInternalAddToDumpFile((VOID *)v7, 0x1C8ui64, 0i64);
        PopInternalAddToDumpFile(*(VOID **)(v7 + 168), 0x178ui64, 0i64);
        KeBugCheckEx(0xA0u, (PVOID)0x10A, (PVOID)0xA, (PVOID)v7, v29);
      }
      *(_DWORD *)(v7 + 328) = 2;
    }
    v5 = a2;
    *(_QWORD *)(v7 + 336) = v28;
  }
  LOBYTE(RemainingHibernateRangeDataSize) = v42 == 0;
  return(char)RemainingHibernateRangeDataSize;
}

Referenced by:

PopCompressCallback
PopWriteHiberImage