PopRequestWrite

char __fastcall PopRequestWrite(ULONG_PTR BugCheckParameter3, __int64 a2, char a3){
  ULONG_PTR RemainingHibernateRangeDataSize; 
  char v4; 
  __int64 v5; 
  __int64 v6; 
  ULONG_PTR v7; 
  int v8; 
  unsigned __int64 v9; 
  __int64 v10; 
  __int64 v11; 
  __int64 IoLocation; 
  __int64 v13; 
  UINT64 v14; 
  VOID *Buffer; 
  unsigned __int64 v16; 
  unsigned __int64 v18; 
  unsigned __int64 v19; 
  unsigned __int64 v20; 
  __int64 v21; 
  UINT64 v22; 
  UINT64 v23; 
  unsigned __int64 v24; 
  __int64 v25; 
  unsigned int v26; 
  unsigned __int64 v27; 
  ULONG_PTR v28; 
  unsigned __int64 v29; 
  ULONG_PTR BugCheckParameter4; 
  unsigned __int64 v31; 
  ULONG_PTR v32; 
  unsigned __int64 v33; 
  unsigned __int64 v35; 
  __int64 Address[2]; 
  __int64 v37; 
  UINT64 Size; 
  RemainingHibernateRangeDataSize = 0i64;
  v4 = a3;
  v5 = a2;
  v6 = *(_QWORD *)(BugCheckParameter3 + 320);
  v7 = BugCheckParameter3;
  Address[0] = 0i64;
  v35 = 0i64;
  while( 1 )
  {
    while( 1 )
    {
      v8 = *(_DWORD *)(v7 + 328);
      if( !v8 )
        break;
      v18 = __rdtsc();
      v19 = v18;
      if( v8 == 1 )
      {
        BugCheckParameter4 = (*(int(__fastcall **)(__int64, ULONG_PTR, __int64))(*(_QWORD *)(v7 + 168) + 128i64))(
                               2i64,
                               v7 + 368,
                               v6);
        v31 = __rdtsc();
        qword_140C237C0 += (((unsigned __int64)HIDWORD(v31) << 32) | (unsigned int)v31) - v19;
        if( (BugCheckParameter4 & 0x80000000) != 0i64 )
        {
          PopCheckpointSystemSleep(PopSleepCheckpointHiberWriteFailed);
          PopInternalAddToDumpFile((PVOID)v7, 0x1C8ui64, 0i64);
          PopInternalAddToDumpFile(*(PVOID *)(v7 + 168), 0x178ui64, 0i64);
          KeBugCheckEx(0xA0u, 0x10Aui64, 0xAui64, v7, BugCheckParameter4);
        }
        if( (_DWORD)BugCheckParameter4 == 259 )
          return RemainingHibernateRangeDataSize;
        *(_DWORD *)(v7 + 328) = 2;
      }
      else
      {
        qword_140C237B8 += v18 - *(_QWORD *)(v7 + 336);
        ProducerConsumerBufferComplete(v5, v5 + 48, *(_QWORD *)(v7 + 384), *(_DWORD *)(v7 + 360));
        v20 = __rdtsc();
        qword_140C237E0 += (((unsigned __int64)HIDWORD(v20) << 32) | (unsigned int)v20) - v19;
        qword_140C23988 += *(_QWORD *)(v7 + 360);
        dword_140C23990 += (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( (PopWatchdogTimerCount & 0x1F) == 0 )
      off_140C008C0[0]();
    v9 = *(_QWORD *)(v7 + 376);
    v10 = v7 + 368;
    v11 = *(_QWORD *)(v7 + 160);
    ++PopWatchdogTimerCount;
    v37 = v7 + 368;
    IoLocation = PopGetIoLocation(v11, v9, &v35);
    v13 = *(unsigned int *)(v7 + 408);
    *(_QWORD *)(v7 + 368) = IoLocation;
    v14 = (v13 << 12) - *(_QWORD *)(v7 + 344) % (unsigned __int64)(v13 << 12);
    if( v14 >= v35 )
      v14 = v35;
    Size = v14;
    Buffer = (VOID *)ConsumerGetBuffer(v5, &Size, v4);
    v16 = (unsigned __int64)Buffer;
    if( !Buffer )
      break;
    v22 = *(_QWORD *)(v7 + 376);
    v23 = Size;
    *(_QWORD *)(v7 + 384) = Buffer;
    *(_QWORD *)(v7 + 360) = v23;
    if( v22 + v14 > qword_140C23450 )
    {
      PopCheckpointSystemSleep(PopSleepCheckpointHiberFileTooSmall);
      if( (unsigned int)(*(_DWORD *)(v7 + 184) - 4) <= 1 )
        RemainingHibernateRangeDataSize = PopGetRemainingHibernateRangeDataSize(v7);
      Address[0] = MmGetNumberOfPhysicalPages(0i64);
      IoAddTriageDumpDataBlock(Address, 8ui64);
      PopRecordHibernateDiagnosticInfo(v7);
      IoAddTriageDumpDataBlock(&PopHibernateDiagnosticInfo, 0x80ui64);
      KeBugCheckEx(0xA0u, 0xBui64, qword_140C23450, *(unsigned int *)(v7 + 184), RemainingHibernateRangeDataSize);
    }
    PopHiberChecksumHiberFileData((_POP_HIBER_CONTEXT *)v7, 1u, v22, Buffer, v23);
    *(_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
      {
        ++v26;
        *(_QWORD *)(v6 + 8 * v25 + 48) = (unsigned __int64)MmGetPhysicalAddress((PVOID)(v16 + (v25 << 12))).QuadPart >> 12;
        v25 = v26;
      }
      while( v26 < ((v16 & 0xFFF) + v14 + 4095) >> 12 );
      v4 = a3;
      RemainingHibernateRangeDataSize = 0i64;
      v7 = BugCheckParameter3;
      v10 = v37;
    }
    *(_QWORD *)(v7 + 352) = v14;
    if( !*(_BYTE *)(v7 + 392) )
      goto LABEL_18;
    v27 = __rdtsc();
    v32 = (*(int(__fastcall **)(__int64, __int64, __int64, _QWORD))(*(_QWORD *)(v7 + 168) + 128i64))(
            1i64,
            v10,
            v6,
            0i64);
    v33 = __rdtsc();
    qword_140C237C0 += (((unsigned __int64)HIDWORD(v33) << 32) | (unsigned int)v33) - v27;
    if( (_DWORD)v32 == -1073741637 )
    {
      *(_BYTE *)(v7 + 392) = 0;
    }
    else
    {
      if( (v32 & 0x80000000) != 0i64 || PopSimulateHiberBugcheck == 2 )
      {
        PopCheckpointSystemSleep(PopSleepCheckpointHiberWriteFailed);
        PopInternalAddToDumpFile((PVOID)v7, 0x1C8ui64, 0i64);
        PopInternalAddToDumpFile(*(PVOID *)(v7 + 168), 0x178ui64, 0i64);
        KeBugCheckEx(0xA0u, 0x10Aui64, 0xAui64, v7, v32);
      }
      *(_DWORD *)(v7 + 328) = ((_DWORD)v32 != 259) + 1;
    }
    if( !*(_BYTE *)(v7 + 392) )
    {
LABEL_18:
      v27 = __rdtsc();
      v28 = (*(int(__fastcall **)(__int64, __int64))(*(_QWORD *)(v7 + 168) + 64i64))(v10, v6);
      v29 = __rdtsc();
      qword_140C237C0 += (((unsigned __int64)HIDWORD(v29) << 32) | (unsigned int)v29) - v27;
      if( (v28 & 0x80000000) != 0i64 )
      {
        PopCheckpointSystemSleep(PopSleepCheckpointHiberWriteFailed);
        PopInternalAddToDumpFile((PVOID)v7, 0x1C8ui64, 0i64);
        PopInternalAddToDumpFile(*(PVOID *)(v7 + 168), 0x178ui64, 0i64);
        KeBugCheckEx(0xA0u, 0x10Aui64, 0xAui64, v7, v28);
      }
      *(_DWORD *)(v7 + 328) = 2;
    }
    v5 = a2;
    *(_QWORD *)(v7 + 336) = v27;
  }
  LOBYTE(RemainingHibernateRangeDataSize) = Size == 0;
  return RemainingHibernateRangeDataSize;
}

Referenced by:

PopCompressCallback
PopWriteHiberImage