public static Error CloseHandle(Process handleOwnerProcess, FileHandleInfo handle, Process currentProcess)
        {
            SafeProcessHandle remoteProcess = NativeMethods.OpenProcess(ProcessAccessRights.DuplicateHandle, true, handleOwnerProcess.Id);

            bool result = NativeMethods.DuplicateHandle(remoteProcess.DangerousGetHandle(), handle.Handle,
                                                        currentProcess.Handle,
                                                        out SafeObjectHandle duplicateHandle, 0, false,
                                                        DuplicateHandleOptions.CloseSourceHandle);

            if (!result)
            {
                return(Error.DuplicateHandleFails);
            }

            result = NativeMethods.GetHandleInformation(duplicateHandle.DangerousGetHandle(),
                                                        out HandleFlag flag);
            if (!result)
            {
                return(Error.GetHandleInformationFails);
            }

            if (flag == HandleFlag.ProtectFromClose)
            {
                return(Error.HandleProtectedFromClosed);
            }

            result = NativeMethods.CloseHandle(duplicateHandle.DangerousGetHandle());
            if (!result)
            {
                int lastError = Marshal.GetLastWin32Error();
                return((Error)lastError);
            }

            return(Error.None);
        }
Exemple #2
0
        private static bool UnlockFiles(string[] files, Process currentProcess)
        {
            bool found     = false;
            var  processes = Unlocker.FindLockerProcesses(files);

            foreach (RM_PROCESS_INFO info in processes)
            {
                Console.WriteLine($"Closing handle locked by {info.strAppName}...");
                using (SmartPtr sptr = SystemInformation.GetSystemHandleInformation())
                {
                    var information                = (SystemHandlesInformation)Marshal.PtrToStructure(sptr.Pointer, typeof(SystemHandlesInformation));
                    int handleCount                = information.Count;
                    var process                    = Process.GetProcessById(info.Process.dwProcessId);
                    var infoEnumerator             = ProcessHelper.GetCurrentProcessOpenFilesEnumerator(info.Process.dwProcessId, sptr, handleCount);
                    Dictionary <string, bool> skip = new Dictionary <string, bool>();
                    while (infoEnumerator.MoveNext())
                    {
                        FileHandleInfo current = infoEnumerator.Current;
                        skip.TryGetValue(current.FileSystemInfo.FullName, out bool skipped);
                        if (skipped ||
                            files.All(file => string.Compare(file, current.FileSystemInfo.FullName, StringComparison.OrdinalIgnoreCase) != 0))
                        {
                            continue;
                        }

                        Console.WriteLine(
                            $"Found locked file {current.FileSystemInfo.FullName}! {process.ProcessName} -> {process.MainModule.FileName}");
                        found = true;
                        skip[current.FileSystemInfo.FullName] = true;
                        var result = ProcessHelper.CloseHandle(process, current, currentProcess);
                        Console.WriteLine(result == 0 ? "Success." : $"Error: {Enum.GetName(typeof(Error), result)}");
                    }
                }
            }

            return(found);
        }
Exemple #3
0
        public static Error Run(params string[] args)
        {
            if (args == null || args.Length != 1)
            {
                return(Error.InvalidArguments);
            }
            string fileName = args[0];

            if (!File.Exists(fileName))
            {
                return(Error.TargetFileNotFound);
            }

            string[] exclusionProcesses = File.ReadAllLines("ExclusionProcesses.txt");
            string[] exclusionFolders   = File.ReadAllLines("ExclusionFolders.txt");
            Process  currentProcess     = Process.GetCurrentProcess();

            Process[] processes = Process
                                  .GetProcesses()
                                  .Where(x =>
                                         x.HandleCount > 0 &&
                                         !exclusionProcesses.Contains(x.ProcessName.ToLowerInvariant()))
                                  .ToArray();
            Console.WriteLine($"Found {processes.Length} processes.");
            using (SmartPtr sptr = SystemInformation.GetSystemHandleInformation())
            {
                var information = (SystemHandlesInformation)Marshal.PtrToStructure(sptr.Pointer, typeof(SystemHandlesInformation));
                int handleCount = information.Count;
                //int handleCount = Marshal.ReadInt32(sptr.Pointer);
                for (int i = 0; i < processes.Length; i++)
                {
                    Process process = processes[i];
                    if (!ProcessHelper.IsCurrentUserProcess(process.Id))
                    {
                        continue;
                    }

                    if (exclusionFolders.Any(y => process.MainModule.FileName.ToLowerInvariant().StartsWith(y)))
                    {
                        continue;
                    }

                    Console.Write("#");
                    var infoEnumerator = ProcessHelper.GetCurrentProcessOpenFilesEnumerator(process.Id, sptr, handleCount);
                    while (infoEnumerator.MoveNext())
                    {
                        FileHandleInfo current = infoEnumerator.Current;
                        if (string.Compare(fileName, current.FileSystemInfo.FullName, StringComparison.OrdinalIgnoreCase) != 0)
                        {
                            continue;
                        }

                        Console.WriteLine();
                        Console.WriteLine($"Found!: {process.ProcessName} -> {process.MainModule.FileName}");

                        return(ProcessHelper.CloseHandle(process, current, currentProcess));
                    }
                }
            }

            return(Error.HandleNotFound);
        }