青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 74, 文章 - 0, 評論 - 26, 引用 - 0
數(shù)據(jù)加載中……

Windows CE usb驅(qū)動程序

上述講了堆理論,可能讀者腦袋都已經(jīng)大了,為此,我們舉個(gè)簡單的例子來詳細(xì)說明一下驅(qū)動程序的開發(fā)過程。

例如我們有個(gè)USB Mouse設(shè)備,設(shè)備信息描述如下:
Device Descriptor:
bcdUSB: 0x0100
bDeviceClass: 0x00
bDeviceSubClass: 0x00
bDeviceProtocol: 0x00
bMaxPacketSize0: 0x08 (8)
idVendor: 0x05E3 (Genesys Logic Inc.)
idProduct: 0x0001
bcdDevice: 0x0101
iManufacturer: 0x00
iProduct: 0x01
iSerialNumber: 0x00
bNumConfigurations: 0x01

ConnectionStatus: DeviceConnected
Current Config value: 0x01
Device Bus Speed: Low
Device Address: 0x02
Open Pipes: 1

Endpoint Descriptor:
bEndpointAddress: 0x81
Transfer Type: Interrupt
wMaxPacketSize: 0x0003 (3)
bInterval: 0x0A

可以看出上述設(shè)備有一個(gè)中斷PIPE,包的最大值為3。可能有人問上述的值怎么得到的,win2k 的DDK中有個(gè)usbview的例程,編譯一下,將你的USB設(shè)備插到PC機(jī)的USB口中,運(yùn)行usbview.exe即可看得相應(yīng)的設(shè)備信息。

有了這些基本信息,就可以編寫USB設(shè)備了,首先聲明一下,下面的代碼取自微軟的USB鼠標(biāo)樣本程序,版權(quán)歸微軟所有,此處僅僅借用來描述一下USB鼠標(biāo)驅(qū)動的開發(fā)過程,讀者如需要引用此代碼,需要得到微軟的同意。

首先,必須輸出USBD要求調(diào)用的三個(gè)函數(shù),首先到設(shè)備插入到USB端口時(shí),USBD會調(diào)用USBDeviceAttach()函數(shù),相應(yīng)的代碼如下:
extern "C" BOOL
USBDeviceAttach(
USB_HANDLE hDevice, // USB設(shè)備句柄
LPCUSB_FUNCS lpUsbFuncs, // USBDI的函數(shù)集合
LPCUSB_INTERFACE lpInterface, // 設(shè)備接口描述信息
LPCWSTR szUniqueDriverId, // 設(shè)備ID描述字符串。
LPBOOL fAcceptControl, // 返回TRUE,標(biāo)識我們可以控制此設(shè)備, 反之表示不能控制
DWORD dwUnused)
{
*fAcceptControl = FALSE;
// 我們的鼠標(biāo)設(shè)備有特定的描述信息,要檢測是否是我們的設(shè)備。
if (lpInterface == NULL)
return FALSE;
// 打印相關(guān)的USB設(shè)備接口描述信息。
DEBUGMSG(ZONE_INIT,(TEXT("USBMouse: DeviceAttach, IF %u, #EP:%u, Class:%u, Sub:%u,Prot:%u\r\n"), lpInterface->Descriptor.bInterfaceNumber,lpInterface->Descriptor.bNumEndpoints, lpInterface->Descriptor.bInterfaceClass,lpInterface->Descriptor.bInterfaceSubClass,lpInterface->Descriptor.bInterfaceProtocol));
// 初試數(shù)據(jù)USB鼠標(biāo)類,產(chǎn)生一個(gè)接受USB鼠標(biāo)數(shù)據(jù)的線程
CMouse * pMouse = new CMouse(hDevice, lpUsbFuncs, lpInterface);
if (pMouse == NULL)
return FALSE;

if (!pMouse->Initialize())
{
delete pMouse;
return FALSE;
}

// 注冊一個(gè)監(jiān)控USB設(shè)備事件的回調(diào)函數(shù),用于監(jiān)控USB設(shè)備是否已經(jīng)拔掉。
(*lpUsbFuncs->lpRegisterNotificationRoutine)(hDevice,
USBDeviceNotifications, pMouse);

*fAcceptControl = TRUE;
return TRUE;
}

第二個(gè)函數(shù)是 USBInstallDriver()函數(shù),
一些基本定義如下:
const WCHAR gcszRegisterClientDriverId[] = L"RegisterClientDriverID";
const WCHAR gcszRegisterClientSettings[] = L"RegisterClientSettings";
const WCHAR gcszUnRegisterClientDriverId[] = L"UnRegisterClientDriverID";
const WCHAR gcszUnRegisterClientSettings[] = L"UnRegisterClientSettings";
const WCHAR gcszMouseDriverId[] = L"Generic_Sample_Mouse_Driver";

函數(shù)接口如下:
extern "C" BOOL
USBInstallDriver(
LPCWSTR szDriverLibFile) // @parm [IN] - Contains client driver DLL name
{
BOOL fRet = FALSE;
HINSTANCE hInst = LoadLibrary(L"USBD.DLL");

// 注冊USB設(shè)備信息
if(hInst)
{
LPREGISTER_CLIENT_DRIVER_ID pRegisterId = (LPREGISTER_CLIENT_DRIVER_ID)
GetProcAddress(hInst, gcszRegisterClientDriverId);

LPREGISTER_CLIENT_SETTINGS pRegisterSettings =
(LPREGISTER_CLIENT_SETTINGS) GetProcAddress(hInst,
gcszRegisterClientSettings);

if(pRegisterId && pRegisterSettings)
{
USB_DRIVER_SETTINGS DriverSettings;

DriverSettings.dwCount = sizeof(DriverSettings);

// 設(shè)置我們的特定的信息。
DriverSettings.dwVendorId = USB_NO_INFO;
DriverSettings.dwProductId = USB_NO_INFO;
DriverSettings.dwReleaseNumber = USB_NO_INFO;

DriverSettings.dwDeviceClass = USB_NO_INFO;
DriverSettings.dwDeviceSubClass = USB_NO_INFO;
DriverSettings.dwDeviceProtocol = USB_NO_INFO;

DriverSettings.dwInterfaceClass = 0x03; // HID
DriverSettings.dwInterfaceSubClass = 0x01; // boot device
DriverSettings.dwInterfaceProtocol = 0x02; // mouse

fRet = (*pRegisterId)(gcszMouseDriverId);

if(fRet)
{
fRet = (*pRegisterSettings)(szDriverLibFile,
gcszMouseDriverId, NULL, &DriverSettings);

if(!fRet)
{
//BUGBUG unregister the Client Driver’s ID
}
}
}
else
{
RETAILMSG(1,(TEXT("!USBMouse: Error getting USBD function pointers\r\n")));
}
FreeLibrary(hInst);
}
return fRet;
}
上述代碼主要用于產(chǎn)生USB設(shè)備驅(qū)動程序需要的注冊表信息,需要注意的是:USB設(shè)備驅(qū)動程序不使用標(biāo)準(zhǔn)的注冊表函數(shù),而是使用RegisterClientDriverID()和RegisterClientSettings來注冊相應(yīng)的設(shè)備信息。

另外一個(gè)函數(shù)是USBUninstallDriver()函數(shù),具體代碼如下:
extern "C" BOOL
USBUnInstallDriver()
{
BOOL fRet = FALSE;
HINSTANCE hInst = LoadLibrary(L"USBD.DLL");

if(hInst)
{
LPUN_REGISTER_CLIENT_DRIVER_ID pUnRegisterId =
(LPUN_REGISTER_CLIENT_DRIVER_ID)
GetProcAddress(hInst, gcszUnRegisterClientDriverId);

LPUN_REGISTER_CLIENT_SETTINGS pUnRegisterSettings =
(LPUN_REGISTER_CLIENT_SETTINGS) GetProcAddress(hInst,
gcszUnRegisterClientSettings);

if(pUnRegisterSettings)
{
USB_DRIVER_SETTINGS DriverSettings;

DriverSettings.dwCount = sizeof(DriverSettings);
// 必須填入與注冊時(shí)相同的信息。
DriverSettings.dwVendorId = USB_NO_INFO;
DriverSettings.dwProductId = USB_NO_INFO;
DriverSettings.dwReleaseNumber = USB_NO_INFO;

DriverSettings.dwDeviceClass = USB_NO_INFO;
DriverSettings.dwDeviceSubClass = USB_NO_INFO;
DriverSettings.dwDeviceProtocol = USB_NO_INFO;

DriverSettings.dwInterfaceClass = 0x03; // HID
DriverSettings.dwInterfaceSubClass = 0x01; // boot device
DriverSettings.dwInterfaceProtocol = 0x02; // mouse

fRet = (*pUnRegisterSettings)(gcszMouseDriverId, NULL,
&DriverSettings);
}

if(pUnRegisterId)
{
BOOL fRetTemp = (*pUnRegisterId)(gcszMouseDriverId);
fRet = fRet ? fRetTemp : fRet;
}
FreeLibrary(hInst);
}
return fRet;
}
此函數(shù)主要用于刪除USBInstallDriver()時(shí)創(chuàng)建的注冊表信息,同樣的它使用自己的函數(shù)接口UnRegisterClientDriverID()和UnRegisterClientSettings()來做相應(yīng)的處理。

另外一個(gè)需要處理的注冊的監(jiān)控通知函數(shù)USBDeviceNotifications():
extern "C" BOOL USBDeviceNotifications(LPVOID lpvNotifyParameter, DWORD dwCode,
LPDWORD * dwInfo1, LPDWORD * dwInfo2, LPDWORD * dwInfo3,
LPDWORD * dwInfo4)
{
CMouse * pMouse = (CMouse *)lpvNotifyParameter;

switch(dwCode)
{
case USB_CLOSE_DEVICE:
//刪除相關(guān)的資源。
delete pMouse;
return TRUE;
}
return FALSE;
}


USB鼠標(biāo)的類的定義如下:
class CMouse
{
public:
CMouse::CMouse(USB_HANDLE hDevice, LPCUSB_FUNCS lpUsbFuncs,
LPCUSB_INTERFACE lpInterface);
~CMouse();

BOOL Initialize();
private:
// 傳輸完畢調(diào)用的回調(diào)函數(shù)
static DWORD CALLBACK MouseTransferCompleteStub(LPVOID lpvNotifyParameter);
// 中斷處理函數(shù)
static ULONG CALLBACK CMouse::MouseThreadStub(PVOID context);
DWORD MouseTransferComplete();
DWORD MouseThread();

BOOL SubmitInterrupt();
BOOL HandleInterrupt();

BOOL m_fClosing;
BOOL m_fReadyForMouseEvents;

HANDLE m_hEvent;
HANDLE m_hThread;

USB_HANDLE m_hDevice;
USB_PIPE m_hInterruptPipe;
USB_TRANSFER m_hInterruptTransfer;

LPCUSB_FUNCS m_lpUsbFuncs;
LPCUSB_INTERFACE m_pInterface;

BOOL m_fPrevButton1;
BOOL m_fPrevButton2;
BOOL m_fPrevButton3;

// 數(shù)據(jù)接受緩沖區(qū)。
BYTE m_pbDataBuffer[8];
};

具體實(shí)現(xiàn)如下:

// 構(gòu)造函數(shù),初始化時(shí)調(diào)用
CMouse::CMouse(USB_HANDLE hDevice, LPCUSB_FUNCS lpUsbFuncs,
LPCUSB_INTERFACE lpInterface)
{
m_fClosing = FALSE;
m_fReadyForMouseEvents = FALSE;
m_hEvent = NULL;
m_hThread = NULL;

m_hDevice = hDevice;
m_hInterruptPipe = NULL;
m_hInterruptTransfer = NULL;

m_lpUsbFuncs = lpUsbFuncs;
m_pInterface = lpInterface;

m_fPrevButton1 = FALSE;
m_fPrevButton2 = FALSE;
m_fPrevButton3 = FALSE;

memset(m_pbDataBuffer, 0, sizeof(m_pbDataBuffer));
}

// 析構(gòu)函數(shù),用于清除申請的資源。
CMouse::~CMouse()
{
// 通知系統(tǒng)去關(guān)閉相關(guān)的函數(shù)接口。
m_fClosing = TRUE;

// Wake up the connection thread again and give it time to die.
if (m_hEvent != NULL)
{
// 通知關(guān)閉數(shù)據(jù)接受線程。
SetEvent(m_hEvent);

if (m_hThread != NULL)
{
DWORD dwWaitReturn;

dwWaitReturn = WaitForSingleObject(m_hThread, 1000);
if (dwWaitReturn != WAIT_OBJECT_0)
{
TerminateThread(m_hThread, DWORD(-1));
}
CloseHandle(m_hThread);
m_hThread = NULL;
}
CloseHandle(m_hEvent);
m_hEvent = NULL;
}

if(m_hInterruptTransfer)
(*m_lpUsbFuncs->lpCloseTransfer)(m_hInterruptTransfer);

if(m_hInterruptPipe)
(*m_lpUsbFuncs->lpClosePipe)(m_hInterruptPipe);
}


// 初始化USB鼠標(biāo)驅(qū)動程序
BOOL CMouse::Initialize()
{
LPCUSB_DEVICE lpDeviceInfo = (*m_lpUsbFuncs->lpGetDeviceInfo)(m_hDevice);

// 檢測配置:USB鼠標(biāo)應(yīng)該只有一個(gè)中斷管道
if ((m_pInterface->lpEndpoints[0].Descriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK) != USB_ENDPOINT_TYPE_INTERRUPT)
{
RETAILMSG(1,(TEXT("!USBMouse: EP 0 wrong type (%u)!\r\n"),
m_pInterface->lpEndpoints[0].Descriptor.bmAttributes));
return FALSE;
}
DEBUGMSG(ZONE_INIT,(TEXT("USBMouse: EP 0:MaxPacket: %u, Interval: %u\r\n"),
m_pInterface->lpEndpoints[0].Descriptor.wMaxPacketSize,
m_pInterface->lpEndpoints[0].Descriptor.bInterval));

m_hInterruptPipe = (*m_lpUsbFuncs->lpOpenPipe)(m_hDevice,
&m_pInterface->lpEndpoints[0].Descriptor);

if (m_hInterruptPipe == NULL) {
RETAILMSG(1,(TEXT("Mouse: Error opening interrupt pipe\r\n")));
return (FALSE);
}
m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (m_hEvent == NULL)
{
RETAILMSG(1,(TEXT("USBMouse: Error on CreateEvent for connect event\r\n")));
return(FALSE);
}
// 創(chuàng)建數(shù)據(jù)接受線程
m_hThread = CreateThread(0, 0, MouseThreadStub, this, 0, NULL);
if (m_hThread == NULL)
{
RETAILMSG(1,(TEXT("USBMouse: Error on CreateThread\r\n")));
return(FALSE);
}

return(TRUE);
}

// 從USB鼠標(biāo)設(shè)備中讀出數(shù)據(jù),產(chǎn)生相應(yīng)的鼠標(biāo)事件。
BOOL CMouse::SubmitInterrupt()
{
if(m_hInterruptTransfer)
(*m_lpUsbFuncs->lpCloseTransfer)(m_hInterruptTransfer);

// 從USB鼠標(biāo)PIPE中讀數(shù)據(jù)
m_hInterruptTransfer = (*m_lpUsbFuncs->lpIssueInterruptTransfer)
(m_hInterruptPipe, MouseTransferCompleteStub, this,
USB_IN_TRANSFER | USB_SHORT_TRANSFER_OK, // 表示讀數(shù)據(jù)
min(m_pInterface->lpEndpoints[0].Descriptor.wMaxPacketSize,
sizeof(m_pbDataBuffer)),
m_pbDataBuffer,
NULL);

if (m_hInterruptTransfer == NULL)
{
DEBUGMSG(ZONE_ERROR,(L "!USBMouse: Error in IssueInterruptTransfer\r\n"));
return FALSE;
}
else
{
DEBUGMSG(ZONE_TRANSFER,(L"USBMouse::SubmitInterrupt,Transfer:0x%X\r\n",
m_hInterruptTransfer));
}
return TRUE;
}

// 處理鼠標(biāo)中斷傳輸?shù)臄?shù)據(jù)
BOOL CMouse::HandleInterrupt()
{
DWORD dwError;
DWORD dwBytes;

DWORD dwFlags = 0;
INT dx = (signed char)m_pbDataBuffer[1];
INT dy = (signed char)m_pbDataBuffer[2];

BOOL fButton1 = m_pbDataBuffer[0] & 0x01 ? TRUE : FALSE;
BOOL fButton2 = m_pbDataBuffer[0] & 0x02 ? TRUE : FALSE;
BOOL fButton3 = m_pbDataBuffer[0] & 0x04 ? TRUE : FALSE;

if (!(*m_lpUsbFuncs->lpGetTransferStatus)(m_hInterruptTransfer, &dwBytes,&dwError))
{
DEBUGMSG(ZONE_ERROR,(TEXT("!USBMouse: Error in GetTransferStatus(0x%X)\r\n"),
m_hInterruptTransfer));
return FALSE;
}
else
{
DEBUGMSG(ZONE_TRANSFER,(TEXT("USBMouse::HandleInterrupt, hTransfer 0x%X complete (%u bytes, Error:%X)\r\n"),
m_hInterruptTransfer,dwBytes,dwError));
}

if (!SubmitInterrupt())
return FALSE;

if(dwError != USB_NO_ERROR)
{
DEBUGMSG(ZONE_ERROR,(TEXT("!USBMouse: Error 0x%X in interrupt transfer\r\n"),dwError));
return TRUE;
}

if(dwBytes < 3)
{
DEBUGMSG(ZONE_ERROR,(TEXT("!USBMouse: Invalid byte cnt %u from interrupt transfer\r\n"),dwBytes));
return TRUE;
}

if(dx || dy)
dwFlags |= MOUSEEVENTF_MOVE;

if(fButton1 != m_fPrevButton1)
{
if(fButton1)
dwFlags |= MOUSEEVENTF_LEFTDOWN;
else
dwFlags |= MOUSEEVENTF_LEFTUP;
}

if(fButton2 != m_fPrevButton2)
{
if(fButton2)
dwFlags |= MOUSEEVENTF_RIGHTDOWN;
else
dwFlags |= MOUSEEVENTF_RIGHTUP;
}

if(fButton3 != m_fPrevButton3)
{
if(fButton3)
dwFlags |= MOUSEEVENTF_MIDDLEDOWN;
else
dwFlags |= MOUSEEVENTF_MIDDLEUP;
}

m_fPrevButton1 = fButton1;
m_fPrevButton2 = fButton2;
m_fPrevButton3 = fButton3;

DEBUGMSG(ZONE_EVENTS,
(TEXT("USBMouse event: dx:%d, dy:%d, dwFlags:0x%X (B1:%u, B2:%u, B3:%u)\r\n"),
dx,dy,dwFlags,fButton1,fButton2,fButton3));

// 通知系統(tǒng)產(chǎn)生鼠標(biāo)事件
if (m_fReadyForMouseEvents)
mouse_event(dwFlags, dx, dy, 0, 0);
else
m_fReadyForMouseEvents = IsAPIReady(SH_WMGR);

return TRUE;
}


DWORD CALLBACK CMouse::MouseTransferCompleteStub(LPVOID lpvNotifyParameter)
{
CMouse * pMouse = (CMouse *)lpvNotifyParameter;
return(pMouse->MouseTransferComplete());
}

// 數(shù)據(jù)傳輸完畢回調(diào)函數(shù)
DWORD CMouse::MouseTransferComplete()
{
if (m_hEvent)
SetEvent(m_hEvent);
return 0;
}


ULONG CALLBACK CMouse::MouseThreadStub(PVOID context)
{
CMouse * pMouse = (CMouse *)context;
return(pMouse->MouseThread());
}

// USB鼠標(biāo)線程
DWORD CMouse::MouseThread()
{
DEBUGMSG(ZONE_INIT,(TEXT("USBMouse: Worker thread started\r\n")));
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);

if (SubmitInterrupt())
{
while (!m_fClosing)
{
WaitForSingleObject(m_hEvent, INFINITE);

if (m_fClosing)
break;

if ((*m_lpUsbFuncs->lpIsTransferComplete)(m_hInterruptTransfer))
{
if (!HandleInterrupt())
break;
}
else
{
RETAILMSG(1,(TEXT("!USBMouse: Event signalled, but transfer not complete\r\n")));
// The only time this should happen is if we get an error on the transfer
ASSERT(m_fClosing || (m_hInterruptTransfer == NULL));
break;
}
}
}
RETAILMSG(1,(TEXT("USBMouse: Worker thread exiting\r\n")));
return(0);
}

看 到了沒有,其實(shí)USB的驅(qū)動程序編寫就這么簡單,類似的其他設(shè)備,例如打印機(jī)設(shè)備,就有Bulk OUT PIPE,需要Bulk傳輸,那就需要了解一下IssueBulkTransfer()的應(yīng)用。當(dāng)然如果是開發(fā)USB Mass Storage Disk的驅(qū)動,那就需要了解更多的協(xié)議,例如Bulk-Only Transport協(xié)議等。

微軟的Windows CE.NET的Platform Build中已經(jīng)帶有USB Printer和USB Mass Storage Disk的驅(qū)動的源代碼了,好好研究一下,你一定回受益非淺的。



參考資料:
1. 微軟出版社 <<Windows Ce Device Driver Kit>>
2. <<Universal Serial Bus Specification 1.1>> 來自http:://www.usb.org

posted on 2008-12-03 10:35 井泉 閱讀(1322) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            日韩一本二本av| 亚洲精品日产精品乱码不卡| 黄色成人免费观看| 在线视频中文亚洲| 一区二区三区四区五区视频 | 久久亚洲私人国产精品va媚药| 欧美激情第9页| 欧美成va人片在线观看| 老鸭窝毛片一区二区三区| 久久久国产精品一区| 久久久久久久久久久久久久一区| 欧美在线视频免费| 久久九九久精品国产免费直播| 欧美激情在线| 亚洲靠逼com| 亚洲欧美亚洲| 久久综合伊人| 欧美电影免费网站| 先锋影音国产一区| 亚洲欧美视频在线观看| 欧美色123| 欧美精品在线极品| 国产精品亚洲综合天堂夜夜| 国产亚洲福利社区一区| 亚洲激情电影中文字幕| 亚洲综合好骚| 麻豆精品在线观看| 亚洲综合好骚| 欧美日本成人| 亚洲激情小视频| 先锋影院在线亚洲| 日韩午夜黄色| 蜜桃伊人久久| 在线电影欧美日韩一区二区私密| 老司机免费视频久久| 国产精品视频999| 亚洲性人人天天夜夜摸| 亚洲人久久久| 午夜精品久久久久久99热软件| 欧美精品一区二区三区久久久竹菊 | 亚洲天堂第二页| 欧美午夜精品久久久久久浪潮| 欧美午夜寂寞影院| 在线亚洲伦理| 亚洲一品av免费观看| 欧美视频中文在线看| 亚洲免费视频在线观看| 夜夜躁日日躁狠狠久久88av| 久久这里只有| 精品999网站| 亚洲精美视频| 国产精品美女一区二区| 久久精品夜色噜噜亚洲aⅴ| 久久免费99精品久久久久久| 91久久中文| 99国产精品国产精品久久| 欧美视频免费| 欧美成人性生活| 欧美日韩国产综合一区二区| 午夜精品久久久久久久蜜桃app| 亚洲一区免费看| 亚洲高清中文字幕| 亚洲一区二区免费在线| 亚洲经典在线看| 亚洲欧洲视频| 国产欧美日韩在线视频| 久久久久久亚洲综合影院红桃 | 在线视频精品一区| 国产在线麻豆精品观看| 亚洲美女在线观看| 国产一区二区三区黄| 中日韩午夜理伦电影免费| 在线观看精品一区| 欧美一级片在线播放| 你懂的视频欧美| 久久久亚洲人| 国产一区二区三区日韩欧美| 日韩亚洲在线| 亚洲性xxxx| 国产精品国产福利国产秒拍| 亚洲乱码视频| 亚洲一区网站| 欧美激情在线| 欧美不卡视频一区发布| 在线观看一区视频| 美女主播一区| 国产伦精品一区二区三区| 欧美大片91| 99精品欧美一区| 一本久久综合亚洲鲁鲁| 欧美高清视频在线播放| 亚洲午夜精品国产| 久久久www| 亚洲国产aⅴ天堂久久| 91久久一区二区| 欧美日韩中文在线观看| 欧美有码在线视频| 亚洲国产日韩在线一区模特| 亚洲私人影院| 亚洲国产精品999| 亚洲毛片一区| 久久久久高清| 宅男在线国产精品| 亚洲福利av| 国产乱码精品1区2区3区| 久久久久久久久久久久久久一区| 亚洲日本欧美天堂| 欧美国产日韩在线观看| 欧美亚洲自偷自偷| 一区二区三区国产在线| 狠狠噜噜久久| 亚洲中无吗在线| 亚洲韩日在线| 免费欧美日韩| 久久琪琪电影院| 久久久欧美精品sm网站| 欧美在线播放高清精品| 亚洲影院污污.| 欧美一区二区女人| 久久gogo国模裸体人体| 久久成人精品视频| 欧美一区三区二区在线观看| 一本久道综合久久精品| 99国产精品久久久久久久久久| 亚洲欧洲精品一区二区精品久久久| 伊人久久综合| 制服丝袜激情欧洲亚洲| 亚洲一区二区三区成人在线视频精品| 亚洲精品网址在线观看| 一级日韩一区在线观看| 亚洲欧美日韩一区二区| 麻豆精品在线视频| 亚洲看片免费| 欧美一区影院| 欧美日韩免费视频| 激情懂色av一区av二区av| 亚洲免费黄色| 美女国内精品自产拍在线播放| 91久久精品国产91久久性色| 亚洲精选国产| 欧美成人一区二免费视频软件| 欧美日韩一区在线| 国产一区自拍视频| 亚洲无毛电影| 亚洲国产成人av在线| 欧美一区二区三区在线免费观看| 久久久久久久久久看片| 国产毛片一区| 午夜视频在线观看一区| 亚洲国产美国国产综合一区二区| 亚洲午夜性刺激影院| 欧美国产第一页| 99这里只有精品| 亚洲国产精品电影| 久久精品免费| 欧美一激情一区二区三区| 国产日韩欧美精品在线| 久久成人免费视频| 亚洲在线中文字幕| 国产精品乱人伦中文| 亚洲欧美偷拍卡通变态| 亚洲日韩欧美视频| 欧美午夜电影一区| 香蕉久久精品日日躁夜夜躁| 久久综合久久久久88| 久久免费国产| 夜夜嗨av一区二区三区四区| 亚洲激情网站| 国产精品青草综合久久久久99 | 国内精品福利| 欧美va天堂| 欧美视频一区在线观看| 欧美在线亚洲一区| 久久综合色8888| 亚洲欧美在线aaa| 免费观看在线综合| 亚洲欧洲一区二区三区| 在线亚洲+欧美+日本专区| 国产精品美女主播| 久久久久国产精品麻豆ai换脸| 久久电影一区| 另类激情亚洲| 99热精品在线| 国产在线日韩| 在线视频精品| 亚洲精选91| 久久亚洲色图| 欧美亚洲视频在线观看| 欧美福利电影在线观看| 久久九九热免费视频| 欧美日韩爆操| 亚洲风情亚aⅴ在线发布| 国产精品裸体一区二区三区| 国产综合18久久久久久| 亚洲一区二区精品| 亚洲欧美视频在线| 欧美精品尤物在线| 亚洲人成高清| 99视频一区二区| 欧美精品一区在线播放|