CmUnloadKey

INT64 __fastcall CmUnloadKey(_CM_KEY_CONTROL_BLOCK *Kcb, UINT64 Flags, UINT64 *ControlFlags){
  void *v3; 
  void *v4; 
  CHAR v5; 
  wchar_t *v6; 
  KPROCESSOR_MODE v8; 
  char v9; 
  _ETHREAD *CurrentThread; 
  unsigned __int64 v11; 
  unsigned int Length; 
  struct _PRIVILEGE_SET *TransientPoolWithQuotaTag; 
  _OBJECT_TYPE *v14; 
  __int64 v15; 
  unsigned __int64 v16; 
  int v17; 
  int v18; 
  UINT64 v19; 
  UINT8 v20; 
  UINT8 v21; 
  UINT8 v22; 
  NTSTATUS v23; 
  PVOID *Object; 
  IRP *Objecta; 
  CHAR v27; 
  bool v28; 
  PADAPTER_OBJECT v29; 
  struct _UNICODE_STRING DestinationString; 
  PADAPTER_OBJECT DmaAdapter; 
  CHAR v32[4]; 
  _DWORD a1[3]; 
  PPRIVILEGE_SET Privileges; 
  HANDLE Handle; 
  PVOID VirtualAddress; 
  LIST_ENTRY ThreadPreListHead; 
  int v38; 
  struct _UNICODE_STRING v39; 
  PVOID v40[2]; 
  __int128 v41; 
  __int128 v42; 
  __int128 Argument[2]; 
  __int64 v44; 
  _DWORD result[6]; 
  int v46; 
  int v47; 
  _QWORD v48[9]; 
  INT64 v49[11]; 
  v4 = v3;
  v5 = (char)ControlFlags;
  v27 = (char)ControlFlags;
  LODWORD(v6) = Flags;
  *(_DWORD *)v32 = Flags;
  v38 = 0;
  DestinationString = 0i64;
  RtlInitUnicodeString(&DestinationString, 0i64, (WCHAR)ControlFlags);
  memset((INT64)result, 0i64);
  v47 = -1;
  v48[1] = v48;
  v48[0] = v48;
  memset((INT64)v49, 0i64);
  v8 = *((_BYTE *)KeGetCurrentThread() + 562);
  v29 = 0i64;
  DmaAdapter = 0i64;
  Privileges = 0i64;
  Handle = 0i64;
  memset(Argument, 0, sizeof(Argument));
  v44 = 0i64;
  v9 = 0;
  ThreadPreListHead.Blink = &ThreadPreListHead;
  ThreadPreListHead.Flink = &ThreadPreListHead;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  --*((_WORD *)CurrentThread + 242);
  v28 = CmpAcquireShutdownRundown();
  if( !v28 )
  {
LABEL_51:
    v17 = -1073741431;
    goto LABEL_36;
  }
  if( SeSinglePrivilegeCheck(*(_QWORD *)&SeRestorePrivilege, v8) )
  {
    if( ((unsigned int)v6 & 0xFFFFFFFE) != 0 )
    {
      v17 = -1073741811;
    }
    else
    {
      if( v8 == 1 && ((unsigned __int8)Kcb & 3) != 0 )
        ExRaiseDatatypeMisalignment();
      *(_OWORD *)v40 = *(_OWORD *)&Kcb->RefCount;
      v41 = *(_OWORD *)&Kcb->KeyHash.ConvKey.Hash;
      v42 = *(_OWORD *)&Kcb->KeyHive;
      if( v8 == 1 )
      {
        v39 = 0i64;
        v15 = v41;
        if( (unsigned __int64)v41 >= 0x7FFFFFFF0000i64 )
          v15 = 0x7FFFFFFF0000i64;
        LODWORD(v11) = *(_DWORD *)v15;
        *(_DWORD *)&v39.Length = v11;
        v16 = *(_QWORD *)(v15 + 8);
        v39.Buffer = (wchar_t *)v16;
        DestinationString = v39;
        if( (_WORD)v11 )
        {
          if( (v16 & 1) != 0 )
            ExRaiseDatatypeMisalignment();
          v11 = v16 + (unsigned __int16)v11;
          if( v11 > 0x7FFFFFFF0000i64 || v11 < v16 )
            MEMORY[0x7FFFFFFF0000] = 0;
        }
      }
      else
      {
        DestinationString = *(struct _UNICODE_STRING *)*(_QWORD *)&Kcb->KeyHash.ConvKey.Hash;
      }
      Length = DestinationString.Length;
      if( DestinationString.Length )
      {
        TransientPoolWithQuotaTag = (struct _PRIVILEGE_SET *)CmpAllocateTransientPoolWithQuotaTag(
                                                               0x7FFFFFFF0000i64,
                                                               DestinationString.Length,
                                                               0x35374D43ui64);
        Privileges = TransientPoolWithQuotaTag;
        if( !TransientPoolWithQuotaTag )
        {
          v17 = -1073741670;
          a1[1] = -1073741670;
          goto LABEL_36;
        }
        v6 = (wchar_t *)TransientPoolWithQuotaTag;
        memmove((UINT8 *)TransientPoolWithQuotaTag, (UINT8 *)DestinationString.Buffer, Length);
        DestinationString.Length = Length;
        DestinationString.MaximumLength = Length;
        DestinationString.Buffer = v6;
        LOBYTE(v6) = v32[0];
        v5 = v27;
      }
      else
      {
        RtlInitUnicodeString(&DestinationString, 0i64, v11);
      }
      *(_QWORD *)&v41 = &DestinationString;
      v42 = 0i64;
      if( v8 == 1 )
      {
        v17 = CmConvertHandleToKernelHandle(v40[1], v14, 1, 0i64, &Handle);
        if( v17 < 0 )
          goto LABEL_36;
        v40[1] = Handle;
      }
      v46 = 0;
      result[0] = 4;
      LOBYTE(Object) = 0;
      v18 = ObReferenceObjectByNameEx(
              (__int64)v40,
              0i64,
              0,
              (__int64)CmKeyObjectType,
              (INT64)Object,
              (__int64)result,
              &v29);
      if( v18 == -1073741772 )
        v18 = -1073741811;
      v17 = v18;
      if( v18 >= 0 )
      {
        if( v4 )
        {
          VirtualAddress = 0i64;
          v17 = ObReferenceObjectByHandle(v4, 2u, (POBJECT_TYPE)ExEventObjectType, v8, &VirtualAddress, 0i64);
          DmaAdapter = (PADAPTER_OBJECT)VirtualAddress;
          if( v17 < 0 )
            goto LABEL_36;
          KeResetEvent(VirtualAddress, v19, v20, v21, Objecta);
        }
        if( !CmpCallBackCount || ExIsResourceAcquiredSharedLite((PERESOURCE)&CmpRegistryLock) )
          goto LABEL_33;
        *(_QWORD *)&Argument[0] = v29;
        *((_QWORD *)&Argument[0] + 1) = DmaAdapter;
        v23 = CmpCallCallBacks(RegNtPreUnLoadKey, Argument, v22, RegNtPostUnLoadKey, v29, &ThreadPreListHead);
        v17 = v23;
        if( v23 >= 0 )
        {
          v9 = 1;
LABEL_33:
          a1[0] = 0;
          while( (CmpShutdownRundown & 1) == 0 )
          {
            v17 = CmpPerformUnloadKey((INT64)v29, (CHAR)v6, v5, DmaAdapter);
            if( v17 != -1073741267 )
              goto LABEL_36;
            CmpRetryBackOff(a1);
          }
          goto LABEL_51;
        }
        if( v23 == -1073740541 )
          v17 = 0;
      }
    }
  }
  else
  {
    v17 = -1073741727;
  }
LABEL_36:
  if( v9 )
    v17 = CmPostCallbackNotification(RegNtPostUnLoadKey, v29, (unsigned int)v17, Argument, &ThreadPreListHead);
  if( DmaAdapter )
    HalPutDmaAdapter(DmaAdapter);
  if( v29 )
    HalPutDmaAdapter(v29);
  if( Privileges )
    CmSiFreeMemory(Privileges);
  if( Handle )
    ZwClose(Handle);
  CmpCleanupParseContext((__int64)result, 0);
  if( v28 )
    CmpReleaseShutdownRundown();
  KeLeaveCriticalRegion();
  return(unsigned int)v17;
}

Referenced by:

NtUnloadKey
NtUnloadKey2
NtUnloadKeyEx