|
1 | 1 | using System.Diagnostics; |
| 2 | +using System.Runtime.InteropServices; |
2 | 3 | using Microsoft.Win32.SafeHandles; |
3 | 4 | using PInvoke; |
4 | 5 | using Windows.Win32; |
@@ -187,19 +188,39 @@ public unsafe (string? v, Exception? ex) ObjectName |
187 | 188 |
|
188 | 189 | #region Methods |
189 | 190 |
|
| 191 | + /// <summary> |
| 192 | + /// Release the system handle. If the handle has the HANDLE_FLAG_PROTECT_FROM_CLOSE attribute, the operation fails.<br/> |
| 193 | + /// ! WARNING !<br/> |
| 194 | + /// If the handle or a duplicate is in use by a driver or other kernel-level software, a function that accesses the now-invalid handle will cause a stopcode (AKA Blue Screen Of Death). |
| 195 | + /// </summary> |
| 196 | + /// <remarks> |
| 197 | + /// See Raymond Chen's devblog article <see href="https://devblogs.microsoft.com/oldnewthing/20070829-00/?p=25363">"Kernel handles are not reference-counted"</see>. |
| 198 | + /// </remarks> |
| 199 | + /// <exception cref="Win32Exception">Failed to open process to duplicate and close object handle.</exception> |
| 200 | + public bool CloseSourceHandle() => CloseSourceHandle(false); |
| 201 | + |
190 | 202 | /// <summary> |
191 | 203 | /// Release the system handle.<br/> |
192 | 204 | /// ! WARNING !<br/> |
193 | 205 | /// If the handle or a duplicate is in use by a driver or other kernel-level software, a function that accesses the now-invalid handle will cause a stopcode (AKA Blue Screen Of Death). |
194 | 206 | /// </summary> |
| 207 | + /// <param name="removeCloseProtection">Some handles have the HANDLE_FLAG_PROTECT_FROM_CLOSE attribute. In this case, the attribute must be removed for the handle to be closed. Otherwise, the operation will fail. This parameter is made available to allow</param> |
195 | 208 | /// <remarks> |
196 | 209 | /// See Raymond Chen's devblog article <see href="https://devblogs.microsoft.com/oldnewthing/20070829-00/?p=25363">"Kernel handles are not reference-counted"</see>. |
197 | 210 | /// </remarks> |
198 | 211 | /// <exception cref="Win32Exception">Failed to open process to duplicate and close object handle.</exception> |
199 | | - public bool CloseSourceHandle() |
| 212 | + public bool CloseSourceHandle(bool removeCloseProtection) |
200 | 213 | { |
201 | 214 | try |
202 | 215 | { |
| 216 | + if (removeCloseProtection |
| 217 | + && ((SysHandleEx.HandleAttributes & Kernel32.HandleFlags.HANDLE_FLAG_PROTECT_FROM_CLOSE) is not 0) |
| 218 | + && !SetHandleInformation(this, (uint)HANDLE_FLAGS.HANDLE_FLAG_PROTECT_FROM_CLOSE, 0)) |
| 219 | + { |
| 220 | + Win32ErrorCode err = (Win32ErrorCode)Marshal.GetLastPInvokeError(); |
| 221 | + throw new PInvoke.Win32Exception(err, "Failed to remove HANDLE_FLAG_PROTECT_FROM_CLOSE attribute; " + err.GetMessage()); |
| 222 | + } |
| 223 | + |
203 | 224 | HANDLE rawHProcess; |
204 | 225 | using SafeProcessHandle hProcess = new( |
205 | 226 | !(rawHProcess = OpenProcess(PROCESS_ACCESS_RIGHTS.PROCESS_DUP_HANDLE, true, ProcessId)).IsNull |
|
0 commit comments