Ler INTERNET_OPTION_PROXY de WinINet cun búfer C# dimensionado
Obteña INTERNET_OPTION_PROXY cunha consulta de tamaño e un búfer nativo correctamente dimensionado, axustándose aos campos DWORD e de punteiro de C#.
INTERNET_PROXY_INFO contén un tipo de acceso DWORD e dous punteiros a cadeas. A consulta nativa tamén necesita suficiente espazo de búfer para os seus datos de proxy; Marshal.SizeOf dunha estrutura xestionada pequena non é un búfer de resultado completo de lonxitude variable.
Un axudante de compatibilidade de escritorio pode usar o punto de entrada ANSI e copiar as cadeas antes de liberar ese búfer de consulta:
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. A primeira chamada obtén o número de bytes necesario e a segunda enche esa asignación. Se o resultado medra entre chamadas, infórmase o segundo fallo en lugar de ler un búfer demasiado pequeno.
Manteña AccessType como uint. Nun proceso de 64 bits segue sendo un DWORD de 32 bits, mentres que os campos de punteiro se amplían coa arquitectura do proceso. A disposición secuencial normal fornece a aliñación correspondente.
Este exemplo trata do búfer de resultado da opción 38. Non aplique o seu patrón de propiedade a cegas a INTERNET_OPTION_PER_CONNECTION_OPTION, cuxas opcións de cadea devoltas requiren a súa limpeza separada documentada.
O resultado describe a configuración de WinINet no ámbito do identificador elixido. Non é unha decisión PAC para un URL arbitrario nin un informe da ruta efectiva de cada navegador. Cando a cadea de proxy devolta é un mapa específico do protocolo, conserve esa estrutura en lugar de tratala como un único extremo. WinINet é a API de escritorio; as aplicacións de servizo necesitan a súa disposición WinHTTP compatible.