/// <summary> /// This method closes the given handle in the given process. To archive that, the handle is duplicated using the /// native method DuplicateHandle - and during the duplication the handle is closed in the remote process. /// </summary> /// <param name="processId">ID of the process hat has the specified handle opened.</param> /// <param name="handle">Handle to be closed.</param> private void CloseHandleInRemoteProcess(int processId, IntPtr handle) { SafeNativeHandle remoteProcess = NativeMethods.OpenProcess(ProcessAccessRights.ProcessDuplicateHandle, true, processId); if (remoteProcess.IsInvalid) { Logger.Log(LogLevel.Verbose, "Process with PID=" + processId + " could not be opened."); return; } IntPtr remoteProcessHandle = remoteProcess.DangerousGetHandle(); IntPtr currentProcessHandle = NativeMethods.GetCurrentProcess(); SafeNativeHandle duplicatedHandle = null; if (NativeMethods.DuplicateHandle(remoteProcessHandle, handle, currentProcessHandle, out duplicatedHandle, 0, false, DuplicateHandleOptions.CloseSource)) { Logger.Log(LogLevel.Verbose, "File closed in process with PID " + processId); NativeMethods.CloseHandle(duplicatedHandle.DangerousGetHandle()); } else { Logger.Log(LogLevel.Verbose, "File could not be closed in process with PID " + processId); } NativeMethods.CloseHandle(remoteProcessHandle); }
/// <summary> /// Returns the type of a handle (as a string). /// </summary> /// <param name="handle">Handle of the object.</param> /// <param name="processId">Process that owns this handle.</param> /// <returns>Type of the handle, i. e. "File".</returns> private static string GetHandleTypeToken(IntPtr handle, int processId) { IntPtr currentProcess = NativeMethods.GetCurrentProcess(); bool remote = processId != NativeMethods.GetProcessId(currentProcess); SafeNativeHandle processHandle = null; SafeNativeHandle objectHandle = null; try { if (remote) { processHandle = NativeMethods.OpenProcess(ProcessAccessRights.ProcessDuplicateHandle, true, processId); if (NativeMethods.DuplicateHandle(processHandle.DangerousGetHandle(), handle, currentProcess, out objectHandle, 0, false, DuplicateHandleOptions.SameAccess)) { handle = objectHandle.DangerousGetHandle(); } } return(GetHandleTypeToken(handle)); } finally { if (remote) { if (processHandle != null) { processHandle.Close(); } if (objectHandle != null) { objectHandle.Close(); } } } }