Читање на INTERNET_OPTION_PROXY во WinINet со C# бафер со одредена големина
Земете INTERNET_OPTION_PROXY со прашање за големина и правилно димензиониран нативен бафер, усогласен со полињата DWORD и покажувач во C#.
INTERNET_PROXY_INFO содржи DWORD тип на пристап и два покажувачи на низи. Нативното прашање бара и доволно бафер простор за неговите прокси податоци; Marshal.SizeOf на мала управувана структура не е целосен бафер за резултат со променлива должина.
Помошник за компатибилност со работна површина може да ја користи ANSI влезната точка и да ги копира низите пред да го ослободи тој бафер за прашањето:
static class WinInetProxy
{
[System.Runtime.InteropServices.StructLayout(
System.Runtime.InteropServices.LayoutKind.Sequential)]
struct ProxyInfo
{
public uint AccessType;
public IntPtr Proxy;
public IntPtr Bypass;
}
[System.Runtime.InteropServices.DllImport(
"wininet.dll", EntryPoint = "InternetQueryOptionA",
SetLastError = true)]
[return: System.Runtime.InteropServices.MarshalAs(
System.Runtime.InteropServices.UnmanagedType.Bool)]
static extern bool Query(
IntPtr handle, uint option, IntPtr buffer, ref uint size);
public static (uint Type, string Proxy, string Bypass) Read()
{
uint size = 0;
Query(IntPtr.Zero, 38, IntPtr.Zero, ref size);
int error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
if (error != 122 || size == 0)
throw new System.ComponentModel.Win32Exception(error);
IntPtr buffer = System.Runtime.InteropServices.Marshal
.AllocHGlobal(checked((int)size));
try
{
if (!Query(IntPtr.Zero, 38, buffer, ref size))
throw new System.ComponentModel.Win32Exception(
System.Runtime.InteropServices.Marshal.GetLastWin32Error());
var value = System.Runtime.InteropServices.Marshal
.PtrToStructure<ProxyInfo>(buffer);
return (value.AccessType,
System.Runtime.InteropServices.Marshal.PtrToStringAnsi(value.Proxy) ?? "",
System.Runtime.InteropServices.Marshal.PtrToStringAnsi(value.Bypass) ?? "");
}
finally
{
System.Runtime.InteropServices.Marshal.FreeHGlobal(buffer);
}
}
}
38 е INTERNET_OPTION_PROXY; 122 е ERROR_INSUFFICIENT_BUFFER. Првиот повик го добива потребниот број бајти, а вториот ја пополнува таа распределба. Ако резултатот порасне помеѓу повиците, се пријавува вториот неуспех наместо да се чита премал бафер.
Задржете го AccessType како uint. Во 64-битен процес останува 32-битен DWORD, додека полињата покажувачи се шират со архитектурата на процесот. Нормалниот секвенцијален распоред го дава соодветното порамнување.
Овој пример се однесува на баферот за резултат на опцијата 38. Не применувајте го неговиот модел на сопственост слепо на INTERNET_OPTION_PER_CONNECTION_OPTION, чии вратени опции за низи бараат документирано посебно чистење.
Резултатот ја опишува конфигурацијата на WinINet во избраниот опсег на рачката. Тоа не е PAC одлука за произволен URL ниту извештај за вистинската рута на секој прелистувач. Кога вратената прокси низа е карта специфична за протоколот, зачувајте ја таа структура наместо да ја третирате како една крајна точка. WinINet е десктоп API; сервисните апликации го бараат својот поддржан WinHTTP распоред.