如何使用设备查找所有进程

时间:2015-11-07 07:39:54

标签: c# winapi interop

我在确定是否可以找到正在使用设备的进程时遇到了一个非常重要的问题。 我目前正在做的是使用SysInternals handle.exe程序来查找所有打开的“句柄”。

但是,由于该程序已获得许可,我想学习在C#中自己学习,我想知道是否可以单独使用Win32 API。

欢迎所有文档链接。

修改 希望能够搜索类似

的内容
\Device\00000034

3 个答案:

答案 0 :(得分:3)

Fuser SourceForge Project

我在" C"中写了这个实用程序。试图模仿Systinternal的实用程序" handle.exe"确实如此,并使其成为SourceForge项目。您可能必须修改源代码以使其执行您需要它执行的操作。

代码非常丑陋,因为有许多"未记录的" (不一定不支持)正在完成的事情。

我希望这有助于(我认为可能)......

我意识到它写在" C",但希望你可以"翻译" C#的功能。

答案 1 :(得分:1)

最后我找到了一个C# - 只有解决方案!

处理结果大约需要4-5秒,我只在Windows 8.1上进行了测试,但它确实运行良好,您不需要任何设备驱动程序或其他额外组件(如C)。

这里有一些代码可以打印访问\\Device\0000003a的所有进程:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace HandleUtil
{
    class Program
    {


        static void Main(string[] args)
        {
            List<Process> procs = Win32Processes.GetProcessesLockingFile("\\Device\\0000003a");
            foreach(var proc in procs)
            {
                Console.WriteLine(proc.ProcessName);
            }
            Console.ReadLine();
        }



        internal class Win32API
        {
            [DllImport("ntdll.dll")]
            public static extern int NtQueryObject(IntPtr ObjectHandle, int
                ObjectInformationClass, IntPtr ObjectInformation, int ObjectInformationLength,
                ref int returnLength);

            [DllImport("kernel32.dll", SetLastError = true)]
            public static extern uint QueryDosDevice(string lpDeviceName, StringBuilder lpTargetPath, int ucchMax);

            [DllImport("ntdll.dll")]
            public static extern uint NtQuerySystemInformation(int
                SystemInformationClass, IntPtr SystemInformation, int SystemInformationLength,
                ref int returnLength);

            [DllImport("kernel32.dll")]
            public static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
            [DllImport("kernel32.dll")]
            public static extern int CloseHandle(IntPtr hObject);
            [DllImport("kernel32.dll", SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool DuplicateHandle(IntPtr hSourceProcessHandle,
               ushort hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle,
               uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwOptions);
            [DllImport("kernel32.dll")]
            public static extern IntPtr GetCurrentProcess();

            public enum ObjectInformationClass : int
            {
                ObjectBasicInformation = 0,
                ObjectNameInformation = 1,
                ObjectTypeInformation = 2,
                ObjectAllTypesInformation = 3,
                ObjectHandleInformation = 4
            }

            [Flags]
            public enum ProcessAccessFlags : uint
            {
                All = 0x001F0FFF,
                Terminate = 0x00000001,
                CreateThread = 0x00000002,
                VMOperation = 0x00000008,
                VMRead = 0x00000010,
                VMWrite = 0x00000020,
                DupHandle = 0x00000040,
                SetInformation = 0x00000200,
                QueryInformation = 0x00000400,
                Synchronize = 0x00100000
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct OBJECT_BASIC_INFORMATION
            { // Information Class 0
                public int Attributes;
                public int GrantedAccess;
                public int HandleCount;
                public int PointerCount;
                public int PagedPoolUsage;
                public int NonPagedPoolUsage;
                public int Reserved1;
                public int Reserved2;
                public int Reserved3;
                public int NameInformationLength;
                public int TypeInformationLength;
                public int SecurityDescriptorLength;
                public System.Runtime.InteropServices.ComTypes.FILETIME CreateTime;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct OBJECT_TYPE_INFORMATION
            { // Information Class 2
                public UNICODE_STRING Name;
                public int ObjectCount;
                public int HandleCount;
                public int Reserved1;
                public int Reserved2;
                public int Reserved3;
                public int Reserved4;
                public int PeakObjectCount;
                public int PeakHandleCount;
                public int Reserved5;
                public int Reserved6;
                public int Reserved7;
                public int Reserved8;
                public int InvalidAttributes;
                public GENERIC_MAPPING GenericMapping;
                public int ValidAccess;
                public byte Unknown;
                public byte MaintainHandleDatabase;
                public int PoolType;
                public int PagedPoolUsage;
                public int NonPagedPoolUsage;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct OBJECT_NAME_INFORMATION
            { // Information Class 1
                public UNICODE_STRING Name;
            }

            [StructLayout(LayoutKind.Sequential, Pack = 1)]
            public struct UNICODE_STRING
            {
                public ushort Length;
                public ushort MaximumLength;
                public IntPtr Buffer;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct GENERIC_MAPPING
            {
                public int GenericRead;
                public int GenericWrite;
                public int GenericExecute;
                public int GenericAll;
            }

            [StructLayout(LayoutKind.Sequential, Pack = 1)]
            public struct SYSTEM_HANDLE_INFORMATION
            { // Information Class 16
                public int ProcessID;
                public byte ObjectTypeNumber;
                public byte Flags; // 0x01 = PROTECT_FROM_CLOSE, 0x02 = INHERIT
                public ushort Handle;
                public int Object_Pointer;
                public UInt32 GrantedAccess;
            }

            public const int MAX_PATH = 260;
            public const uint STATUS_INFO_LENGTH_MISMATCH = 0xC0000004;
            public const int DUPLICATE_SAME_ACCESS = 0x2;
        }
        public class Win32Processes
        {

            /// <summary>
            /// Return a list of processes that hold on the given file.
            /// </summary>
            public static List<Process> GetProcessesLockingFile(string filePath)
            {
                var procs = new List<Process>();

                foreach (var process in Process.GetProcesses())
                {
                    var files = GetFilesLockedBy(process);
                    if (files.Contains(filePath)) procs.Add(process);
                }
                return procs;
            }

            /// <summary>
            /// Return a list of file locks held by the process.
            /// </summary>
            public static List<string> GetFilesLockedBy(Process process)
            {
                var outp = new List<string>();

                ThreadStart ts = delegate {
                    /*try
                    {
                        outp = UnsafeGetFilesLockedBy(process);
                    }
                    catch
                    {
                    }*/
                    outp = UnsafeGetFilesLockedBy(process);
                };


                try
                {
                    var t = new Thread(ts);
                    t.Start();
                    if (!t.Join(250))
                    {
                        try
                        {
                            t.Abort();
                        }
                        catch { }
                    }
                }
                catch
                {
                }

                return outp;
            }

            private static List<string> UnsafeGetFilesLockedBy(Process process)
            {
                var handles = GetHandles(process);
                var files = new List<string>();

                for(int i = 0; i < handles.Count; i++)
                {
                    var handle = handles[i];
                    var file = GetFilePath(handle, process);
                    //Console.WriteLine(file);
                    if (file != null) files.Add(file);
                }

                //foreach (var handle in handles)
                //{
                //    var file = GetFilePath(handle, process);
                //    Console.WriteLine(file);
                //    if (file != null) files.Add(file);
                //}

                return files;
                /*try
                {
                    var handles = GetHandles(process);
                    var files = new List<string>();

                    foreach (var handle in handles)
                    {
                        var file = GetFilePath(handle, process);
                        if (file != null) files.Add(file);
                    }

                    return files;
                }
                catch
                {
                    return new List<string>();
                }*/
            }

            const int CNST_SYSTEM_HANDLE_INFORMATION = 16;
            const uint STATUS_INFO_LENGTH_MISMATCH = 0xc0000004;
            private static string GetFilePath(Win32API.SYSTEM_HANDLE_INFORMATION sYSTEM_HANDLE_INFORMATION, Process process)
            {
                IntPtr m_ipProcessHwnd = Win32API.OpenProcess(Win32API.ProcessAccessFlags.All, false, process.Id);
                IntPtr ipHandle = IntPtr.Zero;
                var objBasic = new Win32API.OBJECT_BASIC_INFORMATION();
                IntPtr ipBasic = IntPtr.Zero;
                var objObjectType = new Win32API.OBJECT_TYPE_INFORMATION();
                IntPtr ipObjectType = IntPtr.Zero;
                var objObjectName = new Win32API.OBJECT_NAME_INFORMATION();
                IntPtr ipObjectName = IntPtr.Zero;
                string strObjectTypeName = "";
                string strObjectName = "";
                int nLength = 0;
                int nReturn = 0;
                IntPtr ipTemp = IntPtr.Zero;

                if (!Win32API.DuplicateHandle(m_ipProcessHwnd, sYSTEM_HANDLE_INFORMATION.Handle, Win32API.GetCurrentProcess(), out ipHandle, 0, false, Win32API.DUPLICATE_SAME_ACCESS))
                    return null;

                ipBasic = Marshal.AllocHGlobal(Marshal.SizeOf(objBasic));
                Win32API.NtQueryObject(ipHandle, (int)Win32API.ObjectInformationClass.ObjectBasicInformation, ipBasic, Marshal.SizeOf(objBasic), ref nLength);
                objBasic = (Win32API.OBJECT_BASIC_INFORMATION)Marshal.PtrToStructure(ipBasic, objBasic.GetType());
                Marshal.FreeHGlobal(ipBasic);


                ipObjectType = Marshal.AllocHGlobal(objBasic.TypeInformationLength);
                nLength = objBasic.TypeInformationLength;
                while ((uint)(nReturn = Win32API.NtQueryObject(ipHandle, (int)Win32API.ObjectInformationClass.ObjectTypeInformation, ipObjectType, nLength, ref nLength)) == Win32API.STATUS_INFO_LENGTH_MISMATCH)
                {
                    Marshal.FreeHGlobal(ipObjectType);
                    ipObjectType = Marshal.AllocHGlobal(nLength);
                }

                objObjectType = (Win32API.OBJECT_TYPE_INFORMATION)Marshal.PtrToStructure(ipObjectType, objObjectType.GetType());
                if (Is64Bits())
                {
                    ipTemp = new IntPtr(Convert.ToInt64(objObjectType.Name.Buffer.ToString(), 10) >> 32);
                }
                else
                {
                    ipTemp = objObjectType.Name.Buffer;
                }

                strObjectTypeName = Marshal.PtrToStringUni(ipTemp, objObjectType.Name.Length >> 1);
                Marshal.FreeHGlobal(ipObjectType);
                if (strObjectTypeName != "File")
                    return null;

                nLength = objBasic.NameInformationLength;

                ipObjectName = Marshal.AllocHGlobal(nLength);
                while ((uint)(nReturn = Win32API.NtQueryObject(ipHandle, (int)Win32API.ObjectInformationClass.ObjectNameInformation, ipObjectName, nLength, ref nLength)) == Win32API.STATUS_INFO_LENGTH_MISMATCH)
                {
                    Marshal.FreeHGlobal(ipObjectName);
                    ipObjectName = Marshal.AllocHGlobal(nLength);
                }
                objObjectName = (Win32API.OBJECT_NAME_INFORMATION)Marshal.PtrToStructure(ipObjectName, objObjectName.GetType());
                //
                if (Is64Bits())
                {
                    ipTemp = new IntPtr(Convert.ToInt64(objObjectName.Name.Buffer.ToString(), 10) >> 32);
                }
                else
                {
                    ipTemp = objObjectName.Name.Buffer;
                }

                if (ipTemp != IntPtr.Zero)
                {
                    if(nLength < 0)
                    {
                        return null;
                    }
                    byte[] baTemp = new byte[nLength];
                    try
                    {
                        Marshal.Copy(ipTemp, baTemp, 0, nLength);

                        strObjectName = Marshal.PtrToStringUni(Is64Bits() ? new IntPtr(ipTemp.ToInt64()) : new IntPtr(ipTemp.ToInt32()));
                    }
                    catch (Exception)    //AccessViolationException)
                    {
                        return null;
                    }
                    finally
                    {
                        Marshal.FreeHGlobal(ipObjectName);
                        Win32API.CloseHandle(ipHandle);
                    }
                }

                string path = GetRegularFileNameFromDevice(strObjectName);
                try
                {
                    return path;
                }
                catch
                {
                    return null;
                }
            }

            private static string GetRegularFileNameFromDevice(string strRawName)
            {
                string strFileName = strRawName;
                foreach (string strDrivePath in Environment.GetLogicalDrives())
                {
                    StringBuilder sbTargetPath = new StringBuilder(Win32API.MAX_PATH);
                    if (Win32API.QueryDosDevice(strDrivePath.Substring(0, 2), sbTargetPath, Win32API.MAX_PATH) == 0)
                    {
                        return strRawName;
                    }
                    string strTargetPath = sbTargetPath.ToString();
                    if (strFileName.StartsWith(strTargetPath))
                    {
                        strFileName = strFileName.Replace(strTargetPath, strDrivePath.Substring(0, 2));
                        break;
                    }
                }
                return strFileName;
            }

            private static List<Win32API.SYSTEM_HANDLE_INFORMATION> GetHandles(Process process)
            {
                uint nStatus;
                int nHandleInfoSize = 0x10000;
                IntPtr ipHandlePointer = Marshal.AllocHGlobal(nHandleInfoSize);
                int nLength = 0;
                IntPtr ipHandle = IntPtr.Zero;

                while ((nStatus = Win32API.NtQuerySystemInformation(CNST_SYSTEM_HANDLE_INFORMATION, ipHandlePointer, nHandleInfoSize, ref nLength)) == STATUS_INFO_LENGTH_MISMATCH)
                {
                    nHandleInfoSize = nLength;
                    Marshal.FreeHGlobal(ipHandlePointer);
                    ipHandlePointer = Marshal.AllocHGlobal(nLength);
                }

                byte[] baTemp = new byte[nLength];
                Marshal.Copy(ipHandlePointer, baTemp, 0, nLength);

                long lHandleCount = 0;
                if (Is64Bits())
                {
                    lHandleCount = Marshal.ReadInt64(ipHandlePointer);
                    ipHandle = new IntPtr(ipHandlePointer.ToInt64() + 8);
                }
                else
                {
                    lHandleCount = Marshal.ReadInt32(ipHandlePointer);
                    ipHandle = new IntPtr(ipHandlePointer.ToInt32() + 4);
                }

                Win32API.SYSTEM_HANDLE_INFORMATION shHandle;
                List<Win32API.SYSTEM_HANDLE_INFORMATION> lstHandles = new List<Win32API.SYSTEM_HANDLE_INFORMATION>();

                for (long lIndex = 0; lIndex < lHandleCount; lIndex++)
                {
                    shHandle = new Win32API.SYSTEM_HANDLE_INFORMATION();
                    if (Is64Bits())
                    {
                        shHandle = (Win32API.SYSTEM_HANDLE_INFORMATION)Marshal.PtrToStructure(ipHandle, shHandle.GetType());
                        ipHandle = new IntPtr(ipHandle.ToInt64() + Marshal.SizeOf(shHandle) + 8);
                    }
                    else
                    {
                        ipHandle = new IntPtr(ipHandle.ToInt64() + Marshal.SizeOf(shHandle));
                        shHandle = (Win32API.SYSTEM_HANDLE_INFORMATION)Marshal.PtrToStructure(ipHandle, shHandle.GetType());
                    }
                    if (shHandle.ProcessID != process.Id) continue;
                    lstHandles.Add(shHandle);
                }
                return lstHandles;

            }

            private static bool Is64Bits()
            {
                return Marshal.SizeOf(typeof(IntPtr)) == 8 ? true : false;
            }
        }
    }
}

答案 2 :(得分:0)

user3788486 的答案中的解决方案有效,但在 ~430 行的末尾缺少 Marshal.FreeHGlobal(ipHandlePointer);,导致内存泄漏。

此更改后的代码如下所示:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace HandleUtil
{
    class Program
    {


        static void Main(string[] args)
        {
            List<Process> procs = Win32Processes.GetProcessesLockingFile("\\Device\\0000003a");
            foreach(var proc in procs)
            {
                Console.WriteLine(proc.ProcessName);
            }
            Console.ReadLine();
        }



        internal class Win32API
        {
            [DllImport("ntdll.dll")]
            public static extern int NtQueryObject(IntPtr ObjectHandle, int
                ObjectInformationClass, IntPtr ObjectInformation, int ObjectInformationLength,
                ref int returnLength);

            [DllImport("kernel32.dll", SetLastError = true)]
            public static extern uint QueryDosDevice(string lpDeviceName, StringBuilder lpTargetPath, int ucchMax);

            [DllImport("ntdll.dll")]
            public static extern uint NtQuerySystemInformation(int
                SystemInformationClass, IntPtr SystemInformation, int SystemInformationLength,
                ref int returnLength);

            [DllImport("kernel32.dll")]
            public static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
            [DllImport("kernel32.dll")]
            public static extern int CloseHandle(IntPtr hObject);
            [DllImport("kernel32.dll", SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool DuplicateHandle(IntPtr hSourceProcessHandle,
               ushort hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle,
               uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwOptions);
            [DllImport("kernel32.dll")]
            public static extern IntPtr GetCurrentProcess();

            public enum ObjectInformationClass : int
            {
                ObjectBasicInformation = 0,
                ObjectNameInformation = 1,
                ObjectTypeInformation = 2,
                ObjectAllTypesInformation = 3,
                ObjectHandleInformation = 4
            }

            [Flags]
            public enum ProcessAccessFlags : uint
            {
                All = 0x001F0FFF,
                Terminate = 0x00000001,
                CreateThread = 0x00000002,
                VMOperation = 0x00000008,
                VMRead = 0x00000010,
                VMWrite = 0x00000020,
                DupHandle = 0x00000040,
                SetInformation = 0x00000200,
                QueryInformation = 0x00000400,
                Synchronize = 0x00100000
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct OBJECT_BASIC_INFORMATION
            { // Information Class 0
                public int Attributes;
                public int GrantedAccess;
                public int HandleCount;
                public int PointerCount;
                public int PagedPoolUsage;
                public int NonPagedPoolUsage;
                public int Reserved1;
                public int Reserved2;
                public int Reserved3;
                public int NameInformationLength;
                public int TypeInformationLength;
                public int SecurityDescriptorLength;
                public System.Runtime.InteropServices.ComTypes.FILETIME CreateTime;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct OBJECT_TYPE_INFORMATION
            { // Information Class 2
                public UNICODE_STRING Name;
                public int ObjectCount;
                public int HandleCount;
                public int Reserved1;
                public int Reserved2;
                public int Reserved3;
                public int Reserved4;
                public int PeakObjectCount;
                public int PeakHandleCount;
                public int Reserved5;
                public int Reserved6;
                public int Reserved7;
                public int Reserved8;
                public int InvalidAttributes;
                public GENERIC_MAPPING GenericMapping;
                public int ValidAccess;
                public byte Unknown;
                public byte MaintainHandleDatabase;
                public int PoolType;
                public int PagedPoolUsage;
                public int NonPagedPoolUsage;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct OBJECT_NAME_INFORMATION
            { // Information Class 1
                public UNICODE_STRING Name;
            }

            [StructLayout(LayoutKind.Sequential, Pack = 1)]
            public struct UNICODE_STRING
            {
                public ushort Length;
                public ushort MaximumLength;
                public IntPtr Buffer;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct GENERIC_MAPPING
            {
                public int GenericRead;
                public int GenericWrite;
                public int GenericExecute;
                public int GenericAll;
            }

            [StructLayout(LayoutKind.Sequential, Pack = 1)]
            public struct SYSTEM_HANDLE_INFORMATION
            { // Information Class 16
                public int ProcessID;
                public byte ObjectTypeNumber;
                public byte Flags; // 0x01 = PROTECT_FROM_CLOSE, 0x02 = INHERIT
                public ushort Handle;
                public int Object_Pointer;
                public UInt32 GrantedAccess;
            }

            public const int MAX_PATH = 260;
            public const uint STATUS_INFO_LENGTH_MISMATCH = 0xC0000004;
            public const int DUPLICATE_SAME_ACCESS = 0x2;
        }
        public class Win32Processes
        {

            /// <summary>
            /// Return a list of processes that hold on the given file.
            /// </summary>
            public static List<Process> GetProcessesLockingFile(string filePath)
            {
                var procs = new List<Process>();

                foreach (var process in Process.GetProcesses())
                {
                    var files = GetFilesLockedBy(process);
                    if (files.Contains(filePath)) procs.Add(process);
                }
                return procs;
            }

            /// <summary>
            /// Return a list of file locks held by the process.
            /// </summary>
            public static List<string> GetFilesLockedBy(Process process)
            {
                var outp = new List<string>();

                ThreadStart ts = delegate {
                    /*try
                    {
                        outp = UnsafeGetFilesLockedBy(process);
                    }
                    catch
                    {
                    }*/
                    outp = UnsafeGetFilesLockedBy(process);
                };


                try
                {
                    var t = new Thread(ts);
                    t.Start();
                    if (!t.Join(250))
                    {
                        try
                        {
                            t.Abort();
                        }
                        catch { }
                    }
                }
                catch
                {
                }

                return outp;
            }
            
            private static List<string> UnsafeGetFilesLockedBy(Process process)
            {
                var handles = GetHandles(process);
                var files = new List<string>();

                for(int i = 0; i < handles.Count; i++)
                {
                    var handle = handles[i];
                    var file = GetFilePath(handle, process);
                    //Console.WriteLine(file);
                    if (file != null) files.Add(file);
                }

                //foreach (var handle in handles)
                //{
                //    var file = GetFilePath(handle, process);
                //    Console.WriteLine(file);
                //    if (file != null) files.Add(file);
                //}

                return files;
                /*try
                {
                    var handles = GetHandles(process);
                    var files = new List<string>();

                    foreach (var handle in handles)
                    {
                        var file = GetFilePath(handle, process);
                        if (file != null) files.Add(file);
                    }

                    return files;
                }
                catch
                {
                    return new List<string>();
                }*/
            }

            const int CNST_SYSTEM_HANDLE_INFORMATION = 16;
            const uint STATUS_INFO_LENGTH_MISMATCH = 0xc0000004;
            private static string GetFilePath(Win32API.SYSTEM_HANDLE_INFORMATION sYSTEM_HANDLE_INFORMATION, Process process)
            {
                IntPtr m_ipProcessHwnd = Win32API.OpenProcess(Win32API.ProcessAccessFlags.All, false, process.Id);
                IntPtr ipHandle = IntPtr.Zero;
                var objBasic = new Win32API.OBJECT_BASIC_INFORMATION();
                IntPtr ipBasic = IntPtr.Zero;
                var objObjectType = new Win32API.OBJECT_TYPE_INFORMATION();
                IntPtr ipObjectType = IntPtr.Zero;
                var objObjectName = new Win32API.OBJECT_NAME_INFORMATION();
                IntPtr ipObjectName = IntPtr.Zero;
                string strObjectTypeName = "";
                string strObjectName = "";
                int nLength = 0;
                int nReturn = 0;
                IntPtr ipTemp = IntPtr.Zero;

                if (!Win32API.DuplicateHandle(m_ipProcessHwnd, sYSTEM_HANDLE_INFORMATION.Handle, Win32API.GetCurrentProcess(), out ipHandle, 0, false, Win32API.DUPLICATE_SAME_ACCESS))
                    return null;

                ipBasic = Marshal.AllocHGlobal(Marshal.SizeOf(objBasic));
                Win32API.NtQueryObject(ipHandle, (int)Win32API.ObjectInformationClass.ObjectBasicInformation, ipBasic, Marshal.SizeOf(objBasic), ref nLength);
                objBasic = (Win32API.OBJECT_BASIC_INFORMATION)Marshal.PtrToStructure(ipBasic, objBasic.GetType());
                Marshal.FreeHGlobal(ipBasic);


                ipObjectType = Marshal.AllocHGlobal(objBasic.TypeInformationLength);
                nLength = objBasic.TypeInformationLength;
                while ((uint)(nReturn = Win32API.NtQueryObject(ipHandle, (int)Win32API.ObjectInformationClass.ObjectTypeInformation, ipObjectType, nLength, ref nLength)) == Win32API.STATUS_INFO_LENGTH_MISMATCH)
                {
                    Marshal.FreeHGlobal(ipObjectType);
                    ipObjectType = Marshal.AllocHGlobal(nLength);
                }

                objObjectType = (Win32API.OBJECT_TYPE_INFORMATION)Marshal.PtrToStructure(ipObjectType, objObjectType.GetType());
                if (Is64Bits())
                {
                    ipTemp = new IntPtr(Convert.ToInt64(objObjectType.Name.Buffer.ToString(), 10) >> 32);
                }
                else
                {
                    ipTemp = objObjectType.Name.Buffer;
                }

                strObjectTypeName = Marshal.PtrToStringUni(ipTemp, objObjectType.Name.Length >> 1);
                Marshal.FreeHGlobal(ipObjectType);
                if (strObjectTypeName != "File")
                    return null;

                nLength = objBasic.NameInformationLength;

                ipObjectName = Marshal.AllocHGlobal(nLength);
                while ((uint)(nReturn = Win32API.NtQueryObject(ipHandle, (int)Win32API.ObjectInformationClass.ObjectNameInformation, ipObjectName, nLength, ref nLength)) == Win32API.STATUS_INFO_LENGTH_MISMATCH)
                {
                    Marshal.FreeHGlobal(ipObjectName);
                    ipObjectName = Marshal.AllocHGlobal(nLength);
                }
                objObjectName = (Win32API.OBJECT_NAME_INFORMATION)Marshal.PtrToStructure(ipObjectName, objObjectName.GetType());
                //
                if (Is64Bits())
                {
                    ipTemp = new IntPtr(Convert.ToInt64(objObjectName.Name.Buffer.ToString(), 10) >> 32);
                }
                else
                {
                    ipTemp = objObjectName.Name.Buffer;
                }

                if (ipTemp != IntPtr.Zero)
                {
                    if(nLength < 0)
                    {
                        return null;
                    }
                    byte[] baTemp = new byte[nLength];
                    try
                    {
                        Marshal.Copy(ipTemp, baTemp, 0, nLength);

                        strObjectName = Marshal.PtrToStringUni(Is64Bits() ? new IntPtr(ipTemp.ToInt64()) : new IntPtr(ipTemp.ToInt32()));
                    }
                    catch (Exception)    //AccessViolationException)
                    {
                        return null;
                    }
                    finally
                    {
                        Marshal.FreeHGlobal(ipObjectName);
                        Win32API.CloseHandle(ipHandle);
                    }
                }

                string path = GetRegularFileNameFromDevice(strObjectName);
                try
                {
                    return path;
                }
                catch
                {
                    return null;
                }
            }

            private static string GetRegularFileNameFromDevice(string strRawName)
            {
                string strFileName = strRawName;
                foreach (string strDrivePath in Environment.GetLogicalDrives())
                {
                    StringBuilder sbTargetPath = new StringBuilder(Win32API.MAX_PATH);
                    if (Win32API.QueryDosDevice(strDrivePath.Substring(0, 2), sbTargetPath, Win32API.MAX_PATH) == 0)
                    {
                        return strRawName;
                    }
                    string strTargetPath = sbTargetPath.ToString();
                    if (strFileName.StartsWith(strTargetPath))
                    {
                        strFileName = strFileName.Replace(strTargetPath, strDrivePath.Substring(0, 2));
                        break;
                    }
                }
                return strFileName;
            }

            private static List<Win32API.SYSTEM_HANDLE_INFORMATION> GetHandles(Process process)
            {
                uint nStatus;
                int nHandleInfoSize = 0x10000;
                IntPtr ipHandlePointer = Marshal.AllocHGlobal(nHandleInfoSize);
                int nLength = 0;
                IntPtr ipHandle = IntPtr.Zero;

                while ((nStatus = Win32API.NtQuerySystemInformation(CNST_SYSTEM_HANDLE_INFORMATION, ipHandlePointer, nHandleInfoSize, ref nLength)) == STATUS_INFO_LENGTH_MISMATCH)
                {
                    nHandleInfoSize = nLength;
                    Marshal.FreeHGlobal(ipHandlePointer);
                    ipHandlePointer = Marshal.AllocHGlobal(nLength);
                }

                byte[] baTemp = new byte[nLength];
                Marshal.Copy(ipHandlePointer, baTemp, 0, nLength);

                long lHandleCount = 0;
                if (Is64Bits())
                {
                    lHandleCount = Marshal.ReadInt64(ipHandlePointer);
                    ipHandle = new IntPtr(ipHandlePointer.ToInt64() + 8);
                }
                else
                {
                    lHandleCount = Marshal.ReadInt32(ipHandlePointer);
                    ipHandle = new IntPtr(ipHandlePointer.ToInt32() + 4);
                }

                Win32API.SYSTEM_HANDLE_INFORMATION shHandle;
                List<Win32API.SYSTEM_HANDLE_INFORMATION> lstHandles = new List<Win32API.SYSTEM_HANDLE_INFORMATION>();

                for (long lIndex = 0; lIndex < lHandleCount; lIndex++)
                {
                    shHandle = new Win32API.SYSTEM_HANDLE_INFORMATION();
                    if (Is64Bits())
                    {
                        shHandle = (Win32API.SYSTEM_HANDLE_INFORMATION)Marshal.PtrToStructure(ipHandle, shHandle.GetType());
                        ipHandle = new IntPtr(ipHandle.ToInt64() + Marshal.SizeOf(shHandle) + 8);
                    }
                    else
                    {
                        ipHandle = new IntPtr(ipHandle.ToInt64() + Marshal.SizeOf(shHandle));
                        shHandle = (Win32API.SYSTEM_HANDLE_INFORMATION)Marshal.PtrToStructure(ipHandle, shHandle.GetType());
                    }
                    if (shHandle.ProcessID != process.Id) continue;
                    lstHandles.Add(shHandle);
                }

                Marshal.FreeHGlobal(ipHandlePointer);

                return lstHandles;

            }

            private static bool Is64Bits()
            {
                return Marshal.SizeOf(typeof(IntPtr)) == 8 ? true : false;
            }
        }
    }
}