CmUnloadKey

__int64 __fastcall CmUnloadKey(_OBJECT_ATTRIBUTES *a1, int a2, WCHAR a3, __int64 a4){
  char v5; 
  _PRIVILEGE_SET *v6; 
  char PreviousMode; 
  char v9; 
  _ETHREAD *CurrentThread; 
  size_t Length; 
  _PRIVILEGE_SET *TransientPoolWithQuotaTag; 
  INT8 v13; 
  UINT64 v14; 
  __int64 ObjectName; 
  int v16; 
  unsigned __int64 v17; 
  unsigned __int64 v18; 
  int v19; 
  NTSTATUS v20; 
  INT64 v21; 
  INT64 v22; 
  UINT8 v23; 
  int v24; 
  VOID **ProbeMode; 
  char v27; 
  BOOL v28; 
  _UNICODE_STRING DestinationString; 
  PADAPTER_OBJECT DmaAdapter; 
  int v31; 
  int v32[3]; 
  PPRIVILEGE_SET Privileges; 
  VOID *Handle; 
  PVOID Object; 
  LIST_ENTRY ThreadPreListHead; 
  int v37; 
  _UNICODE_STRING v38; 
  _OBJECT_ATTRIBUTES ObjectAttributes; 
  __int128 Argument[2]; 
  __int64 v41; 
  INT64 v42[38]; 

  v5 = a3;
  v27 = a3;
  LODWORD(v6) = a2;
  v31 = a2;
  v37 = 0;
  DestinationString = 0i64;
  RtlInitUnicodeString(&DestinationString, 0i64);
  memset(v42, 0i64, 0x128u);
  LODWORD(v42[12]) = -1;
  v42[19] = (INT64)&v42[18];
  v42[18] = (INT64)&v42[18];
  memset(&v42[27], 0i64, 0x50u);
  PreviousMode = KeGetCurrentThread()->PreviousMode;
  DmaAdapter = 0i64;
  Privileges = 0i64;
  Handle = 0i64;
  memset(Argument, 0, sizeof(Argument));
  v41 = 0i64;
  v9 = 0;
  ThreadPreListHead.Blink = &ThreadPreListHead;
  ThreadPreListHead.Flink = &ThreadPreListHead;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  --CurrentThread->Tcb.KernelApcDisable;
  v28 = CmpAcquireShutdownRundown();
  if( !v28 )
  {
LABEL_49:
    v19 = -1073741431;
    goto LABEL_36;
  }
  if( SeSinglePrivilegeCheck(*(_QWORD *)&SeRestorePrivilege, PreviousMode) )
  {
    if( ((unsigned int)v6 & 0xFFFFFFFE) != 0 )
    {
      v19 = -1073741811;
    }
    else
    {
      if( PreviousMode == 1 && ((unsigned __int8)a1 & 3) != 0 )
        ExRaiseDatatypeMisalignment();
      ObjectAttributes = *a1;
      if( PreviousMode == 1 )
      {
        v38 = 0i64;
        ObjectName = (__int64)ObjectAttributes.ObjectName;
        if( ObjectAttributes.ObjectName >= (_UNICODE_STRING *)0x7FFFFFFF0000i64 )
          ObjectName = 0x7FFFFFFF0000i64;
        v16 = *(_DWORD *)ObjectName;
        *(_DWORD *)&v38.Length = v16;
        v17 = *(_QWORD *)(ObjectName + 8);
        v38.Buffer = (wchar_t *)v17;
        DestinationString = v38;
        if( (_WORD)v16 )
        {
          if( (v17 & 1) != 0 )
            ExRaiseDatatypeMisalignment();
          v18 = v17 + (unsigned __int16)v16;
          if( v18 > 0x7FFFFFFF0000i64 || v18 < v17 )
            MEMORY[0x7FFFFFFF0000] = 0;
        }
      }
      else
      {
        DestinationString = *a1->ObjectName;
      }
      Length = DestinationString.Length;
      if( DestinationString.Length )
      {
        TransientPoolWithQuotaTag = (_PRIVILEGE_SET *)CmpAllocateTransientPoolWithQuotaTag(
                                                        0x7FFFFFFF0000i64,
                                                        DestinationString.Length,
                                                        0x35374D43ui64);
        Privileges = TransientPoolWithQuotaTag;
        if( !TransientPoolWithQuotaTag )
        {
          v19 = -1073741670;
          v32[1] = -1073741670;
          goto LABEL_36;
        }
        v6 = TransientPoolWithQuotaTag;
        memmove(TransientPoolWithQuotaTag, DestinationString.Buffer, Length);
        DestinationString.Length = Length;
        DestinationString.MaximumLength = Length;
        DestinationString.Buffer = (wchar_t *)v6;
        LOBYTE(v6) = v31;
        v5 = v27;
      }
      else
      {
        RtlInitUnicodeString(&DestinationString, 0i64);
      }
      ObjectAttributes.ObjectName = &DestinationString;
      *(_OWORD *)&ObjectAttributes.SecurityDescriptor = 0i64;
      if( PreviousMode == 1 )
      {
        ProbeMode = &Handle;
        LOBYTE(v14) = 1;
        v19 = CmConvertHandleToKernelHandle(ObjectAttributes.RootDirectory, v13, v14, 0i64);
        if( v19 < 0 )
          goto LABEL_36;
        ObjectAttributes.RootDirectory = Handle;
      }
      LODWORD(v42[3]) = 0;
      LODWORD(v42[0]) = 4;
      LOBYTE(ProbeMode) = 0;
      v20 = ObReferenceObjectByNameEx(&ObjectAttributes, 0i64, 0i64, (CHAR)CmKeyObjectType, ProbeMode, (VOID **)v42);
      if( v20 == -1073741772 )
        v20 = -1073741811;
      v19 = v20;
      if( v20 >= 0 )
      {
        if( a4 )
        {
          Object = 0i64;
          v19 = ObReferenceObjectByHandle(
                  (VOID *)a4,
                  2ui64,
                  (_OBJECT_TYPE *)ExEventObjectType,
                  PreviousMode,
                  &Object,
                  0i64);
          DmaAdapter = (PADAPTER_OBJECT)Object;
          if( v19 < 0 )
            goto LABEL_36;
          KeResetEvent((_KEVENT *)Object);
        }
        if( !dword_140C5083C || ExIsResourceAcquiredSharedLite((UINT64)&CmpRegistryLock, v21, v22) )
          goto LABEL_33;
        *(_QWORD *)&Argument[0] = 0i64;
        *((_QWORD *)&Argument[0] + 1) = DmaAdapter;
        v24 = CmpCallCallBacks(RegNtPreUnLoadKey, Argument, v23, RegNtPostUnLoadKey, 0i64, &ThreadPreListHead);
        v19 = v24;
        if( v24 >= 0 )
        {
          v9 = 1;
LABEL_33:
          v32[0] = 0;
          while( (*(&CmpDummyThreadEvent + 1056) & 1) == 0 )
          {
            v19 = CmpPerformUnloadKey(0i64, (char)v6, v5, DmaAdapter);
            if( v19 != -1073741267 )
              goto LABEL_36;
            CmpRetryBackOff(v32);
          }
          goto LABEL_49;
        }
        if( v24 == -1073740541 )
          v19 = 0;
      }
    }
  }
  else
  {
    v19 = -1073741727;
  }
LABEL_36:
  if( v9 )
    v19 = CmPostCallbackNotification(RegNtPostUnLoadKey, 0i64, (unsigned int)v19, Argument, &ThreadPreListHead);
  if( DmaAdapter )
    HalPutDmaAdapter(DmaAdapter);
  if( Privileges )
    CmSiFreeMemory(Privileges);
  if( Handle )
    ZwClose((_HANDLE)Handle);
  CmpCleanupParseContext((INT64)v42, 0);
  if( v28 )
    CmpReleaseShutdownRundown();
  KeLeaveCriticalRegion();
  return(unsigned int)v19;
}

Referenced by:

NtUnloadKey
NtUnloadKey2
NtUnloadKeyEx