အရွယ်အစားသတ်မှတ်ထားသော C# buffer ဖြင့် WinINet INTERNET_OPTION_PROXY ကို ဖတ်ခြင်း
အရွယ်အစားမေးမြန်းချက်နှင့် မှန်ကန်စွာ အရွယ်သတ်မှတ်ထားသော native buffer ဖြင့် INTERNET_OPTION_PROXY ကို ရယူပြီး C# ရှိ DWORD နှင့် pointer အကွက်များနှင့် ကိုက်ညီအောင်လုပ်ပါ။
INTERNET_PROXY_INFO တွင် DWORD access အမျိုးအစားနှင့် string pointer နှစ်ခု ပါဝင်သည်။ native မေးမြန်းချက်သည် ၎င်း၏ proxy ဒေတာအတွက် လုံလောက်သော buffer နေရာလည်း လိုအပ်သည်။ သေးငယ်သော managed structure ၏ Marshal.SizeOf သည် ပြောင်းလဲနိုင်သော အလျားရှိ ရလဒ် buffer အပြည့်အစုံ မဟုတ်ပါ။
Desktop လိုက်လျောညီထွေရေး အကူအညီတစ်ခုသည် ANSI ဝင်ပေါက်ကို အသုံးပြုပြီး ထို မေးမြန်းချက် buffer ကို မလွှတ်မီ string များကို ကူးယူနိုင်သည်။
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 ဖြစ်သည်။ ပထမခေါ်ဆိုမှုက လိုအပ်သော byte အရေအတွက်ကို ရယူပြီး ဒုတိယက ထို ခွဲဝေမှုကို ဖြည့်သည်။ ခေါ်ဆိုမှုများကြား ရလဒ် ကြီးလာပါက အလွန်သေးငယ်သော buffer ကို ဖတ်မည့်အစား ဒုတိယ မအောင်မြင်မှုကို အစီရင်ခံသည်။
AccessType ကို uint အဖြစ် ထားရှိပါ။ 64-bit လုပ်ငန်းစဉ်တွင် ၎င်းသည် 32-bit DWORD အဖြစ် ကျန်ရှိပြီး pointer အကွက်များသည် လုပ်ငန်းစဉ် ဗိသုကာနှင့်အတူ ကျယ်လာသည်။ ပုံမှန် အစဉ်လိုက် အပြင်အဆင်သည် သက်ဆိုင်ရာ ချိန်ညှိမှုကို ပေးသည်။
ဤဥပမာသည် ရွေးချယ်မှု 38 ၏ ရလဒ် buffer အကြောင်း ဖြစ်သည်။ ၎င်း၏ ပိုင်ဆိုင်မှုပုံစံကို INTERNET_OPTION_PER_CONNECTION_OPTION တွင် မျက်စိမှိတ် မကျင့်သုံးပါနှင့်၊ ၎င်း၏ ပြန်ပေးသော string ရွေးချယ်မှုများသည် မှတ်တမ်းတင်ထားသော သီးခြား သန့်ရှင်းရေး လိုအပ်သည်။
ရလဒ်သည် ရွေးချယ်ထားသော handle အတိုင်းအတာအတွင်း WinINet ဖွဲ့စည်းမှုကို ဖော်ပြသည်။ ၎င်းသည် မတရားသော URL အတွက် PAC ဆုံးဖြတ်ချက် သို့မဟုတ် browser တစ်ခုချင်းစီ၏ အမှန်တကယ် လမ်းကြောင်း အစီရင်ခံစာ မဟုတ်ပါ။ ပြန်ပေးသော proxy string သည် ပရိုတိုကော-သီးသန့် မြေပုံ ဖြစ်ပါက ၎င်းကို အဆုံးမှတ်တစ်ခုအဖြစ် မသတ်မှတ်ဘဲ ထို ဖွဲ့စည်းပုံကို ထိန်းသိမ်းပါ။ WinINet သည် desktop API ဖြစ်သည်။ ဝန်ဆောင်မှု အက်ပ်များသည် ၎င်းတို့၏ ပံ့ပိုးထားသော WinHTTP အပြင်အဆင် လိုအပ်သည်။