none
NativeWiFiのWlanScanがパラメータエラー(ERROR_INVALID_PARAMETER)となってしまう RRS feed

  • 質問

  • C#でNativeWiFiAPIをコールして付近にあるWiFiアクセスポイントの一覧を取得しようとしています。
    そこで、以下のようなDLLImport宣言を行い、以下のようにAPIコールをした場合に、WlanScanのreturn値がERROR_INVALID_PARAMETERとなってしまいます。
    ちなみに、return値を無視してWlanGetAvailableNetworkListのAPIをコールした場合、それはERROR_SUCCESSを返します。
    どなたかWlanScanがERROR_SUCCESSを返すようにするにはどのようにすればよいか教えていただけますでしょうか。

    namespace NativeWiFi
    {
        class Wlanapi
        {
            /// <summary>
            /// DWORD WINAPI WlanOpenHandle(
            ///   __in        DWORD dwClientVersion,
            ///   __reserved  PVOID pReserved,
            ///   __out       PDWORD pdwNegotiatedVersion,
            ///   __out       PHANDLE phClientHandle
            /// );
            /// </summary>
            [DllImport("Wlanapi.dll", EntryPoint = "WlanOpenHandle")]
            public static extern uint WlanOpenHandle(uint dwClientVersion, IntPtr pReserved, [Out] out uint pdwNegotiatedVersion, ref IntPtr ClientHandle);
            public const uint client_version_xp = 1;
            public const uint client_version_vista = 2;

            /// <summary>
            /// DWORD WINAPI WlanEnumInterfaces(
            ///   __in        HANDLE hClientHandle,
            ///   __reserved  PVOID pReserved,
            ///   __out       PWLAN_INTERFACE_INFO_LIST *ppInterfaceList
            /// );
            /// </summary>
            [DllImport("Wlanapi.dll", EntryPoint = "WlanEnumInterfaces")]
            public static extern uint WlanEnumInterfaces([In] IntPtr hClientHandle, IntPtr pReserved, ref IntPtr ppInterfaceList);
            [StructLayout(LayoutKind.Sequential)]
            public struct WLAN_INTERFACE_INFO_LIST
            {
                public Int32 dwNumberOfItems;
                public Int32 dwIndex;
                public WLAN_INTERFACE_INFO[] InterfaceInfo;

                /// <summary>
                /// Constructor for WLAN_INTERFACE_INFO_LIST.
                /// Constructor is needed because the InterfaceInfo member varies based on how many adapters are in the system.
                /// </summary>
                /// <param name="pList">the unmanaged pointer containing the list.</param>
                public WLAN_INTERFACE_INFO_LIST(IntPtr pList)
                {
                    // The first 4 bytes are the number of WLAN_INTERFACE_INFO structures.
                    dwNumberOfItems = Marshal.ReadInt32(pList, 0);

                    // The next 4 bytes are the index of the current item in the unmanaged API.
                    dwIndex = Marshal.ReadInt32(pList, 4);

                    // Construct the array of WLAN_INTERFACE_INFO structures.
                    InterfaceInfo = new WLAN_INTERFACE_INFO[dwNumberOfItems];

                    for (int i = 0; i < dwNumberOfItems; i++)
                    {
                        // The offset of the array of structures is 8 bytes past the beginning. Then, take the index and multiply it by the number of bytes in the structure.
                        // the length of the WLAN_INTERFACE_INFO structure is 532 bytes - this was determined by doing a sizeof(WLAN_INTERFACE_INFO) in an unmanaged C++ app.
                        IntPtr pItemList = new IntPtr(pList.ToInt32() + (i * 532) + 8);

                        // Construct the WLAN_INTERFACE_INFO structure, marshal the unmanaged structure into it, then copy it to the array of structures.
                        WLAN_INTERFACE_INFO wii = new WLAN_INTERFACE_INFO();
                        wii = (WLAN_INTERFACE_INFO)Marshal.PtrToStructure(pItemList, typeof(WLAN_INTERFACE_INFO));
                        InterfaceInfo[i] = wii;
                    }
                }
            }
            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
            public struct WLAN_INTERFACE_INFO
            {
                /// GUID->_GUID
                public Guid InterfaceGuid;
                /// WCHAR[256]
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
                public string strInterfaceDescription;
                /// WLAN_INTERFACE_STATE->_WLAN_INTERFACE_STATE
                public WLAN_INTERFACE_STATE isState;
            }
            public enum WLAN_INTERFACE_STATE
            {
                /// wlan_interface_state_not_ready -> 0
                wlan_interface_state_not_ready = 0,
                /// wlan_interface_state_connected -> 1
                wlan_interface_state_connected = 1,
                /// wlan_interface_state_ad_hoc_network_formed -> 2
                wlan_interface_state_ad_hoc_network_formed = 2,
                /// wlan_interface_state_disconnecting -> 3
                wlan_interface_state_disconnecting = 3,
                /// wlan_interface_state_disconnected -> 4
                wlan_interface_state_disconnected = 4,
                /// wlan_interface_state_associating -> 5
                wlan_interface_state_associating = 5,
                /// wlan_interface_state_discovering -> 6
                wlan_interface_state_discovering = 6,
                /// wlan_interface_state_authenticating -> 7
                wlan_interface_state_authenticating = 7,
            }

            /// <summary>
            /// DWORD WINAPI WlanScan(
            ///   __in        HANDLE hClientHandle,
            ///   __in        const GUID *pInterfaceGuid,
            ///   __in_opt    const PDOT11_SSID pDot11Ssid,
            ///   __in_opt    const PWLAN_RAW_DATA pIeData,
            ///   __reserved  PVOID pReserved
            /// );
            /// </summary>
            [DllImport("Wlanapi.dll", EntryPoint = "WlanEnumInterfaces")]
            public static extern uint WlanScan(IntPtr hClientHandle, ref Guid InterfaceGuid, IntPtr pDot11Ssid, IntPtr pIeData, IntPtr pReserved);


        public partial class Form1 : Form
        {
            IntPtr ClientHandle;
            uint NegotiatedVersion;
            Guid InterFaceGUID;
            Wlanapi.WLAN_AVAILABLE_NETWORK_LIST AvailableNetworkList;

            public Form1()
            {
                InitializeComponent();
                this.ClientHandle = new IntPtr();
                this.InterFaceGUID = new Guid();
            }

            private void btnScan_Click(object sender, EventArgs e)
            {
                uint result;

                result = Wlanapi.WlanOpenHandle(Wlanapi.client_version_xp, IntPtr.Zero, out this.NegotiatedVersion, ref this.ClientHandle);
                if (result != Wlanapi.Win32Err.ERROR_SUCCESS)
                {
                    MessageBox.Show("WlanOpenHandleError:" + result.ToString());
                    return;
                }

                IntPtr InterfaceList = new IntPtr();
                result = Wlanapi.WlanEnumInterfaces(this.ClientHandle, IntPtr.Zero, ref InterfaceList);
                if (result != Wlanapi.Win32Err.ERROR_SUCCESS)
                {
                    MessageBox.Show("WlanEnumInterfacesError:" + result.ToString());
                    return;
                }
                Wlanapi.WLAN_INTERFACE_INFO_LIST interfaces = new Wlanapi.WLAN_INTERFACE_INFO_LIST(InterfaceList);
                this.InterFaceGUID = interfaces.InterfaceInfo[0].InterfaceGuid;

                result = Wlanapi.WlanScan(this.ClientHandle, ref InterFaceGUID, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
                if (result != Wlanapi.Win32Err.ERROR_SUCCESS)
                {
                    MessageBox.Show("WlanScanError:" + result.ToString());
                    return;
                }

    2009年4月20日 2:15

回答

  • [DllImport("Wlanapi.dll", EntryPoint = "WlanEnumInterfaces ")]
    public static extern uint WlanScan (IntPtr hClientHandle, ref Guid InterfaceGuid, IntPtr pDot11Ssid, IntPtr pIeData, IntPtr pReserved);

    メソッド名と実際に呼び出されるAPI名が異なりますが…WlanScanを呼び出したいんですよね?
    • 回答としてマーク sk7474 2009年5月7日 9:23
    2009年4月20日 2:47
  • なるほど。でしたらアドバイスを。
    メソッド名とAPI名を一致させているのであれば、EntryPoint=を記述しないことです。省略した場合にはメソッド名を使用してくれますので、このようなミスを防げますよ。
    • 回答としてマーク sk7474 2009年5月7日 9:23
    2009年4月20日 11:17

すべての返信

  • [DllImport("Wlanapi.dll", EntryPoint = "WlanEnumInterfaces ")]
    public static extern uint WlanScan (IntPtr hClientHandle, ref Guid InterfaceGuid, IntPtr pDot11Ssid, IntPtr pIeData, IntPtr pReserved);

    メソッド名と実際に呼び出されるAPI名が異なりますが…WlanScanを呼び出したいんですよね?
    • 回答としてマーク sk7474 2009年5月7日 9:23
    2009年4月20日 2:47
  • ああ!!恥ずかしながら、ご指摘のとおりです。。。。
    すみません。

    [DllImport("Wlanapi.dll", EntryPoint = "WlanScan")]
    public static extern uint WlanScan (IntPtr hClientHandle, ref Guid InterfaceGuid, IntPtr pDot11Ssid, IntPtr pIeData, IntPtr pReserved);

    でERROR_SUCCESSが返りました。
    ありがとうございました。
    2009年4月20日 11:14
  • なるほど。でしたらアドバイスを。
    メソッド名とAPI名を一致させているのであれば、EntryPoint=を記述しないことです。省略した場合にはメソッド名を使用してくれますので、このようなミスを防げますよ。
    • 回答としてマーク sk7474 2009年5月7日 9:23
    2009年4月20日 11:17
  • こんにちは。中川俊輔です。

    佐祐理さん、素早い回答ありがとうございます。

    でんでんさん、はじめまして。フォーラムのご利用ありがとうございます。
    有用な情報と思われたため、勝手ながら佐祐理さんの回答へ回答マークをつけさせていただきました。

    今後ともフォーラムをよろしくお願いします。
    それでは!
    マイクロソフト株式会社 フォーラム オペレータ 中川 俊輔
    2009年5月7日 9:41