CmpAddDriverToList

UINT8 __fastcall CmpAddDriverToList(
        _HHIVE *Hive,
        UINT64 DriverCell,
        UINT64 GroupOrderCell,
        _UNICODE_STRING *RegistryPath,
        _LIST_ENTRY *BootDriverListHead,
        UINT8 UpdateExistingDriver){
  char *v7; 
  char *v8; 
  _CELL_DATA *(__fastcall *GetCellRoutine)(_HHIVE *, unsigned int, _HV_GET_CELL_CONTEXT *); 
  _CM_KEY_NODE *v10; 
  _CM_KEY_NODE *v11; 
  WCHAR *NodeName; 
  WCHAR *v13; 
  char *v14; 
  _LIST_ENTRY *v15; 
  _WORD *v16; 
  UINT16 v17; 
  unsigned int ValueByName; 
  _CELL_DATA *v19; 
  _CELL_DATA *v20; 
  unsigned int v21; 
  wchar_t *v22; 
  wchar_t *Buffer; 
  void(__fastcall *ReleaseCellRoutine)(_HHIVE *, _HV_GET_CELL_CONTEXT *); 
  void *(__fastcall *v25)(unsigned int, unsigned __int8, unsigned int); 
  UINT8 v26; 
  void *v27; 
  void *v28; 
  __int64 *v29; 
  __int64 v30; 
  unsigned int v31; 
  _CELL_DATA *v32; 
  _CELL_DATA *v33; 
  unsigned int v34; 
  _CELL_DATA *v35; 
  const UNICODE_STRING *v36; 
  unsigned __int16 v37; 
  unsigned int v38; 
  unsigned int v39; 
  void *(__fastcall *Allocate)(unsigned int, unsigned __int8, unsigned int); 
  __int64 v42; 
  _CELL_DATA *v43; 
  unsigned __int16 v44; 
  void *v45; 
  void *v46; 
  void *v47; 
  size_t Size; 
  _CM_KEY_NODE *KeyNode; 
  int v50[2]; 
  UNICODE_STRING v51; 
  struct _UNICODE_STRING Destination; 
  _HV_GET_CELL_CONTEXT CellContext; 
  _HV_GET_CELL_CONTEXT v54; 
  _HV_GET_CELL_CONTEXT v55; 
  _HV_GET_CELL_CONTEXT v56; 
  int v57[2]; 
  struct _UNICODE_STRING DestinationString; 
  UINT16 NameLength; 
  ULONG_PTR BugCheckParameter3; 
  UINT64 v61; 
  LODWORD(v61) = (_DWORD)RegistryPath;
  BugCheckParameter3 = GroupOrderCell;
  v57[1] = 0;
  *(_DWORD *)&v56.BinContext = 0;
  v57[0] = -1;
  v56.Cell = -1;
  v55.Cell = -1;
  *(_DWORD *)&v55.BinContext = 0;
  v7 = 0i64;
  v54.Cell = -1;
  v8 = 0i64;
  *(_DWORD *)&v54.BinContext = 0;
  CellContext.Cell = -1;
  *(_DWORD *)&CellContext.BinContext = 0;
  v50[0] = -1;
  v50[1] = 0;
  GetCellRoutine = Hive->GetCellRoutine;
  LODWORD(Size) = 0;
  DestinationString = 0i64;
  NameLength = 0;
  v51 = 0i64;
  Destination = 0i64;
  v10 = (_CM_KEY_NODE *)GetCellRoutine(Hive, DriverCell, (_HV_GET_CELL_CONTEXT *)v57);
  KeyNode = v10;
  v11 = v10;
  if( !v10 )
  {
    v11 = 0i64;
    goto LABEL_64;
  }
  NodeName = CmpGetNodeName(Hive, v10, &NameLength);
  v13 = NodeName;
  if( !NodeName )
  {
LABEL_64:
    v26 = 0;
    goto LABEL_36;
  }
  if( (int)RtlInitUnicodeStringEx(&DestinationString, NodeName) < 0
    || (v14 = (char *)Hive->Allocate(144i64, 0i64, 540101955i64), (v8 = v14) == 0i64) )
  {
    v26 = 0;
    goto LABEL_34;
  }
  memset((INT64)v14, 0i64);
  v15 = BootDriverListHead;
  v16 = v8 + 120;
  v17 = NameLength;
  *((_QWORD *)v8 + 8) = Hive;
  v7 = v8;
  *(_LIST_ENTRY *)(v8 + 72) = *v15;
  *((_QWORD *)v8 + 5) = 0i64;
  *((_QWORD *)v8 + 3) = 0i64;
  *((_QWORD *)v8 + 16) = v13;
  v13 = 0i64;
  *((_WORD *)v8 + 60) = v17 - 2;
  *((_WORD *)v8 + 61) = v17;
  ValueByName = CmpFindValueByName(Hive, v11, (_UNICODE_STRING *)&CmpImagePathString);
  if( ValueByName == -1 )
  {
    Allocate = Hive->Allocate;
    v42 = (unsigned int)(unsigned __int16)*v16 + 46;
    v51.MaximumLength = *v16 + 46;
    v51.Buffer = (wchar_t *)Allocate(v42, 0, 540233027u);
    if( !v51.Buffer )
    {
      v26 = 0;
      goto LABEL_39;
    }
    if( RtlAppendUnicodeToString(&v51, (PWCHAR)L"System32\\Drivers\\") >= 0
      && RtlAppendUnicodeStringToString(&v51, (UNICODE_STRING *)(v8 + 120)) >= 0
      && RtlAppendUnicodeToString(&v51, (PWCHAR)L".sys") >= 0 )
    {
      Buffer = v51.Buffer;
      goto LABEL_10;
    }
    goto LABEL_64;
  }
  v19 = Hive->GetCellRoutine(Hive, ValueByName, v50);
  if( !v19
    || (v20 = CmpValueToData(Hive, ValueByName, (_CM_KEY_VALUE *)v19, (UINT *)&Size, &CellContext),
        *(_QWORD *)&DestinationString.Length = v20,
        Hive->ReleaseCellRoutine(Hive, (_HV_GET_CELL_CONTEXT *)v50),
        !v20) )
  {
    v11 = KeyNode;
    v26 = 0;
LABEL_36:
    Buffer = v51.Buffer;
    goto LABEL_37;
  }
  v21 = Size;
  v22 = (wchar_t *)Hive->Allocate((unsigned int)Size, 0i64, 540233027i64);
  v51.Buffer = v22;
  Buffer = v22;
  if( !v22 )
  {
    Hive->ReleaseCellRoutine(Hive, &CellContext);
    v11 = KeyNode;
    v26 = 0;
    goto LABEL_39;
  }
  memmove((UINT8 *)v22, *(UINT8 **)&DestinationString.Length, v21);
  ReleaseCellRoutine = Hive->ReleaseCellRoutine;
  v51.Length = v21;
  v51.MaximumLength = v21;
  ReleaseCellRoutine(Hive, &CellContext);
  v11 = KeyNode;
LABEL_10:
  v25 = Hive->Allocate;
  Destination.MaximumLength = *v16 + LOWORD(BootDriverListHead->Flink) + 92;
  Destination.Buffer = (wchar_t *)v25(Destination.MaximumLength, 0, 540298563u);
  if( !Destination.Buffer
    || RtlAppendUnicodeStringToString(&Destination, (UNICODE_STRING *)&CmpRegistryRootKeyPath) < 0
    || RtlAppendUnicodeStringToString(&Destination, (UNICODE_STRING *)BootDriverListHead) < 0
    || RtlAppendUnicodeStringToString(&Destination, (UNICODE_STRING *)&CmpServicesSubKeyPath) < 0
    || (v26 = 0, RtlAppendUnicodeStringToString(&Destination, (UNICODE_STRING *)(v8 + 120)) < 0) )
  {
    v26 = 0;
    goto LABEL_66;
  }
  v27 = (void *)*((_QWORD *)v8 + 3);
  if( v27 )
    Hive->Free(v27, *((unsigned __int16 *)v8 + 8));
  v28 = (void *)*((_QWORD *)v8 + 5);
  *((UNICODE_STRING *)v8 + 1) = v51;
  v51 = 0i64;
  if( v28 )
    Hive->Free(v28, *((unsigned __int16 *)v8 + 16));
  v29 = (__int64 *)UpdateExistingDriver;
  *((struct _UNICODE_STRING *)v8 + 2) = Destination;
  v30 = *v29;
  Destination = 0i64;
  if( *(__int64 **)(v30 + 8) != v29 )
    __fastfail(3u);
  *(_QWORD *)v8 = v30;
  *((_QWORD *)v8 + 1) = v29;
  *(_QWORD *)(v30 + 8) = v8;
  v7 = 0i64;
  *v29 = (__int64)v8;
  v31 = CmpFindValueByName(Hive, v11, (_UNICODE_STRING *)&CmpErrorControlString);
  if( v31 == -1 )
  {
    *((_DWORD *)v8 + 35) = 1;
  }
  else
  {
    v32 = Hive->GetCellRoutine(Hive, v31, v50);
    if( !v32 )
      goto LABEL_56;
    v33 = CmpValueToData(Hive, v31, (_CM_KEY_VALUE *)v32, (UINT *)&Size, &v54);
    Hive->ReleaseCellRoutine(Hive, (_HV_GET_CELL_CONTEXT *)v50);
    if( !v33 )
      goto LABEL_56;
    *((_DWORD *)v8 + 35) = v33->u.KeyList[0];
    Hive->ReleaseCellRoutine(Hive, &v54);
  }
  v34 = CmpFindValueByName(Hive, v11, (_UNICODE_STRING *)&CmpGroupString);
  if( v34 == -1 )
  {
    v36 = (const UNICODE_STRING *)(v8 + 104);
    *((_WORD *)v8 + 52) = 0;
    *((_WORD *)v8 + 53) = 0;
    *((_QWORD *)v8 + 14) = 0i64;
    goto LABEL_29;
  }
  v35 = Hive->GetCellRoutine(Hive, v34, v50);
  if( v35 )
  {
    *((_QWORD *)v8 + 14) = CmpValueToData(Hive, v34, (_CM_KEY_VALUE *)v35, (UINT *)&Size, &v55);
    Hive->ReleaseCellRoutine(Hive, (_HV_GET_CELL_CONTEXT *)v50);
    if( *((_QWORD *)v8 + 14) )
    {
      Hive->ReleaseCellRoutine(Hive, &v55);
      v36 = (const UNICODE_STRING *)(v8 + 104);
      v37 = Size - 2;
      *((_WORD *)v8 + 52) = Size - 2;
      if( v37 <= (unsigned __int16)Size )
      {
        *((_WORD *)v8 + 53) = v37;
LABEL_29:
        v38 = CmpFindValueByName(Hive, v11, (_UNICODE_STRING *)&CmpDriverDependencyString);
        if( v38 == -1 )
        {
          *((_DWORD *)v8 + 22) = 0;
          *((_QWORD *)v8 + 12) = 0i64;
LABEL_31:
          v11 = KeyNode;
          v39 = CmpFindValueByName(Hive, KeyNode, (_UNICODE_STRING *)&CmpTagString);
          if( v39 == -1 )
            *((_DWORD *)v8 + 34) = -1;
          else
            *((_DWORD *)v8 + 34) = CmpFindTagIndex(BugCheckParameter3, v39, (unsigned int)v61, v36);
          v26 = 1;
LABEL_34:
          v7 = 0i64;
          if( v13 )
            Hive->Free(v13, NameLength);
          goto LABEL_36;
        }
        v43 = Hive->GetCellRoutine(Hive, v38, v50);
        if( v43 )
        {
          *((_QWORD *)v8 + 12) = CmpValueToData(Hive, v38, (_CM_KEY_VALUE *)v43, (UINT *)&Size, &v56);
          Hive->ReleaseCellRoutine(Hive, (_HV_GET_CELL_CONTEXT *)v50);
          if( *((_QWORD *)v8 + 12) )
          {
            Hive->ReleaseCellRoutine(Hive, &v56);
            v44 = Size - 2;
            *((_WORD *)v8 + 44) = Size - 2;
            if( v44 <= (unsigned __int16)Size )
            {
              *((_WORD *)v8 + 45) = v44;
              goto LABEL_31;
            }
          }
        }
      }
    }
  }
LABEL_56:
  Buffer = v51.Buffer;
LABEL_66:
  v11 = KeyNode;
LABEL_37:
  if( Buffer )
    Hive->Free(Buffer, v51.Length);
LABEL_39:
  if( Destination.Buffer )
    Hive->Free(Destination.Buffer, Destination.Length);
  if( v7 )
  {
    v45 = (void *)*((_QWORD *)v7 + 3);
    if( v45 )
      Hive->Free(v45, *((unsigned __int16 *)v7 + 8));
    v46 = (void *)*((_QWORD *)v7 + 5);
    if( v46 )
      Hive->Free(v46, *((unsigned __int16 *)v7 + 16));
    v47 = (void *)*((_QWORD *)v8 + 16);
    if( v47 )
      Hive->Free(v47, *((unsigned __int16 *)v8 + 60));
    Hive->Free(v8, 144u);
  }
  if( v11 )
    Hive->ReleaseCellRoutine(Hive, (_HV_GET_CELL_CONTEXT *)v57);
  return v26;
}

Referenced by:

CmpFindDrivers