خواندن 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 بیتی همچنان DWORD 32 بیتی میماند، در حالی که فیلدهای اشارهگر با معماری فرایند گسترده میشوند. چیدمان متوالی معمول، همترازی متناظر را فراهم میکند.
این مثال درباره بافر نتیجه گزینه 38 است. الگوی مالکیت آن را کورکورانه روی INTERNET_OPTION_PER_CONNECTION_OPTION اعمال نکنید، زیرا گزینههای رشتهای بازگشتی آن به پاکسازی جداگانه مستندشده نیاز دارند.
نتیجه پیکربندی WinINet را در محدوده دسته انتخابشده توصیف میکند. این تصمیم PAC برای یک URL دلخواه یا گزارشی از مسیر مؤثر هر مرورگر نیست. وقتی رشته پروکسی بازگشتی یک نقشه مخصوص پروتکل است، آن ساختار را حفظ کنید و آن را یک نقطه پایانی واحد در نظر نگیرید. WinINet همان API دسکتاپ است؛ برنامههای سرویس به چیدمان WinHTTP پشتیبانیشده خود نیاز دارند.