Inheritance: System.Runtime.InteropServices.SafeBuffer, IDisposable
Esempio n. 1
0
        internal static SafeLocalAllocHandle LocalAlloc(int cb)
        {
            var h = new SafeLocalAllocHandle();

            h.SetHandle(Marshal.AllocHGlobal(cb));
            h.Initialize((ulong)cb);
            return(h);
        }
        internal static SafeLocalAllocHandle LocalAlloc(int cb)
        {
            SafeLocalAllocHandle result = Interop.Kernel32.LocalAlloc(Interop.Kernel32.LMEM_FIXED, (UIntPtr)cb);

            if (result.IsInvalid)
            {
                result.SetHandleAsInvalid();
                throw new OutOfMemoryException();
            }
            return(result);
        }
Esempio n. 3
0
        [System.Security.SecurityCritical]  // auto-generated
        internal UNICODE_INTPTR_STRING(int stringBytes, SafeLocalAllocHandle buffer)
        {
            Debug.Assert(buffer == null || (stringBytes >= 0 && (ulong)stringBytes <= buffer.ByteLength),
                            "buffer == null || (stringBytes >= 0 && stringBytes <= buffer.ByteLength)");

            this.Length = (ushort)stringBytes;
            this.MaxLength = (ushort)buffer.ByteLength;

            // Marshaling with a SafePointer does not work correctly, so unfortunately we need to extract
            // the raw handle here.
            this.Buffer = buffer.DangerousGetHandle();
        }
 internal extern static uint GetNetworkParams(SafeLocalAllocHandle pFixedInfo, ref uint pOutBufLen);
Esempio n. 5
0
 internal unsafe static extern uint HttpSendResponseEntityBody(SafeHandle requestQueueHandle, ulong requestId, uint flags, ushort entityChunkCount, HTTP_DATA_CHUNK* pEntityChunks, uint* pBytesSent, SafeLocalAllocHandle pRequestBuffer, uint requestBufferLength, NativeOverlapped* pOverlapped, void* pLogData);
Esempio n. 6
0
 internal unsafe static extern uint HttpSendHttpResponse(SafeHandle requestQueueHandle, ulong requestId, uint flags, HTTP_RESPONSE* pHttpResponse, void* pCachePolicy, uint* pBytesSent, SafeLocalAllocHandle pRequestBuffer, uint requestBufferLength, NativeOverlapped* pOverlapped, void* pLogData);
Esempio n. 7
0
        // Any exceptions that escape synchronously will be caught by the caller and wrapped in a PingException.
        // We do not need to or want to capture such exceptions into the returned task.
        private Task<PingReply> SendPingAsyncCore(IPAddress address, byte[] buffer, int timeout, PingOptions options)
        {
            var tcs = new TaskCompletionSource<PingReply>();
            _taskCompletionSource = tcs;

            _ipv6 = (address.AddressFamily == AddressFamily.InterNetworkV6);
            _sendSize = buffer.Length;

            // Get and cache correct handle.
            if (!_ipv6 && _handlePingV4 == null)
            {
                _handlePingV4 = Interop.IpHlpApi.IcmpCreateFile();
                if (_handlePingV4.IsInvalid)
                {
                    _handlePingV4 = null;
                    throw new Win32Exception(); // Gets last error.
                }
            }
            else if (_ipv6 && _handlePingV6 == null)
            {
                _handlePingV6 = Interop.IpHlpApi.Icmp6CreateFile();
                if (_handlePingV6.IsInvalid)
                {
                    _handlePingV6 = null;
                    throw new Win32Exception(); // Gets last error.
                }
            }

            var ipOptions = new Interop.IpHlpApi.IPOptions(options);

            if (_replyBuffer == null)
            {
                _replyBuffer = SafeLocalAllocHandle.LocalAlloc(MaxUdpPacket);
            }

            // Queue the event.
            int error;
            try
            {
                if (_pingEvent == null)
                {
                    _pingEvent = new ManualResetEvent(false);
                }
                else
                {
                    _pingEvent.Reset();
                }

                _registeredWait = ThreadPool.RegisterWaitForSingleObject(_pingEvent, (state, _) => ((Ping)state).PingCallback(), this, -1, true);

                SetUnmanagedStructures(buffer);

                if (!_ipv6)
                {
                    SafeWaitHandle pingEventSafeWaitHandle = _pingEvent.GetSafeWaitHandle();
                    error = (int)Interop.IpHlpApi.IcmpSendEcho2(
                        _handlePingV4,
                        pingEventSafeWaitHandle,
                        IntPtr.Zero,
                        IntPtr.Zero,
                        (uint)address.GetAddress(),
                        _requestBuffer,
                        (ushort)buffer.Length,
                        ref ipOptions,
                        _replyBuffer,
                        MaxUdpPacket,
                        (uint)timeout);
                }
                else
                {
                    IPEndPoint ep = new IPEndPoint(address, 0);
                    Internals.SocketAddress remoteAddr = IPEndPointExtensions.Serialize(ep);
                    byte[] sourceAddr = new byte[28];

                    SafeWaitHandle pingEventSafeWaitHandle = _pingEvent.GetSafeWaitHandle();
                    error = (int)Interop.IpHlpApi.Icmp6SendEcho2(
                        _handlePingV6,
                        pingEventSafeWaitHandle,
                        IntPtr.Zero,
                        IntPtr.Zero,
                        sourceAddr,
                        remoteAddr.Buffer,
                        _requestBuffer,
                        (ushort)buffer.Length,
                        ref ipOptions,
                        _replyBuffer,
                        MaxUdpPacket,
                        (uint)timeout);
                }
            }
            catch
            {
                UnregisterWaitHandle();
                throw;
            }

            if (error == 0)
            {
                error = Marshal.GetLastWin32Error();

                // Only skip Async IO Pending error value.
                if (error != Interop.IpHlpApi.ERROR_IO_PENDING)
                {
                    // Cleanup.
                    FreeUnmanagedStructures();
                    UnregisterWaitHandle();

                    throw new Win32Exception(error);
                }
            }

            return tcs.Task;
        }
Esempio n. 8
0
        // Cancels pending async requests, closes the handles.
        private void InternalDispose()
        {
            _disposeRequested = true;

            if (Interlocked.CompareExchange(ref _status, Disposed, Free) != Free)
            {
                // Already disposed, or Finish will call Dispose again once Free.
                return;
            }

            if (_handlePingV4 != null)
            {
                _handlePingV4.Dispose();
                _handlePingV4 = null;
            }

            if (_handlePingV6 != null)
            {
                _handlePingV6.Dispose();
                _handlePingV6 = null;
            }

            UnregisterWaitHandle();

            if (pingEvent != null)
            {
                pingEvent.Dispose();
                pingEvent = null;
            }

            if (_replyBuffer != null)
            {
                _replyBuffer.Dispose();
                _replyBuffer = null;
            }

            if (_asyncFinished != null)
            {
                _asyncFinished.Dispose();
                _asyncFinished = null;
            }
        }
Esempio n. 9
0
        /*private*/ partial void InternalDisposeCore()
        {
            if (_handlePingV4 != null)
            {
                _handlePingV4.Dispose();
                _handlePingV4 = null;
            }

            if (_handlePingV6 != null)
            {
                _handlePingV6.Dispose();
                _handlePingV6 = null;
            }

            UnregisterWaitHandle();

            if (_pingEvent != null)
            {
                _pingEvent.Dispose();
                _pingEvent = null;
            }

            if (_replyBuffer != null)
            {
                _replyBuffer.Dispose();
                _replyBuffer = null;
            }
        }
Esempio n. 10
0
 internal UNICODE_INTPTR_STRING(int stringBytes, SafeLocalAllocHandle buffer)
 {
     this.Length = (ushort) stringBytes;
     this.MaxLength = (ushort) buffer.ByteLength;
     this.Buffer = buffer.DangerousGetHandle();
 }
 internal extern static uint GetPerAdapterInfo(uint IfIndex, SafeLocalAllocHandle pPerAdapterInfo, ref uint pOutBufLen);
 internal extern static uint GetExtendedUdpTable(SafeLocalAllocHandle pUdpTable, ref uint dwOutBufLen, bool order,
                                                 uint IPVersion, UdpTableClass tableClass, uint reserved);
 internal extern static uint GetUdpTable(SafeLocalAllocHandle pUdpTable, ref uint dwOutBufLen, bool order);
 internal extern static uint GetAdaptersAddresses(
     AddressFamily family,
     uint flags,
     IntPtr pReserved,
     SafeLocalAllocHandle adapterAddresses,
     ref uint outBufLen);
Esempio n. 15
0
        private PingReply InternalSend(IPAddress address, byte[] buffer, int timeout, PingOptions options, bool async)
        {
            _ipv6 = (address.AddressFamily == AddressFamily.InterNetworkV6) ? true : false;
            _sendSize = buffer.Length;

            // Get and cache correct handle.
            if (!_ipv6 && _handlePingV4 == null)
            {
                _handlePingV4 = Interop.IpHlpApi.IcmpCreateFile();
                if (_handlePingV4.IsInvalid)
                {
                    _handlePingV4 = null;
                    throw new Win32Exception(); // Gets last error.
                }
            }
            else if (_ipv6 && _handlePingV6 == null)
            {
                _handlePingV6 = Interop.IpHlpApi.Icmp6CreateFile();
                if (_handlePingV6.IsInvalid)
                {
                    _handlePingV6 = null;
                    throw new Win32Exception(); // Gets last error.
                }
            }

            var ipOptions = new Interop.IpHlpApi.IPOptions(options);

            if (_replyBuffer == null)
            {
                _replyBuffer = SafeLocalAllocHandle.LocalAlloc(MaxUdpPacket);
            }

            // Queue the event.
            int error;

            try
            {
                if (async)
                {
                    if (pingEvent == null)
                    {
                        pingEvent = new ManualResetEvent(false);
                    }
                    else
                    {
                        pingEvent.Reset();
                    }

                    _registeredWait = ThreadPool.RegisterWaitForSingleObject(pingEvent, new WaitOrTimerCallback(PingCallback), this, -1, true);
                }

                SetUnmanagedStructures(buffer);

                if (!_ipv6)
                {
                    if (async)
                    {
                        SafeWaitHandle pingEventSafeWaitHandle = pingEvent.GetSafeWaitHandle();
                        error = (int)Interop.IpHlpApi.IcmpSendEcho2(
                            _handlePingV4,
                            pingEventSafeWaitHandle,
                            IntPtr.Zero,
                            IntPtr.Zero,
                            (uint)address.GetAddress(),
                            _requestBuffer,
                            (ushort)buffer.Length,
                            ref ipOptions,
                            _replyBuffer,
                            MaxUdpPacket,
                            (uint)timeout);
                    }
                    else
                    {
                        error = (int)Interop.IpHlpApi.IcmpSendEcho2(
                            _handlePingV4,
                            IntPtr.Zero,
                            IntPtr.Zero,
                            IntPtr.Zero,
                            (uint)address.GetAddress(),
                            _requestBuffer,
                            (ushort)buffer.Length,
                            ref ipOptions,
                            _replyBuffer,
                            MaxUdpPacket,
                            (uint)timeout);
                    }
                }
                else
                {
                    IPEndPoint ep = new IPEndPoint(address, 0);
                    Internals.SocketAddress remoteAddr = IPEndPointExtensions.Serialize(ep);
                    byte[] sourceAddr = new byte[28];
                    if (async)
                    {
                        SafeWaitHandle pingEventSafeWaitHandle = pingEvent.GetSafeWaitHandle();
                        error = (int)Interop.IpHlpApi.Icmp6SendEcho2(
                            _handlePingV6,
                            pingEventSafeWaitHandle,
                            IntPtr.Zero,
                            IntPtr.Zero,
                            sourceAddr,
                            remoteAddr.Buffer,
                            _requestBuffer,
                            (ushort)buffer.Length,
                            ref ipOptions,
                            _replyBuffer,
                            MaxUdpPacket,
                            (uint)timeout);
                    }
                    else
                    {
                        error = (int)Interop.IpHlpApi.Icmp6SendEcho2(
                            _handlePingV6,
                            IntPtr.Zero,
                            IntPtr.Zero,
                            IntPtr.Zero,
                            sourceAddr,
                            remoteAddr.Buffer,
                            _requestBuffer,
                            (ushort)buffer.Length,
                            ref ipOptions,
                            _replyBuffer,
                            MaxUdpPacket,
                            (uint)timeout);
                    }
                }
            }
            catch
            {
                UnregisterWaitHandle();
                throw;
            }

            if (error == 0)
            {
                error = Marshal.GetLastWin32Error();

                // Only skip Async IO Pending error value.
                if (async && error == Interop.IpHlpApi.ERROR_IO_PENDING)
                {
                    // Expected async return value.
                    return null;
                }

                // Cleanup.
                FreeUnmanagedStructures();
                UnregisterWaitHandle();

                if (async // No IPStatus async errors.
                    || error < (int)IPStatus.DestinationNetworkUnreachable // Min
                    || error > (int)IPStatus.DestinationScopeMismatch) // Max or Out of IPStatus range.
                {
                    throw new Win32Exception(error);
                }

                return new PingReply((IPStatus)error); // Synchronous IPStatus errors.
            }

            if (async)
            {
                return null;
            }

            FreeUnmanagedStructures();

            PingReply reply;
            if (_ipv6)
            {
                Interop.IpHlpApi.Icmp6EchoReply icmp6Reply = Marshal.PtrToStructure<Interop.IpHlpApi.Icmp6EchoReply>(_replyBuffer.DangerousGetHandle());
                reply = new PingReply(icmp6Reply, _replyBuffer.DangerousGetHandle(), _sendSize);
            }
            else
            {
                Interop.IpHlpApi.IcmpEchoReply icmpReply = Marshal.PtrToStructure<Interop.IpHlpApi.IcmpEchoReply>(_replyBuffer.DangerousGetHandle());
                reply = new PingReply(icmpReply);
            }

            // IcmpEchoReply still has an unsafe IntPtr reference into replybuffer
            // and replybuffer was being freed prematurely by the GC, causing AccessViolationExceptions.
            GC.KeepAlive(_replyBuffer);

            return reply;
        }
Esempio n. 16
0
 internal extern static uint IcmpSendEcho2(SafeCloseIcmpHandle icmpHandle, SafeWaitHandle Event, IntPtr apcRoutine, IntPtr apcContext,
     uint ipAddress, [In] SafeLocalAllocHandle data, ushort dataSize, ref IPOptions options, SafeLocalAllocHandle replyBuffer, uint replySize, uint timeout);
Esempio n. 17
0
 internal extern static uint Icmp6SendEcho2(SafeCloseIcmpHandle icmpHandle, IntPtr Event, IntPtr apcRoutine, IntPtr apcContext,
     byte[] sourceSocketAddress, byte[] destSocketAddress, [In] SafeLocalAllocHandle data, ushort dataSize, ref IPOptions options, SafeLocalAllocHandle replyBuffer, uint replySize, uint timeout);
Esempio n. 18
0
 // Copies _requestBuffer into unmanaged memory for async icmpsendecho APIs.
 private unsafe void SetUnmanagedStructures(byte[] buffer)
 {
     _requestBuffer = SafeLocalAllocHandle.LocalAlloc(buffer.Length);
     byte* dst = (byte*)_requestBuffer.DangerousGetHandle();
     for (int i = 0; i < buffer.Length; ++i)
     {
         dst[i] = buffer[i];
     }
 }
Esempio n. 19
0
 internal static extern bool GetTokenInformation(
     IntPtr TokenHandle,
     uint TokenInformationClass,
     SafeLocalAllocHandle TokenInformation,
     uint TokenInformationLength,
     out uint ReturnLength);
Esempio n. 20
0
 // Releases the unmanaged memory after ping completion.
 private void FreeUnmanagedStructures()
 {
     if (_requestBuffer != null)
     {
         _requestBuffer.Dispose();
         _requestBuffer = null;
     }
 }