CmpStartRMLog

NTSTATUS __stdcall CmpStartRMLog(_CM_RM *CmRm, _GUID *FallbackLogGuid){
  NTSTATUS v2; 
  _ETHREAD *CurrentThread; 
  char *PoolWithTag; 
  bool v7; 
  NTSTATUS started; 
  unsigned __int64 *p_ContainerSize; 
  _CMHIVE *CmHive; 
  void *v11; 
  void **p_MarshallingContext; 
  void **p_LogFileObject; 
  unsigned int *p_ContainerNum; 
  CLFS_INFORMATION *v15; 
  CLFS_INFORMATION *v16; 
  FILE_OBJECT *v17; 
  PVOID v18; 
  NTSTATUS v19; 
  __int64 v20; 
  PVOID v21; 
  NTSTATUS v22; 
  __int64 v24; 
  FILE_OBJECT *LogFileObject; 
  PVOID *ppvReadContext; 
  __int64 v27; 
  PVOID pvCursorContext; 
  ULONG pcbReadBuffer; 
  PVOID P; 
  struct _UNICODE_STRING UnicodeString; 
  ULONG pcbInfoBuffer; 
  ULONG pcbRestartBuffer; 
  PVOID pvReadContext; 
  PCUNICODE_STRING Source; 
  UNICODE_STRING NameStr; 
  PVOID ppvRestartBuffer; 
  __int64 v38; 
  __int64 plsnPrevious; 
  __int64 plsnUndoNext; 
  PVOID ppvReadBuffer; 
  __int64 v42; 
  __int64 pvRestartBuffer; 
  __int64 v44[8]; 
  CLS_RECORD_TYPE peRecordType; 
  char v46; 
  ULONG pcbWritten; 
  v2 = 0;
  v46 = 1;
  ppvRestartBuffer = 0i64;
  pcbRestartBuffer = 0;
  v38 = 0i64;
  pvCursorContext = 0i64;
  v27 = 0i64;
  pcbWritten = 0;
  pvRestartBuffer = 0i64;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  *(_QWORD *)&NameStr.Length = 0i64;
  NameStr.Buffer = 0i64;
  *(_QWORD *)&UnicodeString.Length = 0i64;
  --*((_WORD *)CurrentThread + 242);
  UnicodeString.Buffer = 0i64;
  P = 0i64;
  ExAcquireResourceExclusiveLite(CmRm->RmLock, 1u);
  if( (CmRm->RmFlags & 1) != 0 )
    goto LABEL_47;
  PoolWithTag = (char *)ExAllocatePoolWithTag(PagedPool, 0x78ui64, 0x20204D43ui64);
  if( !PoolWithTag )
  {
    v2 = -1073741670;
LABEL_47:
    ExReleaseResourceLite(CmRm->RmLock);
    KeLeaveCriticalRegionThread((__int64)KeGetCurrentThread());
    return v2;
  }
  CmRm->RmFlags |= 2u;
  v7 = CmRm == CmRmSystem;
  CmRm->BaseLsn = CLFS_LSN_INVALID_EXT;
  if( v7 )
  {
    Source = &CmpLogPath;
    if( FallbackLogGuid )
      *(_GUID *)(*(_QWORD *)(Hive + 64) + 128i64) = *FallbackLogGuid;
    started = RtlStringFromGUIDEx((const _GUID *const)(*(_QWORD *)(Hive + 64) + 128i64), &UnicodeString, 1u);
    if( started < 0 )
      goto LABEL_33;
    p_ContainerSize = &CmRm->ContainerSize;
    CmRm->ContainerSize = 5242880i64;
    CmHive = (_CMHIVE *)Hive;
  }
  else
  {
    started = CmpQueryNameString(*((PVOID *)CmRm->CmHive + 192), &NameStr);
    if( started < 0 )
      goto LABEL_33;
    Source = &NameStr;
    if( FallbackLogGuid )
      *(_GUID *)(*((_QWORD *)CmRm->CmHive + 8) + 128i64) = *FallbackLogGuid;
    started = RtlStringFromGUIDEx((const _GUID *const)(*((_QWORD *)CmRm->CmHive + 8) + 128i64), &UnicodeString, 1u);
    if( started < 0 )
      goto LABEL_33;
    CmHive = CmRm->CmHive;
    p_ContainerSize = &CmRm->ContainerSize;
    CmRm->ContainerSize = 0x100000i64;
  }
  started = CmpQueryFileSecurityDescriptor(*((PVOID *)CmHive + 192), &P);
  if( started < 0 )
  {
    P = 0i64;
  }
  else
  {
    p_MarshallingContext = &CmRm->MarshallingContext;
    p_LogFileObject = &CmRm->LogFileObject;
    p_ContainerNum = &CmRm->ContainerNum;
    while( 1 )
    {
      started = CmpStartCLFSLog(
                  (UNICODE_STRING *)Source,
                  &UnicodeString,
                  v11,
                  (UINT64 *)P,
                  (UINT64 *)ppvReadContext,
                  (PVOID *)p_ContainerSize,
                  (PVOID *)p_ContainerNum);
      if( started < 0 )
        break;
      pcbInfoBuffer = 120;
      v15 = (CLFS_INFORMATION *)ExAllocatePoolWithTag(PagedPool, 0x78ui64, 0x20204D43ui64);
      v16 = v15;
      if( v15 )
      {
        ClfsGetLogFileInformation((PLOG_FILE_OBJECT)*p_LogFileObject, v15, &pcbInfoBuffer);
        ExFreePoolWithTag(v16, 0);
      }
      v17 = (FILE_OBJECT *)*p_LogFileObject;
      pcbWritten = 120;
      started = ClfsGetLogFileInformation(v17, (PCLFS_INFORMATION)PoolWithTag, &pcbWritten);
      CmRm->BaseLsn = *((_QWORD *)PoolWithTag + 9);
      if( started < 0 )
        break;
      if( ClfsReadRestartArea(
             *p_MarshallingContext,
             &ppvRestartBuffer,
             &pcbRestartBuffer,
             (PCLFS_LSN)&v38,
             &pvCursorContext) == 1075445772
        || !ppvRestartBuffer )
      {
        v27 = *((_QWORD *)PoolWithTag + 9);
      }
      else
      {
        v27 = *(_QWORD *)ppvRestartBuffer;
        if( ClfsLsnEqual((const CLFS_LSN *)&v38, (const CLFS_LSN *)&v27) )
        {
          v18 = *p_MarshallingContext;
          v44[0] = v27;
          pvReadContext = 0i64;
          ppvReadBuffer = 0i64;
          pcbReadBuffer = 0;
          plsnUndoNext = 0i64;
          plsnPrevious = 0i64;
          v42 = 0i64;
          peRecordType = 0;
          if( ClfsReadLogRecord(
                 v18,
                 (PCLFS_LSN)v44,
                 ClfsContextForward,
                 &ppvReadBuffer,
                 &pcbReadBuffer,
                 &peRecordType,
                 (PCLFS_LSN)&plsnUndoNext,
                 (PCLFS_LSN)&plsnPrevious,
                 &pvReadContext) >= 0 )
          {
            peRecordType = 1;
            v19 = ClfsReadNextLogRecord(
                    pvReadContext,
                    &ppvReadBuffer,
                    &pcbReadBuffer,
                    &peRecordType,
                    0i64,
                    (PCLFS_LSN)&plsnUndoNext,
                    (PCLFS_LSN)&plsnPrevious,
                    (PCLFS_LSN)&v42);
            if( v19 == -1073741807 )
            {
              v20 = *((_QWORD *)PoolWithTag + 11);
            }
            else
            {
              v20 = v27;
              if( v19 >= 0 )
                v20 = v42;
            }
            v27 = v20;
          }
          if( pvReadContext )
            ClfsTerminateReadLog(pvReadContext);
        }
      }
      if( pvCursorContext )
      {
        ClfsTerminateReadLog(pvCursorContext);
        pvCursorContext = 0i64;
      }
      if( !ClfsLsnEqual((const CLFS_LSN *)&v27, (const CLFS_LSN *)(PoolWithTag + 88)) && (CmRm->RmFlags & 4) != 0 )
      {
        v24 = v27;
        if( (int)CmpRmAnalysisPhase(CmRm, v27) >= 0 )
        {
          CmpRmReDoPhase((__int64)CmRm, v24);
          CmpRmUnDoPhase((__int64)CmRm);
        }
        CmRm->RmFlags &= ~4u;
      }
      v21 = *p_MarshallingContext;
      pvRestartBuffer = *((_QWORD *)PoolWithTag + 11);
      v22 = ClfsWriteRestartArea(v21, &pvRestartBuffer, 8u, 0i64, 0, &pcbWritten, 0i64);
      started = v22;
      if( !v46 || v22 != -1072037859 && CmRm->ContainerNum <= 0xA )
        break;
      v46 = 0;
      if( pvCursorContext )
      {
        ClfsTerminateReadLog(pvCursorContext);
        pvCursorContext = 0i64;
      }
      p_LogFileObject = &CmRm->LogFileObject;
      ClfsDeleteLogByPointer((PLOG_FILE_OBJECT)CmRm->LogFileObject);
      ClfsDeleteMarshallingArea(*p_MarshallingContext);
      LogFileObject = (FILE_OBJECT *)CmRm->LogFileObject;
      *p_MarshallingContext = 0i64;
      ClfsCloseLogFileObject(LogFileObject);
      p_ContainerNum = &CmRm->ContainerNum;
      CmRm->LogFileObject = 0i64;
      CmRm->ContainerNum = 0;
    }
    if( pvCursorContext )
      ClfsTerminateReadLog(pvCursorContext);
    if( started < 0 )
    {
      if( *p_MarshallingContext )
        *p_MarshallingContext = 0i64;
    }
    else
    {
      CmRm->RmFlags = CmRm->RmFlags & 0xFFFFFFFC | 1;
    }
  }
LABEL_33:
  ExReleaseResourceLite(CmRm->RmLock);
  KeLeaveCriticalRegionThread((__int64)KeGetCurrentThread());
  if( NameStr.Buffer )
    RtlFreeAnsiString(&NameStr);
  if( UnicodeString.Buffer )
    RtlFreeAnsiString(&UnicodeString);
  ExFreePoolWithTag(PoolWithTag, 0);
  if( P )
    ExFreePoolWithTag(P, 0);
  return started;
}

Referenced by:

CmpInitCmRM
CmpStartRMLogs