1 //------------------------------------------------------------------------------
2 // <copyright file="StopListeningWaitHandle.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 //------------------------------------------------------------------------------
7 namespace System.Web.Util {
8 using Microsoft.Win32.SafeHandles;
10 using System.Diagnostics.CodeAnalysis;
11 using System.Runtime.ConstrainedExecution;
12 using System.Runtime.InteropServices;
13 using System.Security;
14 using System.Threading;
15 using System.Web.Hosting;
17 // This is a ManualResetEvent that corresponds to the OnGlobalStopListening event.
18 internal sealed class StopListeningWaitHandle : WaitHandle {
19 [SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources", Justification = @"This is a pseudohandle so shouldn't be closed.")]
20 private static IntPtr _processHandle = GetCurrentProcess();
22 public StopListeningWaitHandle() {
23 // This handle is process-wide and not ref counted, so no need to wrap inside a SafeHandle
24 IntPtr eventHandle = UnsafeIISMethods.MgdGetStopListeningEventHandle();
26 // Per documentation for RegisterWaitForSingleObject, we need to duplicate handles
27 // before asynchronously waiting on them.
28 SafeWaitHandle safeWaitHandle;
29 bool succeeded = DuplicateHandle(
30 hSourceProcessHandle: _processHandle,
31 hSourceHandle: eventHandle,
32 hTargetProcessHandle: _processHandle,
33 lpTargetHandle: out safeWaitHandle,
35 bInheritHandle: false,
36 dwOptions: 2 /* DUPLICATE_SAME_ACCESS */);
39 int hr = Marshal.GetHRForLastWin32Error();
40 Marshal.ThrowExceptionForHR(hr);
43 this.SafeWaitHandle = safeWaitHandle;
46 [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
47 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
48 [SuppressUnmanagedCodeSecurity]
49 [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "We carefully control this method's callers.")]
50 private static extern IntPtr GetCurrentProcess();
52 [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
53 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
54 [SuppressUnmanagedCodeSecurity]
55 [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "We carefully control this method's callers.")]
56 private static extern bool DuplicateHandle([In] IntPtr hSourceProcessHandle, [In] IntPtr hSourceHandle, [In] IntPtr hTargetProcessHandle, [Out] out SafeWaitHandle lpTargetHandle, [In] uint dwDesiredAccess, [In] bool bInheritHandle, [In] uint dwOptions);