/// <summary>
        /// Enumerates all kernel object type-infos available in the operating system.
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NtStatusException">NtQueryObject failed</exception>
        public static IEnumerable <ObjectTypeInfo> EnumerateAllObjectTypes()
        {
            int    nLength            = 0x1000;
            IntPtr ipBufferObjectType = IntPtr.Zero;

            ipBufferObjectType = Marshal.AllocHGlobal(nLength);
            while (true)
            {
                NT_STATUS res1 = NativeMethods.NtQueryObject(IntPtr.Zero, OBJECT_INFORMATION_CLASS.ObjectAllTypesInformation, ipBufferObjectType, nLength, out nLength);
                if (res1 == NT_STATUS.STATUS_SUCCESS)
                {
                    break;
                }
                if (res1 != NT_STATUS.STATUS_INFO_LENGTH_MISMATCH)
                {
                    throw new NtStatusException("NtQueryObject failed", res1);
                }
                Marshal.FreeHGlobal(ipBufferObjectType);
                ipBufferObjectType = Marshal.AllocHGlobal(nLength);
            }

            int    typeInfoCount = Marshal.ReadInt32(ipBufferObjectType);          // actually uint! C++: ULONG NumberOfTypes;
            IntPtr ipTypeInfo    = IntPtr.Add(ipBufferObjectType, IntPtr.Size);    // the int that we just read + padding (only in 64bit!)

            for (int nIndex = 0; nIndex < typeInfoCount; nIndex++)
            {
                OBJECT_TYPE_INFORMATION otiTemp = Marshal.PtrToStructure <OBJECT_TYPE_INFORMATION>(ipTypeInfo);
                string strType = Helpers.MarshalUnicodeString(otiTemp.TypeName);
                yield return(new ObjectTypeInfo(otiTemp, strType));

                int currentSize  = Marshal.SizeOf <OBJECT_TYPE_INFORMATION>() + otiTemp.TypeName.MaximumLength;
                int offsetToNext = Helpers.RoundUp(currentSize, IntPtr.Size);                 // padding depends on 32/64bit
                ipTypeInfo = IntPtr.Add(ipTypeInfo, offsetToNext);
            }
        }
        /// <summary>
        /// Gets the type-info for the handle.
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NtStatusException">
        /// NtQueryObject failed
        /// </exception>
        public ObjectTypeInfo GetHandleType()
        {
            int       length;
            NT_STATUS res1 = NativeMethods.NtQueryObject(_duplicatedObjectHandle, OBJECT_INFORMATION_CLASS.ObjectTypeInformation, IntPtr.Zero, 0, out length);

            if (res1 != NT_STATUS.STATUS_SUCCESS && res1 != NT_STATUS.STATUS_INFO_LENGTH_MISMATCH)
            {
                throw new NtStatusException("NtQueryObject call1 failed", res1);
            }
            IntPtr ptr = IntPtr.Zero;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                RuntimeHelpers.PrepareConstrainedRegions();
                try { }
                finally
                {
                    ptr = Marshal.AllocHGlobal(length);
                }
                NT_STATUS res2 = NativeMethods.NtQueryObject(_duplicatedObjectHandle, OBJECT_INFORMATION_CLASS.ObjectTypeInformation, ptr, length, out length);
                if (res2 != NT_STATUS.STATUS_SUCCESS)
                {
                    throw new NtStatusException("NtQueryObject call2 failed", res2);
                }
                OBJECT_TYPE_INFORMATION objectType = Marshal.PtrToStructure <OBJECT_TYPE_INFORMATION>(ptr);
                string typeName = Helpers.MarshalUnicodeString(objectType.TypeName);
                return(new ObjectTypeInfo(objectType, typeName));
            }
            finally
            {
                Marshal.FreeHGlobal(ptr);
            }
        }
 public ObjectTypeInfo(OBJECT_TYPE_INFORMATION raw, string typeName)
 {
     _raw      = raw;
     _typeName = typeName;
 }