/// <summary>
        /// Get a list of handles
        /// </summary>
        /// <param name="pid">A process ID to filter on. If -1 will get all handles</param>
        /// <param name="allow_query">True to allow the handles returned to query for certain properties</param>
        /// <returns>The list of handles</returns>
        public static IEnumerable <NtHandle> GetHandles(int pid, bool allow_query)
        {
            using (SafeHGlobalBuffer handle_info = new SafeHGlobalBuffer(0x10000))
            {
                AllocateSafeBuffer(handle_info, SystemInformationClass.SystemHandleInformation);
                int handle_count = handle_info.Read <Int32>(0);
                SystemHandleTableInfoEntry[] handles = new SystemHandleTableInfoEntry[handle_count];
                handle_info.ReadArray((ulong)IntPtr.Size, handles, 0, handle_count);

                return(handles.Where(h => pid == -1 || h.UniqueProcessId == pid).Select(h => new NtHandle(h, allow_query)));
            }
        }
        internal NtHandle(SystemHandleTableInfoEntry entry, bool allow_query)
        {
            ProcessId = entry.UniqueProcessId;
            NtType info = NtType.GetTypeByIndex(entry.ObjectTypeIndex);

            if (info != null)
            {
                NtType = info;
            }

            Attributes    = (AttributeFlags)entry.HandleAttributes;
            Handle        = entry.HandleValue;
            Object        = entry.Object.ToUInt64();
            GrantedAccess = (GenericAccessRights)entry.GrantedAccess;
            _allow_query  = allow_query;
        }
        internal NtHandle(SystemHandleTableInfoEntry entry, bool allow_query)
        {
            ProcessId = entry.UniqueProcessId;
            NtType info = NtType.GetTypeByIndex(entry.ObjectTypeIndex);

            if (info != null)
            {
                ObjectType = info.Name;
            }
            else
            {
                ObjectType = String.Format("Unknown {0}", entry.ObjectTypeIndex);
            }
            Attributes    = (AttributeFlags)entry.HandleAttributes;
            Handle        = entry.HandleValue;
            Object        = (ulong)entry.Object.ToInt64();
            GrantedAccess = entry.GrantedAccess;
            _allow_query  = allow_query;
        }
        /// <summary>
        /// Get a list of handles
        /// </summary>
        /// <param name="pid">A process ID to filter on. If -1 will get all handles</param>
        /// <param name="allow_query">True to allow the handles returned to query for certain properties</param>
        /// <returns>The list of handles</returns>
        public static IEnumerable <NtHandle> GetHandles(int pid, bool allow_query)
        {
            SafeHGlobalBuffer handleInfo = new SafeHGlobalBuffer(0x10000);

            try
            {
                NtStatus status        = 0;
                int      return_length = 0;
                while ((status = NtSystemCalls.NtQuerySystemInformation(SystemInformationClass.SystemHandleInformation,
                                                                        handleInfo.DangerousGetHandle(),
                                                                        handleInfo.Length,
                                                                        out return_length)) == NtStatus.STATUS_INFO_LENGTH_MISMATCH)
                {
                    int length = handleInfo.Length * 2;
                    handleInfo.Close();
                    handleInfo = new SafeHGlobalBuffer(length);
                }
                status.ToNtException();

                IntPtr          handleInfoBuf = handleInfo.DangerousGetHandle();
                int             handle_count  = Marshal.ReadInt32(handleInfoBuf);
                List <NtHandle> ret           = new List <NtHandle>();
                handleInfoBuf += IntPtr.Size;
                for (int i = 0; i < handle_count; ++i)
                {
                    SystemHandleTableInfoEntry entry = (SystemHandleTableInfoEntry)Marshal.PtrToStructure(handleInfoBuf, typeof(SystemHandleTableInfoEntry));

                    if (pid == -1 || entry.UniqueProcessId == pid)
                    {
                        ret.Add(new NtHandle(entry, allow_query));
                    }
                    handleInfoBuf += Marshal.SizeOf(typeof(SystemHandleTableInfoEntry));
                }
                return(ret);
            }
            finally
            {
                handleInfo.Close();
            }
        }
 internal NtHandle(SystemHandleTableInfoEntry entry, bool allow_query)
 {
     ProcessId = entry.UniqueProcessId;
     NtType info = NtType.GetTypeByIndex(entry.ObjectTypeIndex);
     if (info != null)
     {
         ObjectType = info.Name;
     }
     else
     {
         ObjectType = String.Format("Unknown {0}", entry.ObjectTypeIndex);
     }
     Attributes = (AttributeFlags)entry.HandleAttributes;
     Handle = entry.HandleValue;
     Object = (ulong)entry.Object.ToInt64();
     GrantedAccess = entry.GrantedAccess;
     _allow_query = allow_query;
 }