亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++程序中使用Windows系統Native Wifi API的基本教程

2020-05-23 14:07:11
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了C++程序中使用Windows系統Native Wifi API的基本教程,包括在程序中控制無線網卡開關的方法,需要的朋友可以參考下
 

Windows應用想要實現連接wifi,監聽wifi信號,斷開連接等功能,用NativeWifi API是個不錯的選擇。

打開MSDN,搜索NativeWifi Api,找到Native Wifi頁。在這里。

信息量很大,如果像我著急實現上述功能,看海量的文檔有些來不及。如果直接給我例子,在運行中調試,閱讀代碼,效率會更高。
但是,我并沒有成功。首先,Sample在SDK中,參見這里。我下載幾次都失敗了,最后放棄這條路。后來同事給了我一份Sample,我不敢確定是否就是這個,但是代碼寫的也是很晦澀。我的初衷是簡單的使用這些API的例子。

看來還是自己動手吧??聪嚓PAPI,如果不懂,就找有經驗人的例子。

幾經周折,終于實現我的需求。讓我慢慢道來。
1.獲得可用AP列表
參見WlanGetAvailableNetworkList的官方文檔,下面有例子。

DWORD WINAPI WlanGetAvailableNetworkList(  _In_  HANDLE hClientHandle,  _In_  const GUID *pInterfaceGuid,  _In_  DWORD dwFlags,  _Reserved_ PVOID pReserved,  _Out_  PWLAN_AVAILABLE_NETWORK_LIST *ppAvailableNetworkList ); 

由可用列表便可以找到當前哪個AP正在連接,并顯示信號強度。
2.監聽當前連接
在獲得可用AP列表的基礎上,遍歷當前AP,看誰正在連接,并取得它的信號。代碼片段如下:

bool isConnect = false; int numberOfItems = pWLAN_AVAILABLE_NETWORK_LIST->dwNumberOfItems;   for(int i = 0; i <= numberOfItems; i++)   {    WLAN_AVAILABLE_NETWORK wlanAN = pWLAN_AVAILABLE_NETWORK_LIST->Network[i];    if(wlanAN.dwFlags & WLAN_AVAILABLE_NETWORK_CONNECTED)    {     Wprintf(WLAN signal is %s:%d/n", wlanAN.strProfileName, wlanAN.wlanSignalQuality);     isConnect = true;        }   }   if(!isConnect){     wprintf("Wifi is disconnected!/n");} 

3.斷開連接
如果wifi處于連接狀態,將其斷開。WlanDisconnect還是容易使用的。原型如下:

DWORD WINAPI WlanDisconnect(  _In_  HANDLE hClientHandle,  _In_  const GUID *pInterfaceGuid,  _Reserved_ PVOID pReserved ); 

代碼演示在后面。
4.連接一個有profile的AP(已保存過密碼)
這是本文的重點。
雖然連接函數WlanConnect原型很簡單:

DWORD WINAPI WlanConnect(  _In_  HANDLE hClientHandle,  _In_  const GUID *pInterfaceGuid,  _In_  const PWLAN_CONNECTION_PARAMETERS pConnectionParameters,  _Reserved_ PVOID pReserved ); 
但參數PWLAN_CONNECTION_PARAMETERS卻是很復雜,只要有一個配錯,連接就會失敗。
還好我的需求還是蠻簡單的,只要連接已有的profile的AP。那么我的工作就會有針對性的開展。挫折了好多天,每次都連接失敗,原因是ERROR_INVALID_PARAMETER。
就在今天,我終于成功了。真是會者不難,難者不會啊。
看看連接參數的結構體:
typedef struct _WLAN_CONNECTION_PARAMETERS {  WLAN_CONNECTION_MODE wlanConnectionMode;  LPCWSTR    strProfile;  PDOT11_SSID   pDot11Ssid;  PDOT11_BSSID_LIST pDesiredBssidList;  DOT11_BSS_TYPE  dot11BssType;  DWORD    dwFlags; } WLAN_CONNECTION_PARAMETERS, *PWLAN_CONNECTION_PARAMETERS; 

為了實現我的要求,可以這樣賦值:
wlanConnectionMode這里設成wlan_connection_mode_profile;
strProfile寫上你要連接ap的名稱(通常是profile名稱);
pDot11Ssid用不上,設置NULL;
pDesiredBssidList同樣置成NULL;
dot11BssType我給設成dot11_BSS_type_infrastructure(基礎設施?);
dwFlags設置為WLAN_CONNECTION_HIDDEN_NETWORK。
確實是工作了,strProfile如何獲取呢?參見監聽連接信號中對可用AP列表中第一個profile的獲取。
完整代碼如下:

// #include "stdafx.h" #include <windows.h> #include <wlanapi.h> #include <objbase.h> #include <wtypes.h> #include <string> #include <stdio.h> #include <stdlib.h>  // Need to link with Wlanapi.lib and Ole32.lib #pragma comment(lib, "wlanapi.lib") #pragma comment(lib, "ole32.lib")  using namespace std;  int listenStatus() {  HANDLE hClient = NULL;  DWORD dwMaxClient = 2;    DWORD dwCurVersion = 0;  DWORD dwResult = 0;  DWORD dwRetVal = 0;  int iRet = 0;    WCHAR GuidString[39] = {0};  //Listen the status of the AP you connected.  while(1){   Sleep(5000);   PWLAN_INTERFACE_INFO_LIST pIfList = NULL;//I think wlan interface means network card   PWLAN_INTERFACE_INFO pIfInfo = NULL;    DWORD dwFlags = 0;       dwResult = WlanOpenHandle(dwMaxClient, NULL, &dwCurVersion, &hClient);   if (dwResult != ERROR_SUCCESS) {    wprintf(L"WlanOpenHandle failed with error: %u/n", dwResult);    return 1;   }    dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList);   if (dwResult != ERROR_SUCCESS) {    wprintf(L"WlanEnumInterfaces failed with error: %u/n", dwResult);    return 1;   } else {     wprintf(L"WLAN_INTERFACE_INFO_LIST for this system/n");     wprintf(L"Num Entries: %lu/n", pIfList->dwNumberOfItems);    wprintf(L"Current Index: %lu/n/n", pIfList->dwIndex);    int i;    for (i = 0; i < (int) pIfList->dwNumberOfItems; i++) {     pIfInfo = (WLAN_INTERFACE_INFO *) &pIfList->InterfaceInfo[i];     wprintf(L" Interface Index[%u]:/t %lu/n", i, i);     iRet = StringFromGUID2(pIfInfo->InterfaceGuid, (LPOLESTR) &GuidString,      sizeof(GuidString)/sizeof(*GuidString));      if (iRet == 0)      wprintf(L"StringFromGUID2 failed/n");     else {      wprintf(L" InterfaceGUID[%d]: %ws/n",i, GuidString);     }      wprintf(L" Interface Description[%d]: %ws", i,      pIfInfo->strInterfaceDescription);     wprintf(L"/n");      wprintf(L" Interface State[%d]:/t ", i);     switch (pIfInfo->isState) {     case wlan_interface_state_not_ready:      wprintf(L"Not ready/n");      break;     case wlan_interface_state_connected:      wprintf(L"Connected/n");      break;     case wlan_interface_state_ad_hoc_network_formed:      wprintf(L"First node in a ad hoc network/n");      break;     case wlan_interface_state_disconnecting:      wprintf(L"Disconnecting/n");      break;     case wlan_interface_state_disconnected:      wprintf(L"Not connected/n");      break;     case wlan_interface_state_associating:      wprintf(L"Attempting to associate with a network/n");      break;     case wlan_interface_state_discovering:      wprintf(L"Auto configuration is discovering settings for the network/n");      break;     case wlan_interface_state_authenticating:      wprintf(L"In process of authenticating/n");      break;     default:      wprintf(L"Unknown state %ld/n", pIfInfo->isState);      break;     }    }   }  } }  int _tmain(int argc, _TCHAR* argv[]) {   HANDLE hClient = NULL;  DWORD dwMaxClient = 2;    DWORD dwCurVersion = 0;  DWORD dwResult = 0;  DWORD dwRetVal = 0;  int iRet = 0;    /* variables used for WlanEnumInterfaces */   PWLAN_INTERFACE_INFO_LIST pIfList = NULL;  PWLAN_INTERFACE_INFO pIfInfo = NULL;   LPCWSTR pProfileName = NULL;  LPWSTR pProfileXml = NULL;  DWORD dwFlags = 0;    pProfileName = argv[1];    wprintf(L"Information for profile: %ws/n/n", pProfileName);    dwResult = WlanOpenHandle(dwMaxClient, NULL, &dwCurVersion, &hClient);  if (dwResult != ERROR_SUCCESS) {   wprintf(L"WlanOpenHandle failed with error: %u/n", dwResult);   return 1;  }   dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList);  if (dwResult != ERROR_SUCCESS) {   wprintf(L"WlanEnumInterfaces failed with error: %u/n", dwResult);   return 1;  } else {   dwResult = WlanDisconnect(hClient, &pIfList->InterfaceInfo[0].InterfaceGuid,NULL);//DISCONNECT FIRST   if(dwResult != ERROR_SUCCESS)   {    printf("WlanDisconnect failed with error: %u/n",dwResult);    return -1;   }   PWLAN_AVAILABLE_NETWORK_LIST pWLAN_AVAILABLE_NETWORK_LIST = NULL;   dwResult = WlanGetAvailableNetworkList(hClient, &pIfList->InterfaceInfo[0].InterfaceGuid,     WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_MANUAL_HIDDEN_PROFILES,     NULL, &pWLAN_AVAILABLE_NETWORK_LIST);   if (dwResult != ERROR_SUCCESS)   {       printf("WlanGetAvailableNetworkList failed with error: %u/n",dwResult);    WlanFreeMemory(pWLAN_AVAILABLE_NETWORK_LIST);    return -1;   }   WLAN_AVAILABLE_NETWORK wlanAN = pWLAN_AVAILABLE_NETWORK_LIST->Network[0];//PLEASE CHECK THIS YOURSELF   if(pProfileName == NULL)    pProfileName = wlanAN.strProfileName;    WLAN_CONNECTION_PARAMETERS wlanConnPara;   wlanConnPara.wlanConnectionMode =wlan_connection_mode_profile ; //YES,WE CONNECT AP VIA THE PROFILE   wlanConnPara.strProfile =pProfileName;       // set the profile name   wlanConnPara.pDot11Ssid = NULL;         // SET SSID NULL   wlanConnPara.dot11BssType = dot11_BSS_type_infrastructure;  //dot11_BSS_type_any,I do not need it this time.     wlanConnPara.pDesiredBssidList = NULL;       // the desired BSSID list is empty   wlanConnPara.dwFlags = WLAN_CONNECTION_HIDDEN_NETWORK;   //it works on my WIN7/8    dwResult=WlanConnect(hClient,&pIfList->InterfaceInfo[0].InterfaceGuid,&wlanConnPara ,NULL);   if (dwResult==ERROR_SUCCESS)   {    printf("WlanConnect success!/n");   }   else   {    printf("WlanConnect failed err is %d/n",dwResult);   }  }   listenStatus(); //LISTEN THE STATUS   if (pProfileXml != NULL) {   WlanFreeMemory(pProfileXml);   pProfileXml = NULL;  }   if (pIfList != NULL) {   WlanFreeMemory(pIfList);   pIfList = NULL;  }  return dwRetVal; } 

 
5.打開網絡設置界面
遇到以前沒有連接過的AP,需要輸入密碼,那么,直接打開配置界面讓用戶自己來搞吧。

ShellExecute(  NULL,  L"open",  L"shell:::{21EC2020-3AEA-1069-A2DD-08002B30309D}//::{38a98528-6cbf-4ca9-8dc0-b1e1d10f7b1b}",  NULL,  NULL,  SW_SHOWNORMAL); 

6.RSSI
當屏幕上打印出“WlanConnect success!”的時候,別提多高興了。
就像愛迪生試驗燈絲一下,在無數次失敗后,終于找到了一種材料可以勝任燈絲的工作。這種喜悅真的令人振奮,往日的陰霾和不爽終于一掃而光。
其實我也嘗試過WlanGetProfile和WlanSetProfile,雖然有時結果是能夠連上指定AP,但是函數返回結果卻總是ERROR_INVALID_PARAMETER。
網上的例子,很多都是抄來抄去的,寫的不明不白,雖然有過幫助,但是也有些誤導。
今天自己成功的連接到指定AP了(用命令行運行我的例子,輸入參數profile name),我一定要把它發表出來,讓其他人有個參考。
我認為這是一件誠意的作品,在此也謝謝給過我幫助的朋友。
最后說一下獲得的信號。標準信號RSSI是負值,而這里獲得的信號都是正值(0~100),在有些需要RSSI的地方,我們需要轉換一下:

if (pBssEntry->wlanSignalQuality == 0)   iRSSI = -100;  else if (pBssEntry->wlanSignalQuality == 100)    iRSSI = -50;  else   iRSSI = -100 + (pBssEntry->wlanSignalQuality/2);     wprintf(L" Signal Quality[%u]:/t %u (RSSI: %i dBm)/n", j,   pBssEntry->wlanSignalQuality, iRSSI); 

     
7.Wifi on與wifi off
下面要說的是在軟件層面控制無線網卡的開和關。
問題聽起來簡單,調查起來復雜,但解決起來卻也簡單。關鍵函數便是Native wifi api中的WlanSetInterface。其實這個API功能也是非
常強大的,我只用到其中控制wifi radio state的功能。官網文檔在此。
函數原型:

DWORD WINAPI WlanSetInterface(  _In_  HANDLE hClientHandle,  _In_  const GUID *pInterfaceGuid,  _In_  WLAN_INTF_OPCODE OpCode,  _In_  DWORD dwDataSize,  _In_  const PVOID pData,  _Reserved_ PVOID pReserved ); 

重點說一下三個參數:
(1) OpCode,指定要設置的參數。我們選擇wlan_intf_opcode_radio_state
(2) DwDataSize,pData的size。傳入時用sizeof得到。
(3) pData,radio state對應的data是WLAN_PHY_RADIO_STATE。
看看這個state結構體:

typedef struct _WLAN_PHY_RADIO_STATE {  DWORD    dwPhyIndex;  DOT11_RADIO_STATE dot11SoftwareRadioState;  DOT11_RADIO_STATE dot11HardwareRadioState; } WLAN_PHY_RADIO_STATE, *PWLAN_PHY_RADIO_STATE; 

Index設為0.
State設置如下:

typedef enum _DOT11_RADIO_STATE {  dot11_radio_state_unknown,  dot11_radio_state_on,  dot11_radio_state_off } DOT11_RADIO_STATE, *PDOT11_RADIO_STATE; 

與前幾個API(比如wlanconnect)相比,這個函數的使用簡單多了。全部源碼如下:

// ManageWirelessNetwork.cpp : Defines the entry point for the console application. //  #include "stdafx.h" #include <stdio.h> #include <windows.h> #include <shellapi.h> #include <wlanapi.h>  // Need to link with shell32.lib #pragma comment(lib, "shell32.lib") #pragma comment(lib, "wlanapi.lib")  int _tmain(int argc, _TCHAR* argv[]) {  DWORD dwResult = 0;  DWORD dwMaxClient = 2;  DWORD dwCurVersion = 0;  HANDLE hClient = NULL;  PWLAN_INTERFACE_INFO_LIST pIfList = NULL;  PWLAN_INTERFACE_INFO pIfInfo = NULL;   dwResult = WlanOpenHandle(dwMaxClient, NULL, &dwCurVersion, &hClient);  if (dwResult != ERROR_SUCCESS) {   wprintf(L"WlanOpenHandle failed with error: %u/n", dwResult);   return false;  }   dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList);  if (dwResult != ERROR_SUCCESS) {   wprintf(L"WlanEnumInterfaces failed with error: %u/n", dwResult);   return false;  }    WLAN_PHY_RADIO_STATE state;  state.dwPhyIndex = 0;  state.dot11SoftwareRadioState = dot11_radio_state_on;  PVOID pData = &state;   dwResult = WlanSetInterface(hClient,&pIfList->InterfaceInfo[0].InterfaceGuid,   wlan_intf_opcode_radio_state,sizeof(WLAN_PHY_RADIO_STATE),pData,NULL);   if(dwResult == ERROR_SUCCESS)  {   wprintf(L"set state success!/n");  }  else  {   wprintf(L"set state failed!err is %d/n",dwResult);  }   return 0; } 

8.GOTO在釋放資源時的作用
GOTO語句有著很臭的名聲,我們的老師經常教導我們說,不要輕易使用它。
C++跳轉語句有三個:goto、break和continue。它們只是工具,我覺得問題不能歸咎于工具,問題在于人。
就像指針一樣,goto這個無條件跳轉語句力量還是很強大的,如果濫用,出現問題很難排查。
但有些時候goto確實是不二選擇,例如我遇到的,在函數中有多個出口,而每個出口都遇到釋放資源的時候,與其都把釋放語句不厭其煩的寫一遍,
不如一個goto語句來的干脆利落。
下面的例子取自上一篇Native Wifi API文章,由于我們的程序經常控制的wifi的on和off,必須注意釋放資源。就拿WlanOpenHandle來說,
如果不注意對稱WlanCloseHandler,程序幾次運行后報錯:ERROR_REMOTE_SESSION_LIMIT_EXCEEDED
官網解釋為:Too many handles have been issued by the server.
所以我們會在每個API調用后,確認返回值,如果錯誤,程序將不再繼續向下運行,return之前,我們必須釋放資源。當出口很多時,我們要寫很多同樣的代碼,
很煩躁,難讀,代碼急速膨脹。但使用goto后,問題便輕松了許多,請看簡單例子:

// ManageWirelessNetwork.cpp : Defines the entry point for the console application. //  #include "stdafx.h" #include <stdio.h> #include <windows.h> #include <shellapi.h> #include <wlanapi.h>  // Need to link with shell32.lib #pragma comment(lib, "shell32.lib") #pragma comment(lib, "wlanapi.lib")  int _tmain(int argc, _TCHAR* argv[]) {   DWORD dwResult = 0;   DWORD dwMaxClient = 2;   DWORD dwCurVersion = 0;   HANDLE hClient = NULL;   PWLAN_INTERFACE_INFO_LIST pIfList = NULL;   PWLAN_INTERFACE_INFO pIfInfo = NULL;    dwResult = WlanOpenHandle(dwMaxClient, NULL, &dwCurVersion, &hClient);   if (dwResult != ERROR_SUCCESS) {     wprintf(L"WlanOpenHandle failed with error: %u/n", dwResult);     return false;   }    dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList);   if (dwResult != ERROR_SUCCESS) {     wprintf(L"WlanEnumInterfaces failed with error: %u/n", dwResult);     goto RELEASE_RESOURCE;   }      WLAN_PHY_RADIO_STATE state;   state.dwPhyIndex = 0;   state.dot11SoftwareRadioState = dot11_radio_state_on;//off here too.   PVOID pData = &state;    dwResult = WlanSetInterface(hClient,&pIfList->InterfaceInfo[0].InterfaceGuid,     wlan_intf_opcode_radio_state,sizeof(WLAN_PHY_RADIO_STATE),pData,NULL);    if(dwResult == ERROR_SUCCESS)   {     wprintf(L"set state success!/n");   }   else   {     wprintf(L"set state failed!err is %d/n",dwResult);   } RELEASE_RESOURCE:   if(hClient)   {     WlanCloseHandle(hClient,NULL);     hClient = NULL;   }   if(pIfList)   {     WlanFreeMemory(pIfList);     pIfList = NULL;   }   if(pIfInfo)   {     WlanFreeMemory(pIfInfo);     pIfInfo = NULL;   }   return 0; } 

最后,goto還會用來跳出多重循環。但需要注意的是,只能從內層跳到外層,不可逆操作。

 

后記:
其實幾個月前就要實現windows上的wifi on和off,問了許多人,發了許多帖子,最后都不了了之。之后的日子里也發生了許多事。國內的
搜索無果,加上google的無法使用,都對調查增加了些許難度。我們把重點先放到了native wifi api的幾個方法,見上一篇玩轉文章。但
那并不是我想要的。
原以為windows也會想android一樣,普通應用沒有權限來控制wifi的開關呢,結果并不是這樣。這也宣告了之前我的判斷失誤。
直到今天,通過Bing發現了幾條線索。那是通過C#調用native wifi api的問題,里面提及了之前并沒有重視的wlansetinterface。
Interface,在這里我覺得可以理解成無線網卡。類似的WlanEnumInterfaces中實現的功能是羅列出當前無線網卡。
無線網卡的設置,其中有一項是radio的狀態。
果然,這一切都有了了斷。



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
自拍偷拍免费精品| 久久成年人免费电影| 97在线免费观看| 92看片淫黄大片看国产片| 亚洲综合在线做性| 亚洲香蕉成人av网站在线观看| 国产精品自产拍在线观看| 中文字幕亚洲综合久久筱田步美| 国产精品久久久久久av福利| 日韩精品在线播放| 夜夜嗨av色综合久久久综合网| 亚洲精品美女在线观看播放| 96sao精品视频在线观看| 精品久久香蕉国产线看观看亚洲| 亚洲另类激情图| 国产成人97精品免费看片| 91wwwcom在线观看| 色青青草原桃花久久综合| 欧美精品www在线观看| 日韩亚洲欧美中文高清在线| 久久久91精品国产一区不卡| 欧美激情xxxx性bbbb| 91在线免费看网站| 久久伊人精品一区二区三区| 热99精品只有里视频精品| 日产精品99久久久久久| 国产欧美一区二区三区在线| 日韩av在线不卡| 永久免费看mv网站入口亚洲| 欧美日韩美女视频| 2023亚洲男人天堂| 欧美在线视频免费播放| 5566日本婷婷色中文字幕97| 欧美乱大交xxxxx另类电影| 97av视频在线| 97久久伊人激情网| 欧美国产中文字幕| 国产一区欧美二区三区| 日韩欧美在线网址| 欧美电影电视剧在线观看| 97久久精品在线| 日韩在线观看免费网站| 欧美激情三级免费| 国产精品久久9| 亚洲韩国欧洲国产日产av| 欧美国产日韩一区二区| 久久精品视频在线| 中文字幕亚洲第一| 精品久久久久久久久国产字幕| 91久久久久久久一区二区| 精品国产一区av| 国产日韩欧美日韩| 午夜精品久久久久久久男人的天堂| 国产精品一区二区三区久久久| 色中色综合影院手机版在线观看| 欧美日韩激情小视频| 欧美日韩激情小视频| 久久视频精品在线| 中文字幕av一区中文字幕天堂| 国产91成人video| 国产丝袜一区视频在线观看| 亚洲欧美福利视频| 亚洲毛茸茸少妇高潮呻吟| 欧美激情精品久久久久久变态| 青青草99啪国产免费| 日韩精品一区二区视频| 韩国美女主播一区| 亚洲深夜福利在线| 伊人久久男人天堂| 久久综合免费视频| 日韩视频精品在线| 91精品美女在线| 日韩的一区二区| 在线视频日本亚洲性| 中文字幕成人精品久久不卡| 亚洲免费av电影| 久久99精品国产99久久6尤物| 国产午夜精品免费一区二区三区| 久久久亚洲影院你懂的| 在线免费看av不卡| 精品日本高清在线播放| 色yeye香蕉凹凸一区二区av| 国产亚洲一区二区精品| 亚洲国产一区二区三区四区| 91九色国产社区在线观看| 亚洲国产精品专区久久| 久久成人人人人精品欧| 久久777国产线看观看精品| 亚洲图片欧洲图片av| 亚洲伊人久久大香线蕉av| 国内精品一区二区三区| 自拍偷拍亚洲欧美| 91在线免费网站| 欧美精品日韩www.p站| 日韩欧美高清视频| 国产一区二区三区三区在线观看| 亚洲美女av在线| 久久久国产精彩视频美女艺术照福利| 亚洲欧美精品一区二区| 久青草国产97香蕉在线视频| 国产成人精品视| 久久久精品2019中文字幕神马| 欧美激情videos| 亚洲一区二区免费| 亚洲欧美中文另类| 国产在线观看精品一区二区三区| 78m国产成人精品视频| 精品久久久久久亚洲国产300| 亚洲欧洲xxxx| 国精产品一区一区三区有限在线| 亚洲free性xxxx护士hd| 国产一区二区视频在线观看| 九九热精品视频| 91精品免费看| 中文字幕一区电影| 欧美激情一级精品国产| 国产成人免费av| 国产精品久久久久久亚洲影视| 91免费看片在线| 国产婷婷成人久久av免费高清| 青青久久aⅴ北条麻妃| 亚洲www永久成人夜色| 北条麻妃久久精品| 欧美日韩在线视频一区| 九九综合九九综合| 中文字幕视频一区二区在线有码| 日韩av网站大全| 久久中国妇女中文字幕| 欧美另类69精品久久久久9999| 欧美日韩综合视频| 夜夜嗨av色综合久久久综合网| 欧美久久精品一级黑人c片| 亚洲成年人影院在线| 亚洲精品视频在线观看视频| 91九色单男在线观看| 91精品视频免费| 亚洲国产精品久久久| 久久影视电视剧免费网站清宫辞电视| 97成人精品区在线播放| 久久久精品美女| 亚洲一区中文字幕在线观看| 中文字幕日韩在线播放| 色老头一区二区三区在线观看| 亚洲精品免费一区二区三区| 国产91成人在在线播放| 欧美精品在线观看| 久久精品99国产精品酒店日本| 91黑丝在线观看| 九九久久综合网站| 亚洲欧美综合区自拍另类| 中文字幕国产精品| 国产精品视频一区二区高潮| 亚洲色图18p| 色狠狠av一区二区三区香蕉蜜桃| 国产精品久久久久久亚洲影视| 国产精品视频自拍| 热久久免费视频精品| 欧美激情一区二区三区久久久| 日韩精品高清在线观看| 日韩精品免费综合视频在线播放| 欧美一级大片视频| 国产成人精品亚洲精品| 午夜精品一区二区三区av| 国产精品老牛影院在线观看|