diff --git a/shadowsocks-csharp/Util/SystemProxy/INTERNET_PER_CONN_OPTION.cs b/shadowsocks-csharp/Util/SystemProxy/INTERNET_PER_CONN_OPTION.cs index 351aa1ca..7a2dbe15 100644 --- a/shadowsocks-csharp/Util/SystemProxy/INTERNET_PER_CONN_OPTION.cs +++ b/shadowsocks-csharp/Util/SystemProxy/INTERNET_PER_CONN_OPTION.cs @@ -76,7 +76,7 @@ namespace Shadowsocks.Util.SystemProxy /// The StructLayout and FieldOffset attributes could help to decrease the struct size. /// [StructLayout(LayoutKind.Explicit)] - public struct INTERNET_PER_CONN_OPTION_OptionUnion + public struct INTERNET_PER_CONN_OPTION_OptionUnion : IDisposable { // A value in INTERNET_OPTION_PER_CONN_FLAGS. [FieldOffset(0)] @@ -85,6 +85,24 @@ namespace Shadowsocks.Util.SystemProxy public System.IntPtr pszValue; [FieldOffset(0)] public System.Runtime.InteropServices.ComTypes.FILETIME ftValue; + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (disposing) + { + if (pszValue != IntPtr.Zero) + { + Marshal.FreeHGlobal(pszValue); + pszValue = IntPtr.Zero; + } + } + } } [StructLayout(LayoutKind.Sequential)] diff --git a/shadowsocks-csharp/Util/SystemProxy/INTERNET_PER_CONN_OPTION_LIST.cs b/shadowsocks-csharp/Util/SystemProxy/INTERNET_PER_CONN_OPTION_LIST.cs index b15870ce..601cde38 100644 --- a/shadowsocks-csharp/Util/SystemProxy/INTERNET_PER_CONN_OPTION_LIST.cs +++ b/shadowsocks-csharp/Util/SystemProxy/INTERNET_PER_CONN_OPTION_LIST.cs @@ -17,22 +17,47 @@ WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. \***************************************************************************/ +using System; using System.Runtime.InteropServices; namespace Shadowsocks.Util.SystemProxy { [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] - public struct INTERNET_PER_CONN_OPTION_LIST + public struct INTERNET_PER_CONN_OPTION_LIST : IDisposable { public int Size; // The connection to be set. NULL means LAN. public System.IntPtr Connection; - + public int OptionCount; public int OptionError; // List of INTERNET_PER_CONN_OPTIONs. public System.IntPtr pOptions; + + public void Dispose() + { + Dispose( true ); + GC.SuppressFinalize( this ); + } + + private void Dispose( bool disposing ) + { + if ( disposing ) + { + if ( Connection != IntPtr.Zero ) + { + Marshal.FreeHGlobal( Connection ); + Connection = IntPtr.Zero; + } + + if ( pOptions != IntPtr.Zero ) + { + Marshal.FreeHGlobal( pOptions ); + pOptions = IntPtr.Zero; + } + } + } } } diff --git a/shadowsocks-csharp/Util/SystemProxy/WinINet.cs b/shadowsocks-csharp/Util/SystemProxy/WinINet.cs index a1de566c..a95a3b5d 100644 --- a/shadowsocks-csharp/Util/SystemProxy/WinINet.cs +++ b/shadowsocks-csharp/Util/SystemProxy/WinINet.cs @@ -121,12 +121,6 @@ namespace Shadowsocks.Util.SystemProxy intptrStruct, optionListSize); // Free the allocated memory. - foreach (var v in _optionlist) - { - // free strings - if (v.Value.pszValue != IntPtr.Zero) - Marshal.FreeHGlobal(v.Value.pszValue); - } Marshal.FreeCoTaskMem(buffer); Marshal.FreeCoTaskMem(intptrStruct);