Annotation of cleanflash/CleanFlashCommon/HandleUtil.cs, revision 1.1

1.1     ! root        1: // Taken from: https://github.com/Walkman100/FileLocks
        !             2: using System;
        !             3: using System.Collections.Generic;
        !             4: using System.IO;
        !             5: using System.Runtime.CompilerServices;
        !             6: using System.Runtime.ConstrainedExecution;
        !             7: using System.Runtime.InteropServices;
        !             8: using System.Security.Permissions;
        !             9: using System.Text;
        !            10: using System.Threading;
        !            11: using Microsoft.Win32.SafeHandles;
        !            12: using System.Diagnostics;
        !            13: using System.Linq;
        !            14: 
        !            15: namespace CleanFlashCommon {
        !            16:     public static class HandleUtil {
        !            17: 
        !            18:         private static Dictionary<string, string> deviceMap;
        !            19:         private const string networkDevicePrefix = "\\Device\\LanmanRedirector\\";
        !            20:         private const int MAX_PATH = 260;
        !            21:         private const int handleTypeTokenCount = 27;
        !            22:         private static readonly string[] handleTypeTokens = new string[] {
        !            23:             "", "", "Directory", "SymbolicLink", "Token",
        !            24:             "Process", "Thread", "Unknown7", "Event", "EventPair", "Mutant",
        !            25:             "Unknown11", "Semaphore", "Timer", "Profile", "WindowStation",
        !            26:             "Desktop", "Section", "Key", "Port", "WaitablePort",
        !            27:             "Unknown21", "Unknown22", "Unknown23", "Unknown24",
        !            28:             "IoCompletion", "File"
        !            29:         };
        !            30: 
        !            31:         internal enum NT_STATUS {
        !            32:             STATUS_SUCCESS = 0x00000000,
        !            33:             STATUS_BUFFER_OVERFLOW = unchecked((int)0x80000005L),
        !            34:             STATUS_INFO_LENGTH_MISMATCH = unchecked((int)0xC0000004L)
        !            35:         }
        !            36: 
        !            37:         internal enum SYSTEM_INFORMATION_CLASS {
        !            38:             SystemBasicInformation = 0,
        !            39:             SystemPerformanceInformation = 2,
        !            40:             SystemTimeOfDayInformation = 3,
        !            41:             SystemProcessInformation = 5,
        !            42:             SystemProcessorPerformanceInformation = 8,
        !            43:             SystemHandleInformation = 16,
        !            44:             SystemInterruptInformation = 23,
        !            45:             SystemExceptionInformation = 33,
        !            46:             SystemRegistryQuotaInformation = 37,
        !            47:             SystemLookasideInformation = 45
        !            48:         }
        !            49: 
        !            50:         internal enum OBJECT_INFORMATION_CLASS {
        !            51:             ObjectBasicInformation = 0,
        !            52:             ObjectNameInformation = 1,
        !            53:             ObjectTypeInformation = 2,
        !            54:             ObjectAllTypesInformation = 3,
        !            55:             ObjectHandleInformation = 4
        !            56:         }
        !            57: 
        !            58:         [Flags]
        !            59:         internal enum ProcessAccessRights {
        !            60:             PROCESS_DUP_HANDLE = 0x00000040
        !            61:         }
        !            62: 
        !            63:         [Flags]
        !            64:         internal enum DuplicateHandleOptions {
        !            65:             DUPLICATE_CLOSE_SOURCE = 0x1,
        !            66:             DUPLICATE_SAME_ACCESS = 0x2
        !            67:         }
        !            68: 
        !            69:         private enum SystemHandleType {
        !            70:             OB_TYPE_UNKNOWN = 0,
        !            71:             OB_TYPE_TYPE = 1,
        !            72:             OB_TYPE_DIRECTORY,
        !            73:             OB_TYPE_SYMBOLIC_LINK,
        !            74:             OB_TYPE_TOKEN,
        !            75:             OB_TYPE_PROCESS,
        !            76:             OB_TYPE_THREAD,
        !            77:             OB_TYPE_UNKNOWN_7,
        !            78:             OB_TYPE_EVENT,
        !            79:             OB_TYPE_EVENT_PAIR,
        !            80:             OB_TYPE_MUTANT,
        !            81:             OB_TYPE_UNKNOWN_11,
        !            82:             OB_TYPE_SEMAPHORE,
        !            83:             OB_TYPE_TIMER,
        !            84:             OB_TYPE_PROFILE,
        !            85:             OB_TYPE_WINDOW_STATION,
        !            86:             OB_TYPE_DESKTOP,
        !            87:             OB_TYPE_SECTION,
        !            88:             OB_TYPE_KEY,
        !            89:             OB_TYPE_PORT,
        !            90:             OB_TYPE_WAITABLE_PORT,
        !            91:             OB_TYPE_UNKNOWN_21,
        !            92:             OB_TYPE_UNKNOWN_22,
        !            93:             OB_TYPE_UNKNOWN_23,
        !            94:             OB_TYPE_UNKNOWN_24,
        !            95:             OB_TYPE_IO_COMPLETION,
        !            96:             OB_TYPE_FILE
        !            97:         };
        !            98: 
        !            99:         [StructLayout(LayoutKind.Sequential)]
        !           100:         private struct SYSTEM_HANDLE_ENTRY {
        !           101:             public int OwnerPid;
        !           102:             public byte ObjectType;
        !           103:             public byte HandleFlags;
        !           104:             public short HandleValue;
        !           105:             public int ObjectPointer;
        !           106:             public int AccessMask;
        !           107:         }
        !           108: 
        !           109:         [DllImport("ntdll.dll")]
        !           110:         internal static extern NT_STATUS NtQuerySystemInformation(
        !           111:             [In] SYSTEM_INFORMATION_CLASS SystemInformationClass,
        !           112:             [In] IntPtr SystemInformation,
        !           113:             [In] int SystemInformationLength,
        !           114:             [Out] out int ReturnLength);
        !           115: 
        !           116:         [DllImport("ntdll.dll")]
        !           117:         internal static extern NT_STATUS NtQueryObject(
        !           118:             [In] IntPtr Handle,
        !           119:             [In] OBJECT_INFORMATION_CLASS ObjectInformationClass,
        !           120:             [In] IntPtr ObjectInformation,
        !           121:             [In] int ObjectInformationLength,
        !           122:             [Out] out int ReturnLength);
        !           123: 
        !           124:         [DllImport("kernel32.dll", SetLastError = true)]
        !           125:         internal static extern SafeProcessHandle OpenProcess(
        !           126:             [In] ProcessAccessRights dwDesiredAccess,
        !           127:             [In, MarshalAs(UnmanagedType.Bool)] bool bInheritHandle,
        !           128:             [In] int dwProcessId);
        !           129: 
        !           130:         [DllImport("kernel32.dll", SetLastError = true)]
        !           131:         [return: MarshalAs(UnmanagedType.Bool)]
        !           132:         internal static extern bool DuplicateHandle(
        !           133:             [In] IntPtr hSourceProcessHandle,
        !           134:             [In] IntPtr hSourceHandle,
        !           135:             [In] IntPtr hTargetProcessHandle,
        !           136:             [Out] out SafeObjectHandle lpTargetHandle,
        !           137:             [In] int dwDesiredAccess,
        !           138:             [In, MarshalAs(UnmanagedType.Bool)] bool bInheritHandle,
        !           139:             [In] DuplicateHandleOptions dwOptions);
        !           140: 
        !           141:         [DllImport("kernel32.dll")]
        !           142:         internal static extern IntPtr GetCurrentProcess();
        !           143: 
        !           144:         [DllImport("kernel32.dll", SetLastError = true)]
        !           145:         internal static extern int GetProcessId(
        !           146:             [In] IntPtr Process);
        !           147: 
        !           148:         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        !           149:         [DllImport("kernel32.dll", SetLastError = true)]
        !           150:         [return: MarshalAs(UnmanagedType.Bool)]
        !           151:         internal static extern bool CloseHandle(
        !           152:             [In] IntPtr hObject);
        !           153: 
        !           154:         [DllImport("kernel32.dll", SetLastError = true)]
        !           155:         internal static extern int QueryDosDevice(
        !           156:             [In] string lpDeviceName,
        !           157:             [Out] StringBuilder lpTargetPath,
        !           158:             [In] int ucchMax);
        !           159: 
        !           160:         [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
        !           161:         internal sealed class SafeObjectHandle : SafeHandleZeroOrMinusOneIsInvalid {
        !           162:             private SafeObjectHandle() : base(true) { }
        !           163: 
        !           164:             internal SafeObjectHandle(IntPtr preexistingHandle, bool ownsHandle) : base(ownsHandle) {
        !           165:                 base.SetHandle(preexistingHandle);
        !           166:             }
        !           167: 
        !           168:             protected override bool ReleaseHandle() {
        !           169:                 return CloseHandle(base.handle);
        !           170:             }
        !           171:         }
        !           172: 
        !           173:         [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
        !           174:         internal sealed class SafeProcessHandle : SafeHandleZeroOrMinusOneIsInvalid {
        !           175:             private SafeProcessHandle()
        !           176:                 : base(true) { }
        !           177: 
        !           178:             internal SafeProcessHandle(IntPtr preexistingHandle, bool ownsHandle)
        !           179:                 : base(ownsHandle) {
        !           180:                 base.SetHandle(preexistingHandle);
        !           181:             }
        !           182: 
        !           183:             protected override bool ReleaseHandle() {
        !           184:                 return CloseHandle(base.handle);
        !           185:             }
        !           186:         }
        !           187: 
        !           188:         private sealed class OpenFiles : IEnumerable<string> {
        !           189:             private readonly int processId;
        !           190: 
        !           191:             internal OpenFiles(int processId) {
        !           192:                 this.processId = processId;
        !           193:             }
        !           194: 
        !           195:             public IEnumerator<string> GetEnumerator() {
        !           196:                 NT_STATUS ret;
        !           197:                 int length = 0x10000;
        !           198:                 // Loop, probing for required memory.
        !           199: 
        !           200:                 do {
        !           201:                     IntPtr ptr = IntPtr.Zero;
        !           202:                     RuntimeHelpers.PrepareConstrainedRegions();
        !           203: 
        !           204:                     try {
        !           205:                         RuntimeHelpers.PrepareConstrainedRegions();
        !           206: 
        !           207:                         try { } finally {
        !           208:                             // CER guarantees that the address of the allocated 
        !           209:                             // memory is actually assigned to ptr if an 
        !           210:                             // asynchronous exception occurs.
        !           211:                             ptr = Marshal.AllocHGlobal(length);
        !           212:                         }
        !           213: 
        !           214:                         ret = NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS.SystemHandleInformation, ptr, length, out int returnLength);
        !           215: 
        !           216:                         if (ret == NT_STATUS.STATUS_INFO_LENGTH_MISMATCH) {
        !           217:                             // Round required memory up to the nearest 64KB boundary.
        !           218:                             length = (returnLength + 0xffff) & ~0xffff;
        !           219:                         } else if (ret == NT_STATUS.STATUS_SUCCESS) {
        !           220:                             int handleCount = Marshal.ReadInt32(ptr);
        !           221:                             int offset = sizeof(int);
        !           222:                             int size = Marshal.SizeOf(typeof(SYSTEM_HANDLE_ENTRY));
        !           223: 
        !           224:                             for (int i = 0; i < handleCount; i++) {
        !           225:                                 SYSTEM_HANDLE_ENTRY handleEntry = (SYSTEM_HANDLE_ENTRY) Marshal.PtrToStructure((IntPtr)((int)ptr + offset), typeof(SYSTEM_HANDLE_ENTRY));
        !           226:                                 
        !           227:                                 if (handleEntry.OwnerPid == processId) {
        !           228:                                     IntPtr handle = (IntPtr) handleEntry.HandleValue;
        !           229:                                     SystemHandleType handleType;
        !           230: 
        !           231:                                     if (GetHandleType(handle, handleEntry.OwnerPid, out handleType) && handleType == SystemHandleType.OB_TYPE_FILE) {
        !           232:                                         if (GetFileNameFromHandle(handle, handleEntry.OwnerPid, out string devicePath)) {
        !           233:                                             if (ConvertDevicePathToDosPath(devicePath, out string dosPath)) {
        !           234:                                                 if (File.Exists(dosPath)) {
        !           235:                                                     yield return dosPath;
        !           236:                                                 } else if (Directory.Exists(dosPath)) {
        !           237:                                                     yield return dosPath;
        !           238:                                                 }
        !           239:                                             }
        !           240:                                         }
        !           241:                                     }
        !           242:                                 }
        !           243: 
        !           244:                                 offset += size;
        !           245:                             }
        !           246:                         }
        !           247:                     } finally {
        !           248:                         // CER guarantees that the allocated memory is freed, 
        !           249:                         // if an asynchronous exception occurs. 
        !           250:                         Marshal.FreeHGlobal(ptr);
        !           251:                     }
        !           252:                 } while (ret == NT_STATUS.STATUS_INFO_LENGTH_MISMATCH);
        !           253:             }
        !           254: 
        !           255:             System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
        !           256:                 return GetEnumerator();
        !           257:             }
        !           258:         }
        !           259: 
        !           260:         private class FileNameFromHandleState : IDisposable {
        !           261:             private readonly ManualResetEvent _mr;
        !           262:             public IntPtr Handle { get; }
        !           263:             public string FileName { get; set; }
        !           264:             public bool RetValue { get; set; }
        !           265: 
        !           266:             public FileNameFromHandleState(IntPtr handle) {
        !           267:                 _mr = new ManualResetEvent(false);
        !           268:                 this.Handle = handle;
        !           269:             }
        !           270: 
        !           271:             public bool WaitOne(int wait) {
        !           272:                 return _mr.WaitOne(wait, false);
        !           273:             }
        !           274: 
        !           275:             public void Set() {
        !           276:                 try {
        !           277:                     _mr.Set();
        !           278:                 } catch { }
        !           279:             }
        !           280: 
        !           281:             public void Dispose() {
        !           282:                 if (_mr != null) {
        !           283:                     _mr.Close();
        !           284:                 }
        !           285:             }
        !           286:         }
        !           287: 
        !           288:         private static bool GetFileNameFromHandle(IntPtr handle, out string fileName) {
        !           289:             IntPtr ptr = IntPtr.Zero;
        !           290:             RuntimeHelpers.PrepareConstrainedRegions();
        !           291: 
        !           292:             try {
        !           293:                 int length = 0x200;  // 512 bytes
        !           294:                 RuntimeHelpers.PrepareConstrainedRegions();
        !           295: 
        !           296:                 try { } finally {
        !           297:                     // CER guarantees the assignment of the allocated 
        !           298:                     // memory address to ptr, if an ansynchronous exception 
        !           299:                     // occurs.
        !           300:                     ptr = Marshal.AllocHGlobal(length);
        !           301:                 }
        !           302: 
        !           303:                 NT_STATUS ret = NtQueryObject(handle, OBJECT_INFORMATION_CLASS.ObjectNameInformation, ptr, length, out length);
        !           304: 
        !           305:                 if (ret == NT_STATUS.STATUS_BUFFER_OVERFLOW) {
        !           306:                     RuntimeHelpers.PrepareConstrainedRegions();
        !           307:                     try { } finally {
        !           308:                         // CER guarantees that the previous allocation is freed,
        !           309:                         // and that the newly allocated memory address is 
        !           310:                         // assigned to ptr if an asynchronous exception occurs.
        !           311:                         Marshal.FreeHGlobal(ptr);
        !           312:                         ptr = Marshal.AllocHGlobal(length);
        !           313:                     }
        !           314:                     ret = NtQueryObject(handle, OBJECT_INFORMATION_CLASS.ObjectNameInformation, ptr, length, out length);
        !           315:                 }
        !           316:                 if (ret == NT_STATUS.STATUS_SUCCESS) {
        !           317:                     fileName = Marshal.PtrToStringUni((IntPtr)((int)ptr + 8), (length - 9) / 2);
        !           318:                     return fileName.Length != 0;
        !           319:                 }
        !           320:             } finally {
        !           321:                 // CER guarantees that the allocated memory is freed, 
        !           322:                 // if an asynchronous exception occurs.
        !           323:                 Marshal.FreeHGlobal(ptr);
        !           324:             }
        !           325: 
        !           326:             fileName = string.Empty;
        !           327:             return false;
        !           328:         }
        !           329:         private static void GetFileNameFromHandle(object state) {
        !           330:             FileNameFromHandleState s = (FileNameFromHandleState)state;
        !           331: 
        !           332:             s.RetValue = GetFileNameFromHandle(s.Handle, out string fileName);
        !           333:             s.FileName = fileName;
        !           334:             s.Set();
        !           335:         }
        !           336: 
        !           337:         private static bool GetFileNameFromHandle(IntPtr handle, out string fileName, int wait) {
        !           338:             using (FileNameFromHandleState f = new FileNameFromHandleState(handle)) {
        !           339:                 ThreadPool.QueueUserWorkItem(new WaitCallback(GetFileNameFromHandle), f);
        !           340: 
        !           341:                 if (f.WaitOne(wait)) {
        !           342:                     fileName = f.FileName;
        !           343:                     return f.RetValue;
        !           344:                 } else {
        !           345:                     fileName = string.Empty;
        !           346:                     return false;
        !           347:                 }
        !           348:             }
        !           349:         }
        !           350: 
        !           351:         private static bool GetFileNameFromHandle(IntPtr handle, int processId, out string fileName) {
        !           352:             IntPtr currentProcess = GetCurrentProcess();
        !           353:             bool remote = processId != GetProcessId(currentProcess);
        !           354:             SafeProcessHandle processHandle = null;
        !           355:             SafeObjectHandle objectHandle = null;
        !           356: 
        !           357:             try {
        !           358:                 if (remote) {
        !           359:                     processHandle = OpenProcess(ProcessAccessRights.PROCESS_DUP_HANDLE, true, processId);
        !           360:                     if (DuplicateHandle(processHandle.DangerousGetHandle(), handle, currentProcess, out objectHandle, 0, false, DuplicateHandleOptions.DUPLICATE_SAME_ACCESS)) {
        !           361:                         handle = objectHandle.DangerousGetHandle();
        !           362:                     }
        !           363:                 }
        !           364: 
        !           365:                 return GetFileNameFromHandle(handle, out fileName, 200);
        !           366:             } finally {
        !           367:                 if (remote) {
        !           368:                     if (processHandle != null) {
        !           369:                         processHandle.Close();
        !           370:                     }
        !           371: 
        !           372:                     if (objectHandle != null) {
        !           373:                         objectHandle.Close();
        !           374:                     }
        !           375:                 }
        !           376:             }
        !           377:         }
        !           378: 
        !           379:         private static string GetHandleTypeToken(IntPtr handle) {
        !           380:             NtQueryObject(handle, OBJECT_INFORMATION_CLASS.ObjectTypeInformation, IntPtr.Zero, 0, out int length);
        !           381:             IntPtr ptr = IntPtr.Zero;
        !           382:             RuntimeHelpers.PrepareConstrainedRegions();
        !           383: 
        !           384:             try {
        !           385:                 RuntimeHelpers.PrepareConstrainedRegions();
        !           386: 
        !           387:                 try { } finally {
        !           388:                     if (length >= 0) {
        !           389:                         ptr = Marshal.AllocHGlobal(length);
        !           390:                     }
        !           391:                 }
        !           392: 
        !           393:                 if (NtQueryObject(handle, OBJECT_INFORMATION_CLASS.ObjectTypeInformation, ptr, length, out length) == NT_STATUS.STATUS_SUCCESS) {
        !           394:                     return Marshal.PtrToStringUni((IntPtr)((int)ptr + 0x60));
        !           395:                 }
        !           396: 
        !           397:             } finally {
        !           398:                 Marshal.FreeHGlobal(ptr);
        !           399:             }
        !           400: 
        !           401:             return string.Empty;
        !           402:         }
        !           403: 
        !           404:         private static string GetHandleTypeToken(IntPtr handle, int processId) {
        !           405:             IntPtr currentProcess = GetCurrentProcess();
        !           406:             bool remote = processId != GetProcessId(currentProcess);
        !           407:             SafeProcessHandle processHandle = null;
        !           408:             SafeObjectHandle objectHandle = null;
        !           409: 
        !           410:             try {
        !           411:                 if (remote) {
        !           412:                     processHandle = OpenProcess(ProcessAccessRights.PROCESS_DUP_HANDLE, true, processId);
        !           413:                     if (DuplicateHandle(processHandle.DangerousGetHandle(), handle, currentProcess, out objectHandle, 0, false, DuplicateHandleOptions.DUPLICATE_SAME_ACCESS)) {
        !           414:                         handle = objectHandle.DangerousGetHandle();
        !           415:                     }
        !           416:                 }
        !           417: 
        !           418:                 return GetHandleTypeToken(handle);
        !           419:             } finally {
        !           420:                 if (remote) {
        !           421:                     if (processHandle != null) {
        !           422:                         processHandle.Close();
        !           423:                     }
        !           424: 
        !           425:                     if (objectHandle != null) {
        !           426:                         objectHandle.Close();
        !           427:                     }
        !           428:                 }
        !           429:             }
        !           430:         }
        !           431: 
        !           432:         private static bool GetHandleTypeFromToken(string token, out SystemHandleType handleType) {
        !           433:             for (int i = 1; i < handleTypeTokenCount; i++) {
        !           434:                 if (handleTypeTokens[i] == token) {
        !           435:                     handleType = (SystemHandleType) i;
        !           436:                     return true;
        !           437:                 }
        !           438:             }
        !           439: 
        !           440:             handleType = SystemHandleType.OB_TYPE_UNKNOWN;
        !           441:             return false;
        !           442:         }
        !           443: 
        !           444:         private static bool GetHandleType(IntPtr handle, int processId, out SystemHandleType handleType) {
        !           445:             string token = GetHandleTypeToken(handle, processId);
        !           446:             return GetHandleTypeFromToken(token, out handleType);
        !           447:         }
        !           448: 
        !           449:         private static bool ConvertDevicePathToDosPath(string devicePath, out string dosPath) {
        !           450:             EnsureDeviceMap();
        !           451:             int i = devicePath.Length;
        !           452: 
        !           453:             while (i > 0 && (i = devicePath.LastIndexOf('\\', i - 1)) != -1) {
        !           454:                 if (deviceMap.TryGetValue(devicePath.Substring(0, i), out string drive)) {
        !           455:                     dosPath = string.Concat(drive, devicePath.Substring(i));
        !           456:                     return dosPath.Length != 0;
        !           457:                 }
        !           458:             }
        !           459: 
        !           460:             dosPath = string.Empty;
        !           461:             return false;
        !           462:         }
        !           463: 
        !           464:         private static void EnsureDeviceMap() {
        !           465:             if (deviceMap == null) {
        !           466:                 Dictionary<string, string> localDeviceMap = BuildDeviceMap();
        !           467:                 Interlocked.CompareExchange(ref deviceMap, localDeviceMap, null);
        !           468:             }
        !           469:         }
        !           470: 
        !           471:         private static Dictionary<string, string> BuildDeviceMap() {
        !           472:             string[] logicalDrives = Environment.GetLogicalDrives();
        !           473:             Dictionary<string, string> localDeviceMap = new Dictionary<string, string>(logicalDrives.Length);
        !           474:             StringBuilder lpTargetPath = new StringBuilder(MAX_PATH);
        !           475: 
        !           476:             foreach (string drive in logicalDrives) {
        !           477:                 string lpDeviceName = drive.Substring(0, 2);
        !           478:                 QueryDosDevice(lpDeviceName, lpTargetPath, MAX_PATH);
        !           479:                 localDeviceMap.Add(NormalizeDeviceName(lpTargetPath.ToString()), lpDeviceName);
        !           480:             }
        !           481: 
        !           482:             localDeviceMap.Add(networkDevicePrefix.Substring(0, networkDevicePrefix.Length - 1), "\\");
        !           483:             return localDeviceMap;
        !           484:         }
        !           485: 
        !           486:         private static string NormalizeDeviceName(string deviceName) {
        !           487:             if (string.Compare(deviceName, 0, networkDevicePrefix, 0, networkDevicePrefix.Length, StringComparison.InvariantCulture) == 0) {
        !           488:                 string shareName = deviceName.Substring(deviceName.IndexOf('\\', networkDevicePrefix.Length) + 1);
        !           489:                 return string.Concat(networkDevicePrefix, shareName);
        !           490:             }
        !           491: 
        !           492:             return deviceName;
        !           493:         }
        !           494: 
        !           495:         /// <summary>
        !           496:         /// Gets the open files enumerator.
        !           497:         /// </summary>
        !           498:         /// <param name="processId">The process id.</param>
        !           499:         /// <returns></returns>
        !           500:         public static IEnumerable<string> GetOpenFilesEnumerator(int processId) {
        !           501:             return new OpenFiles(processId);
        !           502:         }
        !           503: 
        !           504:         public static List<Process> GetProcessesUsingFile(string fName) {
        !           505:             List<Process> result = new List<Process>();
        !           506:             foreach (Process p in Process.GetProcesses()) {
        !           507:                 try {
        !           508:                     if (GetOpenFilesEnumerator(p.Id).Contains(fName)) {
        !           509:                         result.Add(p);
        !           510:                     }
        !           511:                 } catch { } // Some processes will fail.
        !           512:             }
        !           513:             return result;
        !           514:         }
        !           515: 
        !           516:         public static void KillProcessesUsingFile(string fName) {
        !           517:             foreach (Process process in GetProcessesUsingFile(fName).OrderBy(o => o.StartTime)) {
        !           518:                 try {
        !           519:                     process.Kill();
        !           520:                     process.WaitForExit();
        !           521:                 } catch {
        !           522:                     // Oh well...
        !           523:                 }
        !           524:             }
        !           525:         }
        !           526:     }
        !           527: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.