/// <summary> /// Invokes <c>InternetSetStatusCallback</c>, handling error conditions. Returns the wrapper for the delegate, which is actually passed to <c>InternetSetStatusCallback</c>. /// </summary> /// <param name="internet">The internet handle.</param> /// <param name="callback">The internet status callback delegate, used to report progress.</param> /// <returns>The wrapper created for <paramref name="callback"/>, which is actually passed to the unmanaged <c>InternetSetStatusCallback</c> function.</returns> public static object InternetSetStatusCallback(SafeInternetHandle internet, InternetHandle.InternetCallback callback) { // Note: this will only work for synchronous callbacks! Asynchronous callbacks are not yet supported. InternetStatusCallback ret = CreateInternetStatusCallback(callback); if (DoInternetSetStatusCallback(internet, ret) == INTERNET_INVALID_STATUS_CALLBACK) { throw GetLastInternetException(); } return(ret); }
/// <summary> /// Creates a wrapper for the provided internet status callback delegate. /// </summary> /// <param name="callback">The user-provided internet status callback delegate.</param> /// <returns>The wrapped internet status callback delegate.</returns> private static InternetStatusCallback CreateInternetStatusCallback(InternetHandle.InternetCallback callback) { if (callback == null) { return(null); } return((hInternet, dwContext, dwInternetStatus, lpvStatusInformation, dwStatusInformationLength) => { InternetCallbackEventArgs args; switch (dwInternetStatus) { default: case InternetCallbackEventArgs.StatusCode.ClosingConnection: case InternetCallbackEventArgs.StatusCode.ConnectionClosed: case InternetCallbackEventArgs.StatusCode.DetectingProxy: case InternetCallbackEventArgs.StatusCode.HandleClosing: case InternetCallbackEventArgs.StatusCode.IntermediateResponse: case InternetCallbackEventArgs.StatusCode.P3PHeader: case InternetCallbackEventArgs.StatusCode.ReceivingResponse: case InternetCallbackEventArgs.StatusCode.SendingRequest: args = new InternetCallbackEventArgs { Code = dwInternetStatus, RawData = lpvStatusInformation, }; break; case InternetCallbackEventArgs.StatusCode.ConnectedToServer: case InternetCallbackEventArgs.StatusCode.ConnectingToServer: SocketAddress socketAddress = new SocketAddress((AddressFamily)BitConverter.ToUInt16(lpvStatusInformation, 0), 16); lpvStatusInformation.Select((x, i) => socketAddress[i] = x).Run(); args = new InternetCallbackEventArgs.Socket { Code = dwInternetStatus, RawData = lpvStatusInformation, EndPoint = new IPEndPoint(0, 0).Create(socketAddress), }; break; case InternetCallbackEventArgs.StatusCode.CookieHistory: args = new InternetCallbackEventArgs.CookieHistory { Code = dwInternetStatus, RawData = lpvStatusInformation, Accepted = BitConverter.ToUInt32(lpvStatusInformation, 0) != 0, Leashed = BitConverter.ToUInt32(lpvStatusInformation, 4) != 0, Downgraded = BitConverter.ToUInt32(lpvStatusInformation, 8) != 0, Rejected = BitConverter.ToUInt32(lpvStatusInformation, 12) != 0, }; break; case InternetCallbackEventArgs.StatusCode.CookieReceived: case InternetCallbackEventArgs.StatusCode.CookieSent: case InternetCallbackEventArgs.StatusCode.RequestSent: case InternetCallbackEventArgs.StatusCode.ResponseReceived: case InternetCallbackEventArgs.StatusCode.StateChange: args = new InternetCallbackEventArgs.Number { Code = dwInternetStatus, RawData = lpvStatusInformation, Value = BitConverter.ToInt32(lpvStatusInformation, 0), }; break; case InternetCallbackEventArgs.StatusCode.HandleCreated: case InternetCallbackEventArgs.StatusCode.RequestComplete: IntPtr ptr = IntPtr.Size == 4 ? (IntPtr)BitConverter.ToUInt32(lpvStatusInformation, 0) : (IntPtr)BitConverter.ToUInt64(lpvStatusInformation, 0); args = new InternetCallbackEventArgs.AsyncResult { Code = dwInternetStatus, RawData = lpvStatusInformation, Result = IntPtr.Size == 4 ? (IntPtr)Marshal.ReadInt32(ptr) : (IntPtr)Marshal.ReadInt64(ptr), Error = IntPtr.Size == 4 ? Marshal.ReadInt32(ptr, 4) : Marshal.ReadInt32(ptr, 8), }; break; case InternetCallbackEventArgs.StatusCode.ResolvingName: case InternetCallbackEventArgs.StatusCode.NameResolved: case InternetCallbackEventArgs.StatusCode.Redirect: args = new InternetCallbackEventArgs.String { Code = dwInternetStatus, RawData = lpvStatusInformation, Value = Encoding.Unicode.GetString(lpvStatusInformation), }; break; } callback(args); }); }