首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >P/从WlanHostedNetworkQueryStatus调用wlanapi.dll

P/从WlanHostedNetworkQueryStatus调用wlanapi.dll
EN

Stack Overflow用户
提问于 2012-12-10 14:48:23
回答 1查看 1.8K关注 0票数 3

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

代码语言:javascript
复制
    DWORD WINAPI WlanHostedNetworkQueryStatus(
      _In_        HANDLE hClientHandle,
      _Out_       PWLAN_HOSTED_NETWORK_STATUS *ppWlanHostedNetworkStatus,
      _Reserved_  PVOID pvReserved
    );

到以下C#代码:

代码语言:javascript
复制
    [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的映射如下:

代码语言:javascript
复制
    [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),这意味着我已经正确地调用并传递了参数:

代码语言:javascript
复制
    _WLAN_HOSTED_NETWORK_STATUS netStatus = new _WLAN_HOSTED_NETWORK_STATUS();

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

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

代码语言:javascript
复制
netStatus.HostedNetworkState.ToString();

返回

11465720

HostedNetworkState是定义如下的枚举:

代码语言:javascript
复制
    public enum _WLAN_HOSTED_NETWORK_STATE
    {
        wlan_hosted_network_unavailable,
        wlan_hosted_network_idle,
        wlan_hosted_network_active
    }

所以.toString()应该从枚举返回其中一个字符串,对吗?

我很确定这与指针等有关,因为在_WLAN_HOSTED_NETWORK_STATUS ( MS文档 )的文档中,它说在调用该函数之前,ppWlanHostedNetworkStatus应该是NULL,并且它本身就是指向结构的指针.

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

谢谢你的帮助。

-编辑-编辑

我进一步尝试用IntPtr映射函数作为参数,传递IntPtr.Zero和Marshal.PtrToStruct,但是当我试图这样做的时候,会得到AccessViolationException .

代码语言:javascript
复制
    [DllImport("Wlanapi.dll", SetLastError = true)]
    static extern UInt32 WlanHostedNetworkQueryStatus(
        [In] IntPtr hClientHandle,
        [Out] out IntPtr ppWlanHostedNetworkStatus,
        [In, Out] IntPtr pvReserved
        );

然后:

代码语言:javascript
复制
    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的建议,我取消了要映射的结构体的注释部分,并将以下内容更改为计数指向指针的指针:

代码语言:javascript
复制
    [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;
    }

我这样叫它:

代码语言:javascript
复制
    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

EN

回答 1

Stack Overflow用户

发布于 2012-12-10 17:06:02

编辑:我要尝试的一件事是我用来帮助调试的技巧--用字节数组替换您的结构,并查看您拉回的内容(好的,在本例中是uint数组):

代码语言:javascript
复制
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct _WLAN_HOSTED_NETWORK_STATUS
{
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType=UnmanagedType.U4, SizeConst = 48)]
    public uint[] scratch;
}

但是,当我在本地运行这个值时,我得到了非常奇怪的值--第一个(10x4) =40个字节被归零:

代码语言:javascript
复制
0 0 0 0 
0 0 0 0 
0 0 4D454D4C 28 
16DCD870 0 787F6447 80000020 
...omitted...

尝试这组P/Invoke声明:

(在LINQPad中完成,因此相应地替换"Dump“方法)

代码语言:javascript
复制
void Main()
{
    IntPtr clientHandle;
    int negotiatedVersion;
    if(WlanOpenHandle(2, IntPtr.Zero, out negotiatedVersion, out clientHandle) != 0)
    {
        throw new InvalidOperationException("Could not open handle");
    }
    Console.WriteLine("Negotiated version:{0}", negotiatedVersion);
    IntPtr pNetStatus = IntPtr.Zero;
    if(WlanHostedNetworkQueryStatus(clientHandle, out pNetStatus, IntPtr.Zero) != 0)
    {
        throw new InvalidOperationException("Could not query network status");
    }
    var netStatus = (WLAN_HOSTED_NETWORK_STATUS)Marshal.PtrToStructure(pNetStatus, typeof(WLAN_HOSTED_NETWORK_STATUS));
    Console.WriteLine(netStatus.PeerList[0]);
    WlanFreeMemory(pNetStatus);
    WlanCloseHandle(clientHandle, IntPtr.Zero);
}


[DllImport("Wlanapi.dll", SetLastError = true)]
[return:MarshalAs(UnmanagedType.Bool)]
public static extern bool WlanOpenHandle(
  [In] int dwClientVersion,
  IntPtr pReserved,
  [Out] out int pdwNegotiatedVersion,
  [Out] out IntPtr phClientHandle
);
[DllImport("Wlanapi.dll", SetLastError = true)]
[return:MarshalAs(UnmanagedType.Bool)]
public static extern bool WlanCloseHandle(
  [In] IntPtr hClientHandle,
  IntPtr pReserved
);
[DllImport("Wlanapi.dll", SetLastError = true)]
static extern UInt32 WlanHostedNetworkQueryStatus(
    [In] IntPtr hClientHandle,
    [Out] out IntPtr ppWlanHostedNetworkStatus,
    [In, Out] IntPtr pvReserved
);

[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 IntPtr PeerList;
}
public enum _WLAN_HOSTED_NETWORK_STATE 
{ 
  wlan_hosted_network_unavailable,
  wlan_hosted_network_idle,
  wlan_hosted_network_active
}
public enum _DOT11_PHY_TYPE : uint
{ 
  dot11_phy_type_unknown     = 0,
  dot11_phy_type_any         = 0,
  dot11_phy_type_fhss        = 1,
  dot11_phy_type_dsss        = 2,
  dot11_phy_type_irbaseband  = 3,
  dot11_phy_type_ofdm        = 4,
  dot11_phy_type_hrdsss      = 5,
  dot11_phy_type_erp         = 6,
  dot11_phy_type_ht          = 7,
  dot11_phy_type_IHV_start   = 0x80000000,
  dot11_phy_type_IHV_end     = 0xffffffff
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct _WLAN_HOSTED_NETWORK_PEER_STATE 
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=6)]
    public string PeerMacAddress;
    _WLAN_HOSTED_NETWORK_PEER_AUTH_STATE PeerAuthState;
}
public enum _WLAN_HOSTED_NETWORK_PEER_AUTH_STATE 
{ 
  wlan_hosted_network_peer_state_invalid,
  wlan_hosted_network_peer_state_authenticated
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13803265

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档