CmpStartRMLog

__int64 __fastcall CmpStartRMLog(char *a1, _LIST_ENTRY *a2, INT64 a3){
  unsigned int v3; 
  _ETHREAD *CurrentThread; 
  VOID **PoolWithTag; 
  bool v8; 
  int started; 
  char *v10; 
  __int64 v11; 
  __int64 v12; 
  PVOID *v13; 
  PLOG_FILE_OBJECT *v14; 
  char *v15; 
  VOID **v16; 
  VOID **v17; 
  FILE_OBJECT *v18; 
  PVOID v19; 
  NTSTATUS v20; 
  CLFS_LSN ullOffset; 
  PVOID v22; 
  NTSTATUS v23; 
  CLFS_LSN v25; 
  FILE_OBJECT *v26; 
  int ppvReadContext; 
  CLFS_LSN plsn2; 
  PVOID pvCursorContext; 
  unsigned int pcbReadBuffer; 
  PVOID P; 
  _UNICODE_STRING GuidString; 
  unsigned int pcbInfoBuffer; 
  unsigned int pcbRestartBuffer; 
  PVOID pvReadContext; 
  _UNICODE_STRING *Source; 
  _UNICODE_STRING UnicodeString; 
  PVOID ppvRestartBuffer; 
  _CLS_LSN plsn; 
  _CLS_LSN plsnPrevious; 
  _CLS_LSN plsnUndoNext; 
  PVOID ppvReadBuffer; 
  _CLS_LSN plsnRecord; 
  VOID *pvRestartBuffer; 
  _CLS_LSN plsnFirst; 
  unsigned __int8 peRecordType; 
  char v47; 
  unsigned int pcbWritten; 

  v3 = 0;
  v47 = 1;
  ppvRestartBuffer = 0i64;
  pcbRestartBuffer = 0;
  plsn.ullOffset = 0i64;
  pvCursorContext = 0i64;
  plsn2.ullOffset = 0i64;
  pcbWritten = 0;
  pvRestartBuffer = 0i64;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  *(_QWORD *)&UnicodeString.Length = 0i64;
  UnicodeString.Buffer = 0i64;
  *(_QWORD *)&GuidString.Length = 0i64;
  --CurrentThread->Tcb.KernelApcDisable;
  GuidString.Buffer = 0i64;
  P = 0i64;
  ExAcquireResourceExclusiveLite(*((_QWORD *)a1 + 16), 1, a3);
  if( (*((_DWORD *)a1 + 26) & 1) != 0 )
    goto LABEL_47;
  PoolWithTag = ExAllocatePoolWithTag(1ui64, 0x78ui64, 538987843i64);
  if( !PoolWithTag )
  {
    v3 = -1073741670;
LABEL_47:
    ExReleaseResourceLite(*((PERESOURCE *)a1 + 16));
    KeLeaveCriticalRegionThread(KeGetCurrentThread());
    return v3;
  }
  *((_DWORD *)a1 + 26) |= 2u;
  v8 = a1 == CmRmSystem;
  *((_QWORD *)a1 + 15) = CLFS_LSN_INVALID_EXT;
  if( v8 )
  {
    Source = (_UNICODE_STRING *)&CmpLogPath;
    if( a2 )
      *(_LIST_ENTRY *)(*(_QWORD *)(*(&stru_140C00F40 + 70) + 64i64) + 128i64) = *a2;
    started = RtlStringFromGUIDEx((_GUID *)(*(_QWORD *)(*(&stru_140C00F40 + 70) + 64i64) + 128i64), &GuidString, 1u);
    if( started < 0 )
      goto LABEL_33;
    v10 = a1 + 72;
    *((_QWORD *)a1 + 9) = 5242880i64;
    v11 = *(&stru_140C00F40 + 70);
  }
  else
  {
    started = CmpQueryNameString(*(PVOID *)(*((_QWORD *)a1 + 10) + 1536i64), &UnicodeString);
    if( started < 0 )
      goto LABEL_33;
    Source = &UnicodeString;
    if( a2 )
      *(_LIST_ENTRY *)(*(_QWORD *)(*((_QWORD *)a1 + 10) + 64i64) + 128i64) = *a2;
    started = RtlStringFromGUIDEx((_GUID *)(*(_QWORD *)(*((_QWORD *)a1 + 10) + 64i64) + 128i64), &GuidString, 1u);
    if( started < 0 )
      goto LABEL_33;
    v11 = *((_QWORD *)a1 + 10);
    v10 = a1 + 72;
    *((_QWORD *)a1 + 9) = 0x100000i64;
  }
  started = CmpQueryFileSecurityDescriptor(*(PVOID *)(v11 + 1536), &P);
  if( started < 0 )
  {
    P = 0i64;
  }
  else
  {
    v13 = (PVOID *)(a1 + 96);
    v14 = (PLOG_FILE_OBJECT *)(a1 + 88);
    v15 = a1 + 68;
    while( 1 )
    {
      started = CmpStartCLFSLog(
                  Source,
                  &GuidString,
                  v12,
                  P,
                  ppvReadContext,
                  (__int64)v10,
                  (__int64)v15,
                  (__int64)v14,
                  (__int64)(a1 + 96));
      if( started < 0 )
        break;
      pcbInfoBuffer = 120;
      v16 = ExAllocatePoolWithTag(1ui64, 0x78ui64, 538987843i64);
      v17 = v16;
      if( v16 )
      {
        ClfsGetLogFileInformation(*v14, (PCLFS_INFORMATION)v16, &pcbInfoBuffer);
        ExFreePoolWithTag(v17, 0);
      }
      v18 = *v14;
      pcbWritten = 120;
      started = ClfsGetLogFileInformation(v18, (PCLFS_INFORMATION)PoolWithTag, &pcbWritten);
      *((_QWORD *)a1 + 15) = PoolWithTag[9];
      if( started < 0 )
        break;
      if( ClfsReadRestartArea(*v13, &ppvRestartBuffer, &pcbRestartBuffer, &plsn, &pvCursorContext) == 1075445772
        || !ppvRestartBuffer )
      {
        plsn2.ullOffset = (unsigned __int64)PoolWithTag[9];
      }
      else
      {
        plsn2 = *(CLFS_LSN *)ppvRestartBuffer;
        if( ClfsLsnEqual((const CLFS_LSN *)&plsn, &plsn2) )
        {
          v19 = *v13;
          plsnFirst = (_CLS_LSN)plsn2.ullOffset;
          pvReadContext = 0i64;
          ppvReadBuffer = 0i64;
          pcbReadBuffer = 0;
          plsnUndoNext.ullOffset = 0i64;
          plsnPrevious.ullOffset = 0i64;
          plsnRecord.ullOffset = 0i64;
          peRecordType = 0;
          if( ClfsReadLogRecord(
                 v19,
                 &plsnFirst,
                 ClfsContextForward,
                 &ppvReadBuffer,
                 &pcbReadBuffer,
                 &peRecordType,
                 &plsnUndoNext,
                 &plsnPrevious,
                 &pvReadContext) >= 0 )
          {
            peRecordType = 1;
            v20 = ClfsReadNextLogRecord(
                    pvReadContext,
                    &ppvReadBuffer,
                    &pcbReadBuffer,
                    &peRecordType,
                    0i64,
                    &plsnUndoNext,
                    &plsnPrevious,
                    &plsnRecord);
            if( v20 == -1073741807 )
            {
              ullOffset.ullOffset = (unsigned __int64)PoolWithTag[11];
            }
            else
            {
              ullOffset = plsn2;
              if( v20 >= 0 )
                ullOffset = (CLFS_LSN)plsnRecord.ullOffset;
            }
            plsn2 = ullOffset;
          }
          if( pvReadContext )
            ClfsTerminateReadLog(pvReadContext);
        }
      }
      if( pvCursorContext )
      {
        ClfsTerminateReadLog(pvCursorContext);
        pvCursorContext = 0i64;
      }
      if( !ClfsLsnEqual(&plsn2, (const CLFS_LSN *)PoolWithTag + 11) && (*((_DWORD *)a1 + 26) & 4) != 0 )
      {
        v25 = plsn2;
        if( (int)CmpRmAnalysisPhase((__int64)a1, (_CLS_LSN)plsn2.ullOffset) >= 0 )
        {
          CmpRmReDoPhase((__int64)a1, (_CLS_LSN)v25.ullOffset);
          CmpRmUnDoPhase((__int64)a1);
        }
        *((_DWORD *)a1 + 26) &= ~4u;
      }
      v22 = *v13;
      pvRestartBuffer = PoolWithTag[11];
      v23 = ClfsWriteRestartArea(v22, &pvRestartBuffer, 8u, 0i64, 0, &pcbWritten, 0i64);
      started = v23;
      if( !v47 || v23 != -1072037859 && *((_DWORD *)a1 + 17) <= 0xAu )
        break;
      v47 = 0;
      if( pvCursorContext )
      {
        ClfsTerminateReadLog(pvCursorContext);
        pvCursorContext = 0i64;
      }
      v14 = (PLOG_FILE_OBJECT *)(a1 + 88);
      ClfsDeleteLogByPointer(*((PLOG_FILE_OBJECT *)a1 + 11));
      ClfsDeleteMarshallingArea(*v13);
      v26 = (FILE_OBJECT *)*((_QWORD *)a1 + 11);
      *v13 = 0i64;
      ClfsCloseLogFileObject(v26);
      v15 = a1 + 68;
      *((_QWORD *)a1 + 11) = 0i64;
      *((_DWORD *)a1 + 17) = 0;
    }
    if( pvCursorContext )
      ClfsTerminateReadLog(pvCursorContext);
    if( started < 0 )
    {
      if( *v13 )
        *v13 = 0i64;
    }
    else
    {
      *((_DWORD *)a1 + 26) = *((_DWORD *)a1 + 26) & 0xFFFFFFFC | 1;
    }
  }
LABEL_33:
  ExReleaseResourceLite(*((PERESOURCE *)a1 + 16));
  KeLeaveCriticalRegionThread(KeGetCurrentThread());
  if( UnicodeString.Buffer )
    RtlFreeAnsiString(&UnicodeString);
  if( GuidString.Buffer )
    RtlFreeAnsiString(&GuidString);
  ExFreePoolWithTag(PoolWithTag, 0);
  if( P )
    ExFreePoolWithTag(P, 0);
  return(unsigned int)started;
}

Referenced by:

CmpInitCmRM
CmpStartRMLogs