|  |  | 1 |  | using System; | 
|  |  | 2 |  | using System.IO; | 
|  |  | 3 |  |  | 
|  |  | 4 |  | namespace LockCheck.Windows; | 
|  |  | 5 |  |  | 
|  |  | 6 |  | internal static class Extensions | 
|  |  | 7 |  | { | 
|  |  | 8 |  |     public static bool IsFileLocked(Exception exception) | 
|  |  | 9 |  |     { | 
|  | 2 | 10 |  |         if (exception == null) | 
|  | 2 | 11 |  |             throw new ArgumentNullException(nameof(exception)); | 
|  |  | 12 |  |  | 
|  | 2 | 13 |  |         if (exception is IOException ioException) | 
|  |  | 14 |  |         { | 
|  |  | 15 |  |             // Generally it is not safe / stable to convert HRESULTs to Win32 error codes. It works here, | 
|  |  | 16 |  |             // because we exactly know where we're at. So resist refactoring the following code into an | 
|  |  | 17 |  |             // (maybe even externally visible) method. | 
|  | 2 | 18 |  |             int errorCode = ioException.HResult & ((1 << 16) - 1); | 
|  |  | 19 |  |  | 
|  |  | 20 |  |             // Code coverage note: causing a ERROR_LOCK_VIOLATION is rather hard to achieve in a test. | 
|  |  | 21 |  |             // Basically, you will mostly (always?) get a ERROR_SHARING_VIOLATION, unless you would | 
|  |  | 22 |  |             // do the test via the network (e.g. using a share). Note that using the "\\<computer>\C$" | 
|  |  | 23 |  |             // share will not cut it. | 
|  |  | 24 |  |             // | 
|  |  | 25 |  |             // Also note, that as of current (fall 2024), the .NET runtime does not raise IOException | 
|  |  | 26 |  |             // with ERROR_LOCK_VIOLATION. Since technically, this error is a potential result of a | 
|  |  | 27 |  |             // locking issue, we check for it anyway. | 
|  | 2 | 28 |  |             if (errorCode == NativeMethods.ERROR_LOCK_VIOLATION || | 
|  | 2 | 29 |  |                 errorCode == NativeMethods.ERROR_SHARING_VIOLATION) | 
|  |  | 30 |  |             { | 
|  | 2 | 31 |  |                 return true; | 
|  |  | 32 |  |             } | 
|  |  | 33 |  |         } | 
|  | 2 | 34 |  |         return false; | 
|  |  | 35 |  |     } | 
|  |  | 36 |  | } |