IoWriteCrashDump

VOID __fastcall IoWriteCrashDump(
        UINT64 BugCheckCode,
        UINT64 BugCheckParameter1,
        const UINT16 *a3,
        UINT64 a4,
        UINT64 a5,
        _CONTEXT *TriageContext,
        INT64 a7,
        INT64 a8,
        CHAR a9){
  _KTRAP_FRAME *Thread; 
  NTSTATUS v10; 
  UINT64 v11; 
  unsigned int v12; 
  unsigned int v13; 
  _DWORD *v14; 
  __int64 v15; 
  __int64 v16; 
  INT64 *v17; 
  _CONTEXT *v18; 
  UINT64 v19; 
  INT64 v20; 
  _OWORD *v21; 
  __int128 v22; 
  unsigned __int64 v23; 
  const UINT16 *v24; 
  UINT64 v25; 
  __int64 v26; 
  int v27; 
  _QWORD *v28; 
  _MM_DUMP_TYPE v29; 
  int v30; 
  UINT64 v31; 
  NTSTATUS v32; 
  UINT64 v33; 
  const UINT16 *v34; 
  UINT64 v35; 
  _KTRAP_FRAME *TriageOptions; 
  UINT64 NumDataArrays; 
  VOID *DataArraysIn; 
  char v39; 
  unsigned int Flags; 
  _RTL_BITMAP_EX ModifyArrayIn; 
  unsigned int v44; 
  UINT64 Fields; 
  INT64 v46; 
  UINT64 v47; 
  __int64 Context[6]; 
  UINT64 BugCheckParameters[4]; 

  Thread = (_KTRAP_FRAME *)a7;
  v10 = 0;
  v11 = BugCheckParameter1;
  v46 = a7;
  v12 = BugCheckCode;
  v44 = 0;
  Flags = 0;
  v47 = BugCheckParameter1;
  Fields = 3583i64;
  KdCheckForDebugBreak();
  if( byte_140C508F8 == 1 )
  {
    IopWriteCapsuleTriageDumpToFirmware(v12, v11, (UINT64)a3, a4, a5, TriageContext, (_ETHREAD *)a7, TriageOptions);
    return;
  }
  BugCheckParameters[0] = v11;
  BugCheckParameters[1] = (UINT64)a3;
  BugCheckParameters[2] = a4;
  BugCheckParameters[3] = a5;
  MmSnapTriageDumpInformation(TriageContext, BugCheckParameters, a3, a4);
  if( qword_140C50960 )
  {
    if( (*(_DWORD *)(qword_140C50960 + 1368i64) & 1) != 0 && *(_DWORD *)(qword_140C50960 + 1336i64) == 6 )
    {
      v13 = 0;
      v14 = (_DWORD *)(qword_140C50960 + 1372i64);
      while( *v14 != v12 )
      {
        ++v13;
        ++v14;
        if( v13 >= 8 )
          goto LABEL_11;
      }
      *(_DWORD *)(qword_140C50960 + 1336i64) = 5;
    }
LABEL_11:
    if( !a8 )
    {
      v44 = 1;
      LODWORD(Fields) = 3319;
      *(_QWORD *)(qword_140C50960 + 8i64) = 0i64;
    }
    ((void(__fastcall *)(__int64, _QWORD, _QWORD))qword_140C509D0)(1i64, 0i64, v44);
    VfDisableHalVerifier();
    LOBYTE(v15) = 1;
    v39 = ((__int64(__fastcall *)(__int64))qword_140C50A00)(v15);
    IoSaveBugCheckProgress(0x20ui64);
    v16 = 9i64;
    v17 = (INT64 *)a3;
    v18 = TriageContext;
    v19 = a4;
    v20 = a5;
    *(_DWORD *)(qword_140C50960 + 24i64) = v12;
    *(_QWORD *)(qword_140C50960 + 32i64) = v11;
    *(_QWORD *)(qword_140C50960 + 40i64) = a3;
    *(_QWORD *)(qword_140C50960 + 48i64) = a4;
    *(_QWORD *)(qword_140C50960 + 56i64) = a5;
    v21 = (_OWORD *)(qword_140C50960 + 64i64);
    do
    {
      *v21 = *(_OWORD *)&v18->P1Home;
      v21[1] = *(_OWORD *)&v18->P3Home;
      v21[2] = *(_OWORD *)&v18->P5Home;
      v21[3] = *(_OWORD *)&v18->ContextFlags;
      v21[4] = *(_OWORD *)&v18->SegGs;
      v21[5] = *(_OWORD *)&v18->Dr1;
      v21[6] = *(_OWORD *)&v18->Dr3;
      v21 += 8;
      v22 = *(_OWORD *)&v18->Dr7;
      v18 = (_CONTEXT *)((char *)v18 + 128);
      *(v21 - 1) = v22;
      --v16;
    }
    while( v16 );
    *v21 = *(_OWORD *)&v18->P1Home;
    v21[1] = *(_OWORD *)&v18->P3Home;
    v21[2] = *(_OWORD *)&v18->P5Home;
    v21[3] = *(_OWORD *)&v18->ContextFlags;
    v21[4] = *(_OWORD *)&v18->SegGs;
    *(_QWORD *)(qword_140C50960 + 1296i64) = &KdDebuggerDataBlock;
    *(_QWORD *)(qword_140C50960 + 1304i64) = &PsActiveProcessHead;
    *(_QWORD *)(qword_140C50960 + 1312i64) = &PsLoadedModuleList;
    *(_QWORD *)(qword_140C50960 + 1320i64) = MmPfnDatabase;
    *(_QWORD *)(qword_140C50960 + 16i64) = (char *)&KiSwapEvent + 368;
    *(_QWORD *)(qword_140C50960 + 1416i64) = (char *)&KiSwapEvent + 384;
    if( a8 )
      v23 = *(_QWORD *)(*(_QWORD *)(a7 + 184) + 40i64);
    else
      v23 = __readcr3();
    *(_QWORD *)(qword_140C50960 + 1344i64) = v23 & 0xFFFFFFFFFFFFF000ui64;
    if( !*(_QWORD *)(qword_140C50960 + 1328i64) && v39 == 1 && a8 )
    {
LABEL_29:
      v27 = *(_DWORD *)(qword_140C50960 + 1368i64) & 2;
      if( v27 && *(_DWORD *)(qword_140C50960 + 1336i64) == 6 && *(_QWORD *)(qword_140C50960 + 8i64) )
      {
        *(_DWORD *)(qword_140C50960 + 1368i64) |= 4u;
        v10 = IoAddPagesForPartialKernelDump(v12, v11, v17, v19, v20, (INT64)TriageContext, a7);
        goto LABEL_42;
      }
      v28 = *(_QWORD **)(qword_140C50960 + 8i64);
      if( !v28 )
      {
LABEL_41:
        Thread = (_KTRAP_FRAME *)v46;
LABEL_42:
        if( v10 >= 0 )
          v10 = ((__int64(__fastcall *)(_QWORD, INT64))qword_140C509D8)(qword_140C50960, a8);
        if( v10 != -1073741267 )
          goto LABEL_52;
        if( (*(_DWORD *)(qword_140C50960 + 1368i64) & 4) != 0 )
        {
          IoSaveBugCheckProgress(0x27ui64);
          *(_DWORD *)(qword_140C50960 + 1368i64) |= 8u;
          v10 = IoAddPagesForPartialKernelDump(v12, v11, (INT64 *)a3, a4, a5, (INT64)TriageContext, (INT64)Thread);
          if( v10 < 0 )
            goto LABEL_52;
          v32 = ((__int64(__fastcall *)(_QWORD, INT64))qword_140C509D8)(qword_140C50960, a8);
          v33 = 38i64;
        }
        else
        {
          if( !*(_QWORD *)(qword_140C50960 + 1328i64) )
            goto LABEL_52;
          *(_DWORD *)(qword_140C50960 + 1404i64) |= 0x400u;
          IoUpdateBugCheckProgressEnvVariable();
          IopUpdateMinidumpContext(v12, v11, (UINT64)a3, a4, a5, TriageContext, Thread);
          MmSnapTriageDumpInformation(TriageContext, BugCheckParameters, v34, v35);
          ModifyArrayIn.SizeOfBitMap = *(&stru_140C452E0 + 718) | 0x10000000000i64;
          ModifyArrayIn.Buffer = (unsigned __int64 *)((char *)&stru_140C452E0 + 2880);
          LODWORD(DataArraysIn) = 1;
          LODWORD(NumDataArrays) = 65;
          LODWORD(TriageOptions) = CmNtCSDVersion;
          v10 = IoFillTriageDumpBuffer(
                  0x3E000ui64,
                  *(VOID **)(qword_140C50960 + 1328i64),
                  1u,
                  0xDFFui64,
                  0i64,
                  TriageContext,
                  (_KTHREAD *)Thread,
                  (UINT64)TriageOptions,
                  NumDataArrays,
                  DataArraysIn,
                  &ModifyArrayIn,
                  &ModifyArrayIn.SizeOfBitMap);
          if( v10 < 0 )
            goto LABEL_52;
          v32 = ((__int64(__fastcall *)(_QWORD, INT64))qword_140C509D8)(qword_140C50960, a8);
          v33 = 35i64;
        }
        v10 = v32;
        IoSaveBugCheckProgress(v33);
LABEL_52:
        if( (DumpPolicyAttemptOffline & 1) != 0 && v10 < 0 || (DumpPolicyAttemptOffline & 2) != 0 && !v39 )
        {
          IoSaveBugCheckProgress(0x24ui64);
          if( ((int(__fastcall *)(_QWORD))off_140C008D8[0])(0i64) >= 0 )
          {
            if( qword_140C50960 )
            {
              *(_DWORD *)(qword_140C50960 + 1404i64) |= 0x1000u;
              IoUpdateBugCheckProgressEnvVariable();
            }
            while( 1 )
            {
              KeStallExecutionProcessor(0xF4240u);
              ++AttemptOfflineStallCount;
            }
          }
        }
        else if( v10 >= 0 && v39 != 1 )
        {
          if( *(_QWORD *)(qword_140C50960 + 1360i64) )
          {
            IoSetBugCheckProgressAndFlag();
            IopWriteTriageDumpToFirmware(*(UINT8 **)(qword_140C50960 + 1360i64));
            if( qword_140C50960 )
            {
              *(_DWORD *)(qword_140C50960 + 1404i64) |= 0x10000000u;
              IoUpdateBugCheckProgressEnvVariable();
            }
          }
        }
        return;
      }
      Context[5] = 0i64;
      v29 = MmDumpTypeFullMemory;
      ModifyArrayIn.SizeOfBitMap = v28[6];
      ModifyArrayIn.Buffer = v28 + 7;
      Context[2] = (__int64)&ModifyArrayIn;
      Context[0] = (__int64)IoSetDumpRange;
      Context[1] = (__int64)IoFreeDumpRange;
      Context[3] = (__int64)v28;
      Context[4] = 0i64;
      v30 = *(_DWORD *)(qword_140C50960 + 1336i64);
      if( v30 == 6 )
      {
        Flags = a9 != 0;
      }
      else
      {
        if( v30 != 5 || !v27 )
          goto LABEL_40;
        Flags = 2;
      }
      v29 = MmDumpTypeKernel;
LABEL_40:
      IopDumpCallAddPagesCallbacks(v12);
      IoSaveBugCheckProgress(0x21ui64);
      MmGetDumpRange(Context, v29, Flags);
      IopDumpCallRemovePagesCallbacks(v12);
      IoSaveBugCheckProgress(0x22ui64);
      v31 = RtlNumberOfSetBitsEx(&ModifyArrayIn);
      v11 = v47;
      v28[5] = v31;
      goto LABEL_41;
    }
    IopUpdateMinidumpContext(v12, v11, (UINT64)a3, a4, a5, TriageContext, (_KTRAP_FRAME *)a7);
    MmSnapTriageDumpInformation(TriageContext, BugCheckParameters, v24, v25);
    ModifyArrayIn.SizeOfBitMap = *(&stru_140C452E0 + 718) | 0x10000000000i64;
    ModifyArrayIn.Buffer = (unsigned __int64 *)((char *)&stru_140C452E0 + 2880);
    if( v39 == 1 || (v26 = *(_QWORD *)(qword_140C50960 + 1360i64)) == 0 )
    {
      if( !*(_QWORD *)(qword_140C50960 + 1328i64) && !a8 )
        *(_QWORD *)(qword_140C50960 + 1328i64) = *(_QWORD *)(qword_140C50960 + 1360i64) + 0x2000i64;
    }
    else
    {
      *(_QWORD *)(qword_140C50960 + 1328i64) = v26 + 12316;
      *(_QWORD *)(qword_140C50960 + 8i64) = 0i64;
    }
    LODWORD(DataArraysIn) = 1;
    LODWORD(NumDataArrays) = 65;
    LODWORD(TriageOptions) = CmNtCSDVersion;
    v10 = IoFillTriageDumpBuffer(
            0x3E000ui64,
            *(VOID **)(qword_140C50960 + 1328i64),
            1u,
            (unsigned int)Fields,
            0i64,
            TriageContext,
            (_KTHREAD *)a7,
            (UINT64)TriageOptions,
            NumDataArrays,
            DataArraysIn,
            &ModifyArrayIn,
            &ModifyArrayIn.SizeOfBitMap);
    if( v10 >= 0 )
    {
      v17 = (INT64 *)a3;
      v19 = a4;
      v20 = a5;
      goto LABEL_29;
    }
  }
}

Referenced by:

KeBugCheck2