gpt4 book ai didi

c# - P/从 wlanapi.dll 调用 WlanHostedNetworkQueryStatus

转载 作者:太空狗 更新时间:2023-10-29 21:47:04 25 4
gpt4 key购买 nike

我已经映射了 C++ 函数(来自 WLanapi.dll):

    DWORD WINAPI WlanHostedNetworkQueryStatus(
_In_ HANDLE hClientHandle,
_Out_ PWLAN_HOSTED_NETWORK_STATUS *ppWlanHostedNetworkStatus,
_Reserved_ PVOID pvReserved
);

到以下 C# 代码:

    [DllImport("Wlanapi.dll", SetLastError = true)]
static extern UInt32 WlanHostedNetworkQueryStatus(
[In] IntPtr hClientHandle,
[Out] out _WLAN_HOSTED_NETWORK_STATUS ppWlanHostedNetworkStatus,
[In, Out] IntPtr pvReserved
);

我还映射了所有需要的结构和枚举以及其他内容(例如获取 clientHandle 指针和启动托管网络)。
_WLAN_HOSTED_NETWORK_STATUS 映射如下:

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct _WLAN_HOSTED_NETWORK_STATUS
{
public _WLAN_HOSTED_NETWORK_STATE HostedNetworkState;
public Guid IPDeviceID;
public _DOT11_MAC_ADDRESS wlanHostedNetworkBSSID;
public _DOT11_PHY_TYPE dot11PhyType;
public UInt32 ulChannelFrequency;
public UInt32 dwNumberOfPeers;
public _WLAN_HOSTED_NETWORK_PEER_STATE[] PeerList;
}

现在执行该函数时,我不确定如何正确使用 ppWlanHostedNetworkStatus 等。该函数返回 ERROR_SUCCESS (0),这意味着我已调用它并就我而言正确传递了参数:

    _WLAN_HOSTED_NETWORK_STATUS netStatus = new _WLAN_HOSTED_NETWORK_STATUS();

WlanHostedNetworkQueryStatus(clientHandle, out netStatus, IntPtr.Zero);

但是在查询 ppWlanHostedNetworkStatus 的值(如网络状态或连接的对等点数量)时,我得到的只是一些奇怪的长整数(我会说内存地址,但我不确定),例如调用:

netStatus.HostedNetworkState.ToString();

返回

11465720

HostedNetworkState 是一个枚举,定义如下:

    public enum _WLAN_HOSTED_NETWORK_STATE
{
wlan_hosted_network_unavailable,
wlan_hosted_network_idle,
wlan_hosted_network_active
}

所以 .toString() 应该从枚举中返回这些字符串之一,对吧?
我很确定这与指针等有关,因为在 _WLAN_HOSTED_NETWORK_STATUS ( MS documentation ) 的文档中它说在调用该函数之前,ppWlanHostedNetworkStatus 应该是 NULL,并且它本身是指向结构...

如何调试它?我正在用 C#、VS 2012 编写代码...

感谢您的帮助。

-----编辑-----
我进一步尝试使用 IntPtr 作为参数映射函数,传递 IntPtr.Zero 和 Marshal.PtrToStruct,但是我在尝试这样做时遇到了 AccessViolationException ...

    [DllImport("Wlanapi.dll", SetLastError = true)]
static extern UInt32 WlanHostedNetworkQueryStatus(
[In] IntPtr hClientHandle,
[Out] out IntPtr ppWlanHostedNetworkStatus,
[In, Out] IntPtr pvReserved
);

然后:

    IntPtr ppStatus = IntPtr.Zero;

WlanHostedNetworkQueryStatus(clientHandle, out ppStatus, IntPtr.Zero);

_WLAN_HOSTED_NETWORK_STATUS netStatus = (_WLAN_HOSTED_NETWORK_STATUS)Marshal.PtrToStructure(ppStatus, typeof(_WLAN_HOSTED_NETWORK_STATUS));

------编辑 2--------

根据 Fermat2357 的建议,我取消了要映射的部分结构的注释,并将以下内容更改为指向指针的指针:

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct _WLAN_HOSTED_NETWORK_STATUS
{
public _WLAN_HOSTED_NETWORK_STATE HostedNetworkState;
public Guid IPDeviceID;
public _DOT11_MAC_ADDRESS wlanHostedNetworkBSSID;
public _DOT11_PHY_TYPE dot11PhyType;
public UInt32 ulChannelFrequency;
public UInt32 dwNumberOfPeers;
//public _WLAN_HOSTED_NETWORK_PEER_STATE[] PeerList;
}

我这样调用它:

    IntPtr ppStatus = IntPtr.Zero;
WlanHostedNetworkQueryStatus(clientHandle, out ppStatus, IntPtr.Zero);
IntPtr ppStatus2 = new IntPtr(ppStatus.ToInt32());
_WLAN_HOSTED_NETWORK_STATUS stat = (_WLAN_HOSTED_NETWORK_STATUS)Marshal.PtrToStructure(ppStatus2, typeof(_WLAN_HOSTED_NETWORK_STATUS));
netStatus = stat.HostedNetworkState.ToString();

这最终为我提供了正确的网络状态(启动后处于事件状态)...现在我必须找到一种方法来编码该动态数组...
到目前为止感谢 Fermat2357 的帮助

最佳答案

您的映射不正确。看一下API函数的定义WlanHostedNetworkQueryStatus .

DWORD WINAPI WlanHostedNetworkQueryStatus(
_In_ HANDLE hClientHandle,
_Out_ PWLAN_HOSTED_NETWORK_STATUS *ppWlanHostedNetworkStatus,
_Reserved_ PVOID pvReserved
);

请注意,参数ppWlanHostedNetworkStatus 是指向WLAN_HOSTED_NETWORK_STATUS 结构的指针。深入查看函数的文档,您会发现

ppWlanHostedNetworkStatus [out]

On input, this parameter must be NULL.

On output, this parameter receives a pointer to the current status of the wireless Hosted Network, if the call to the WlanHostedNetworkQueryStatus function succeeds. The current status is returned in a WLAN_HOSTED_NETWORK_STATUS structure.

如果您提供一个 NULL 指针(如文档中所述),底层 API 将为您分配一个缓冲区来保存该结构并初始化指向该缓冲区的指针。稍后不要忘记通过调用 WlanFreeMemory 来释放它。否则你会在这里发生资源泄漏。

然而,该功能的文档似乎并未 100% 完整。在我的测试(Win7 32 位)中,如果您将指针初始化为足够大的内存缓冲区,API 将不会为您分配内存。在这种情况下,稍后调用 WlanFreeMemory 似乎没有必要。但在这种情况下,很难猜测以下 WLAN_HOSTED_NETWORK_PEER_STATE 结构需要多少内存。出于这个原因,这似乎无论如何都无法使用。

这是我用来测试的C代码

#include <Wlanapi.h>

int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwRes;
HANDLE hHandle;
DWORD negotiatedVersion;

dwRes = WlanOpenHandle(1, NULL, &negotiatedVersion, &hHandle);
if (ERROR_SUCCESS == dwRes)
{
PWLAN_HOSTED_NETWORK_STATUS pStatus = NULL;

dwRes = WlanHostedNetworkQueryStatus(hHandle, &pStatus, NULL);
if (ERROR_SUCCESS == dwRes)
{
if (wlan_hosted_network_unavailable != pStatus->HostedNetworkState)
{
// Do something with the result
}

WlanFreeMemory(pStatus);
}
else
{
// handle Error
}

WlanCloseHandle(hHandle, NULL);
}
else
{
// handle Error
}

return 0;
}

如果你想让你的示例工作,你需要修改你编码结构的方式。

编辑

要正确编码,您可以尝试以下操作:

...
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct _WLAN_HOSTED_NETWORK_STATUS
{
public _WLAN_HOSTED_NETWORK_STATE HostedNetworkState;
public Guid IPDeviceID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
public string wlanHostedNetworkBSSID;
public _DOT11_PHY_TYPE dot11PhyType;
public UInt32 ulChannelFrequency;
public UInt32 dwNumberOfPeers;
public _WLAN_HOSTED_NETWORK_PEER_STATE PeerList;
}

...

IntPtr ptr = new IntPtr();
uint hostedNetworkQueryStatusSuccess = WlanHostedNetworkQueryStatus(clientHandle, out ptr, IntPtr.Zero);
if (openHandleSuccess == 0)
{
var netStat = (_WLAN_HOSTED_NETWORK_STATUS)Marshal.PtrToStructure(ptr, typeof(_WLAN_HOSTED_NETWORK_STATUS));
Console.WriteLine(netStat.HostedNetworkState);

if (netStat.HostedNetworkState != _WLAN_HOSTED_NETWORK_STATE.wlan_hosted_network_unavailable)
{
IntPtr offset = Marshal.OffsetOf(typeof(_WLAN_HOSTED_NETWORK_STATUS), "PeerList");

for (int i = 0; i < netStat.dwNumberOfPeers; i++)
{
var peer = (_WLAN_HOSTED_NETWORK_PEER_STATE)Marshal.PtrToStructure(
new IntPtr(ptr.ToInt64() + offset.ToInt64()),
typeof(_WLAN_HOSTED_NETWORK_PEER_STATE));

System.Console.WriteLine(peer.PeerMacAddress);

offset += Marshal.SizeOf(peer);
}
}
}

想法:我在这里使用的结构可以确保它始终正确编码。后来有了 dwNumberOfPeers 成员的知识(如果它有效),我一步一步地得到了所有的内部结构。

关于c# - P/从 wlanapi.dll 调用 WlanHostedNetworkQueryStatus,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13803265/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com