亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? readwrite.cpp

?? 一本在講述USB驅動程式的書 及其范例原碼
?? CPP
?? 第 1 頁 / 共 2 頁
字號:
// Read/Write request processors for usbiso driver
// Copyright (C) 1999 by Walter Oney
// All rights reserved

#include "stddcls.h"
#include "driver.h"

#if DBG
	#define MSGUSBSTRING(d,s,i) { \
		UNICODE_STRING sd; \
		if (i && NT_SUCCESS(GetStringDescriptor(d,i,&sd))) { \
			DbgPrint(s, sd.Buffer); \
			RtlFreeUnicodeString(&sd); \
		}}
#else
	#define MSGUSBSTRING(d,i,s)
#endif

typedef struct _RWCONTEXT {
	LIST_ENTRY list;			// list for queuing context structures
	PDEVICE_EXTENSION pdx;		// our device extension address
	PIRP mainirp;				// the main r/w IRP
	NTSTATUS status;			// ending status for main IRP
	ULONG numxfer;				// total number of bytes transferred
	ULONG numirps;				// total number of sub-irps
	LONG numpending;			// number of sub-irps not yet finished
	LONG refcnt;				// reference count (initially 2)
	struct {
		PIRP irp;				// subsidiary IRP
		PURB urb;				// URB packaged with sub-IRP
		PMDL mdl;				// partial MDL for the URB
		} sub[1];
	} RWCONTEXT, *PRWCONTEXT;

BOOLEAN DestroyContextStructure(PRWCONTEXT ctx);
ULONG GetCurrentFrame(PDEVICE_EXTENSION pdx);
VOID OnCancelReadWrite(PDEVICE_OBJECT fdo, PIRP Irp);
NTSTATUS OnReadWriteComplete(PDEVICE_OBJECT fdo, PIRP Irp, PRWCONTEXT context);
NTSTATUS OnStageComplete(PDEVICE_OBJECT fdo, PIRP Irp, PRWCONTEXT context);

NTSTATUS SelectAlternateInterface(PDEVICE_OBJECT fdo);
NTSTATUS SelectDefaultInterface(PDEVICE_OBJECT fdo);

///////////////////////////////////////////////////////////////////////////////

#pragma LOCKEDCODE

BOOLEAN DestroyContextStructure(PRWCONTEXT ctx)
	{							// DestroyContextStructure

	// Decrement the reference count. If it goes to zero, delete
	// all the subsidiary IRPs and the context structure itself.

	if (InterlockedDecrement(&ctx->refcnt) > 0)
		return FALSE;					// still potentially in use
	for (ULONG i = 0; i < ctx->numirps; ++i)
		if (ctx->sub[i].irp)
			IoFreeIrp(ctx->sub[i].irp);
	ExFreePool(ctx);
	return TRUE;
	}							// DestroyContextStructure

///////////////////////////////////////////////////////////////////////////////

#pragma PAGEDCODE

NTSTATUS DispatchCreate(PDEVICE_OBJECT fdo, PIRP Irp)
	{							// DispatchCreate
	PAGED_CODE();
	KdPrint((DRIVERNAME " - IRP_MJ_CREATE\n"));
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);

	NTSTATUS status = STATUS_SUCCESS;
	
	if (InterlockedIncrement(&pdx->handles) == 1)
		{					// no handles previously open
		status = SelectAlternateInterface(fdo);
		if (!NT_SUCCESS(status))
			{				// error selecting alternate interface
			InterlockedDecrement(&pdx->handles);
			IoReleaseRemoveLock(&pdx->RemoveLock, stack->FileObject);
			}				// error selecting alternate interface
		}					// no handles previously open

	return CompleteRequest(Irp, status, 0);
	}							// DispatchCreate

///////////////////////////////////////////////////////////////////////////////

#pragma PAGEDCODE

NTSTATUS DispatchClose(PDEVICE_OBJECT fdo, PIRP Irp)
	{							// DispatchClose
	PAGED_CODE();
	KdPrint((DRIVERNAME " - IRP_MJ_CLOSE\n"));
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
	if (InterlockedDecrement(&pdx->handles) == 0)
		SelectDefaultInterface(fdo);
	return CompleteRequest(Irp, STATUS_SUCCESS, 0);
	}							// DispatchClose

///////////////////////////////////////////////////////////////////////////////

#pragma PAGEDCODE

NTSTATUS DispatchRead(PDEVICE_OBJECT fdo, PIRP Irp)
	{							// DispatchRead
	PAGED_CODE();
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

	ASSERT(pdx->hinpipe);

	NTSTATUS status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
	if (!NT_SUCCESS(status))
		return CompleteRequest(Irp, status, 0);

	ULONG length = Irp->MdlAddress ?  MmGetMdlByteCount(Irp->MdlAddress) : 0;
	if (!length)
		{						// zero-length read
		IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
		return CompleteRequest(Irp, STATUS_SUCCESS, 0);
		}						// zero-length read

	// Calculate the number of IRPs that we need to submit in order to fulfill the
	// request. One of the ingredients of the calculation is the "packet size" the
	// endpoint uses during each frame. We have to know this number a priori, because
	// it doesn't have a fixed relationship to the endpoint's transfer size. Another
	// ingredient of the calculation is the fact that one URB can accomodate only 255
	// packets. The last ingredient is the maximum transfer size we declared when we
	// first configured the pipe. This driver left the default value in place. Given
	// the value of 16 used here for the packet size, we'll end up with a "segsize" of
	// 4080 bytes in fact.

	ULONG packsize = 16;		// known because we write the firmware
	ULONG segsize = USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE; // default we left in place
	if (segsize / packsize > 255)
		segsize = 255 * packsize;	// maximum based on # packets allowed
	ULONG numirps = (length + segsize - 1) / segsize;

	// Allocate a context structure for use in the main IRP's completion and cancel routines.
	// Build as many IRPs (and URBs) as are required to fulfill the request.

	ULONG ctxsize = sizeof(RWCONTEXT) + (numirps - 1) * sizeof(((PRWCONTEXT) 0)->sub);
	PRWCONTEXT ctx = (PRWCONTEXT) ExAllocatePool(NonPagedPool, ctxsize);
	if (!ctx)
		{
		KdPrint((DRIVERNAME	" - unable to allocate %d bytes for record keeping\n", ctxsize));
		IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
		return CompleteRequest(Irp, STATUS_INSUFFICIENT_RESOURCES, 0);
		}
	RtlZeroMemory(ctx, ctxsize);

	ctx->numirps = ctx->numpending = numirps;
	ctx->pdx = pdx;
	ctx->mainirp = Irp;
	ctx->refcnt = 2;			// one for OnReadWriteComplete, one forOnCancelReadWrite
	Irp->Tail.Overlay.DriverContext[0] = (PVOID) ctx; // for cancel routine

	ULONG frame = GetCurrentFrame(pdx) + 2;		// start first URB 2 frames from now
	KdPrint((DRIVERNAME " - First transfer scheduled for frame %8.8lX\n", frame));

	ULONG i;
	CCHAR stacksize = pdx->LowerDeviceObject->StackSize + 1; // 1 extra for OnStageComplete
	PUCHAR va = (PUCHAR) MmGetMdlVirtualAddress(Irp->MdlAddress);

	for (i = 0; i < numirps; ++i)
		{						// for each IRP

		// Create a subsidiary IRP

		PIRP subirp = IoAllocateIrp(stacksize, FALSE);
		if (!subirp)
			break;				// can't create subsidiary IRP
		ctx->sub[i].irp = subirp;

		// Determine how many packets are required and allocate an URB big enough for all of them

		if (segsize > length)
			segsize = length;	// last transfer is short

		ULONG npackets = (segsize + packsize - 1) / packsize; // # packets needed in this stage
		ASSERT(npackets <= 255);	// else we didn't calculate segsize correctly
		ULONG size = GET_ISO_URB_SIZE(npackets); // size of URB needed for that many packets
		PURB urb = (PURB) ExAllocatePool(NonPagedPool, size);
		if (!urb)
			break;

		ctx->sub[i].urb = urb;

		// Create a partial MDL to map this segment. This is necessary because the offset fields in
		// the packet descriptors we'll build must begin at zero for each URB. (It would have been better
		// if they were just relative to whatever MDL in in the URB.)

		PMDL mdl = IoAllocateMdl((PVOID) va, segsize, FALSE, FALSE, NULL);
		if (!mdl)
			break;				// can't allocate memory for MDL
		IoBuildPartialMdl(Irp->MdlAddress, mdl, (PVOID) va, segsize);
		ctx->sub[i].mdl = mdl;
		va += segsize;			// for next iteration

		// Initialize the URB. Use a specific frame number rather than specifying the ASAP
		// flag. Much to my surprise, the bus driver will schedule a second ASAP transfer immediately
		// instead of waiting for current transfers to finish. This is contrary to what the DDK
		// doc says and is, I believe, a bug in XP.

		RtlZeroMemory(urb, size);
		urb->UrbIsochronousTransfer.Hdr.Length = (USHORT) size;
		urb->UrbIsochronousTransfer.Hdr.Function = URB_FUNCTION_ISOCH_TRANSFER;
		urb->UrbIsochronousTransfer.PipeHandle = pdx->hinpipe;
		urb->UrbIsochronousTransfer.TransferFlags = USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK;
		urb->UrbIsochronousTransfer.TransferBufferLength = segsize;
		urb->UrbIsochronousTransfer.TransferBufferMDL = mdl;
		urb->UrbIsochronousTransfer.NumberOfPackets = npackets;
		urb->UrbIsochronousTransfer.StartFrame = frame;

		// Initialize the buffer offset in each packet. The host controller will fill in the packet
		// length in one of two ways. For an input operation, it gets set to whatever the device
		// supplies. For an output operation, the host controller driver sets it based on the buffer
		// offsets.

		ULONG offset = 0;			// packet offset within subsidiary MDL

		for (ULONG j = 0; j < npackets; ++j)
			{						// for each packet
			urb->UrbIsochronousTransfer.IsoPacket[j].Offset = offset;
			ULONG packlen = length > packsize ? packsize : length;
			urb->UrbIsochronousTransfer.IsoPacket[j].Length = 0;

			length -= packlen;
			offset += packlen;
			}						// for each packet

		frame += npackets;			// frame for next URB

		// Initialize the subsidiary IRP. The first stack location is for use by OnStageComplete,
		// which needs several pieces of information it's inconvenient to pass in a single
		// context pointer. The second stack location will describe an internal IOCTL for USBD.

		IoSetNextIrpStackLocation(subirp);
		PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(subirp);
		stack->DeviceObject = fdo;
		stack->Parameters.Others.Argument1 = (PVOID) urb;
		stack->Parameters.Others.Argument2 = (PVOID) mdl;

		stack = IoGetNextIrpStackLocation(subirp);
		stack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
		stack->Parameters.Others.Argument1 = (PVOID) urb;
		stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
		
		IoSetCompletionRoutine(subirp, (PIO_COMPLETION_ROUTINE) OnStageComplete,
			(PVOID) ctx, TRUE, TRUE, TRUE);
		}						// for each IRP

	// If the IRP/URB construction loop finished early, there must have been a memory allocation
	// error.

	if (i < numirps)
		status = STATUS_INSUFFICIENT_RESOURCES;

	// See if the main IRP has already been cancelled.

	else
		{						// check for cancellation
		IoSetCancelRoutine(Irp, OnCancelReadWrite);
		if (Irp->Cancel)
			{
			status = STATUS_CANCELLED;

			// The main IRP has been cancelled. If the cancellation just happened and our
			// cancel routine was called, the following call to IoSetCancelRoutine will
			// return NULL. In this case, both our cleanup code (see below) and the cancel
			// routine will be calling DestroyContextStructure. One or the other of those
			// calls will finish the cleanup of the structure. Otherwise, it will no longer
			// be possible for our cancel routine to get called and we should get rid of
			// its now-unnecessary claim on the structure.

			if (IoSetCancelRoutine(Irp, NULL))
				--ctx->refcnt;
			}
		else
			status = STATUS_SUCCESS;
		}						// check for cancellation

	// Install a completion routine for the main IRP. It will normally be called when
	// the last stage IRP finishes. It might get called pretty soon, though, if we
	// fail the IRP before submitting the stage IRPs.

	IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) OnReadWriteComplete,
		(PVOID) ctx, TRUE, TRUE, TRUE);
	IoMarkIrpPending(Irp);
	IoSetNextIrpStackLocation(Irp);	// so our completion routine will get called

	// If we need to fail the main IRP, cleanup and fail it now.

	if (!NT_SUCCESS(status))
		{						// abort now
		for (i = 0; i < numirps; ++i)
			{					// release memory we were able to allocate
			if (ctx->sub[i].urb)
				ExFreePool(ctx->sub[i].urb);
			if (ctx->sub[i].mdl)
				IoFreeMdl(ctx->sub[i].mdl);
			}					// release memory we were able to allocate
		CompleteRequest(Irp, status, 0); // will trigger completion routine
		return STATUS_PENDING;
		}						// abort now

	ASSERT(length == 0);		// IRP construction loop didn't work right if not true

	// Install a completion routine for the main IRP. Once this is in place, submit the
	// subsidiary IRPs. Note that we can't touch the main IRP pointer after we submit the
	// subsidiary IRPs because the sub-IRP completion routine (OnStageComplete) may complete it.

	for (i = 0; i < numirps; ++i)
		IoCallDriver(pdx->LowerDeviceObject, ctx->sub[i].irp);

	return STATUS_PENDING;
	}							// DispatchRead

///////////////////////////////////////////////////////////////////////////////
// GetCurrentFrame obtains the current USB frame number

#pragma PAGEDCODE

ULONG GetCurrentFrame(PDEVICE_EXTENSION pdx)
	{							// GetCurrentFrame
	URB urb;
	urb.UrbGetCurrentFrameNumber.Hdr.Length = sizeof(struct _URB_GET_CURRENT_FRAME_NUMBER);
	urb.UrbGetCurrentFrameNumber.Hdr.Function = URB_FUNCTION_GET_CURRENT_FRAME_NUMBER;

	NTSTATUS status = SendAwaitUrb(pdx->DeviceObject, &urb);
	if (!NT_SUCCESS(status))
		{
		KdPrint((DRIVERNAME " - URB_FUNCTION_GET_CURRENT_FRAME_NUMBER failed - %X\n", status));
		return 0;
		}

	return urb.UrbGetCurrentFrameNumber.FrameNumber;
	}							// GetCurrentFrame

///////////////////////////////////////////////////////////////////////////////

#pragma PAGEDCODE

NTSTATUS GetStringDescriptor(PDEVICE_OBJECT fdo, UCHAR istring, PUNICODE_STRING s)
	{							// GetStringDescriptor
	NTSTATUS status;
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
	URB urb;

	UCHAR data[256];			// maximum-length buffer

	// If this is the first time here, read string descriptor zero and arbitrarily select
	// the first language identifer as the one to use in subsequent get-descriptor calls.

	if (!pdx->langid)
		{						// determine default language id
		UsbBuildGetDescriptorRequest(&urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_STRING_DESCRIPTOR_TYPE,
			0, 0, data, NULL, sizeof(data), NULL);
		status = SendAwaitUrb(fdo, &urb);
		if (!NT_SUCCESS(status))
			return status;
		pdx->langid = *(LANGID*)(data + 2);
		}						// determine default language id

	// Fetch the designated string descriptor.

	UsbBuildGetDescriptorRequest(&urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_STRING_DESCRIPTOR_TYPE,
		istring, pdx->langid, data, NULL, sizeof(data), NULL);
	status = SendAwaitUrb(fdo, &urb);
	if (!NT_SUCCESS(status))
		return status;

	ULONG nchars = (data[0] - sizeof(WCHAR)) / sizeof(WCHAR);
	if (nchars > 127)
		nchars = 127;
	PWSTR p = (PWSTR) ExAllocatePool(PagedPool, (nchars + 1) * sizeof(WCHAR));
	if (!p)
		return STATUS_INSUFFICIENT_RESOURCES;

	memcpy(p, data + 2, nchars * sizeof(WCHAR));
	p[nchars] = 0;

	s->Length = (USHORT) (sizeof(WCHAR) * nchars);
	s->MaximumLength = (USHORT) ((sizeof(WCHAR) * nchars) + sizeof(WCHAR));
	s->Buffer = p;

	return STATUS_SUCCESS;
	}							// GetStringDescriptor

///////////////////////////////////////////////////////////////////////////////

#pragma LOCKEDCODE

VOID OnCancelReadWrite(PDEVICE_OBJECT fdo, PIRP Irp)
	{							// OnCancelReadWrite
	
	IoReleaseCancelSpinLock(Irp->CancelIrql);

	// Attempt to cancel all the subsidiary IRPs for this IRP. The main IRP cannot
	// have progressed in the cancellation process past our own completion routine,

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲一区二区欧美激情| 91国在线观看| 免费欧美日韩国产三级电影| 亚洲欧洲国产日本综合| 欧美一级精品大片| 欧美日韩美少妇| 色成人在线视频| a美女胸又www黄视频久久| 国产精品99久久久久久有的能看| 婷婷国产v国产偷v亚洲高清| 91精品欧美一区二区三区综合在| 欧美伊人精品成人久久综合97| 99久久精品免费看国产免费软件| 成人黄动漫网站免费app| 国产精品91xxx| 精品系列免费在线观看| 极品少妇一区二区三区精品视频| 久久精品国产在热久久| 日本不卡视频一二三区| 日韩精品久久理论片| 天堂久久久久va久久久久| 天堂一区二区在线免费观看| 国产成人精品三级| 麻豆一区二区三| 国产成人精品1024| 国产福利电影一区二区三区| 国产a精品视频| 91香蕉视频污| 欧美日韩视频在线观看一区二区三区 | 成人黄色在线看| 色综合久久九月婷婷色综合| 欧美喷潮久久久xxxxx| 欧美变态口味重另类| 中文字幕不卡一区| 亚洲va欧美va国产va天堂影院| 蜜臀a∨国产成人精品| 国产精品系列在线观看| 欧美日韩一级二级| 久久久久久久综合| 亚洲视频综合在线| 日日夜夜一区二区| 国产精品自产自拍| 欧美天堂一区二区三区| 欧美国产成人精品| 日本最新不卡在线| 国产.欧美.日韩| 91女神在线视频| 国产成人综合网站| 欧美午夜精品一区二区三区| 91精品国产综合久久久久久久| 在线观看国产日韩| 在线不卡的av| 26uuu亚洲| 日韩电影在线一区| 色视频成人在线观看免| 日韩视频一区二区三区在线播放| 亚洲人成精品久久久久久| 欧美久久一二三四区| 国产精品国产三级国产a| 成人免费看的视频| 欧美视频第二页| 国产视频亚洲色图| 日韩成人一区二区| 欧美日韩一区三区| 日韩一区日韩二区| 国产一二三精品| 欧美日韩精品一区二区三区蜜桃| 国产精品免费视频网站| 国产精品99久久久久久似苏梦涵| 欧美大片一区二区| 一区二区三区四区五区视频在线观看| 黄色资源网久久资源365| 在线观看国产日韩| 中文字幕一区二区在线播放| 亚洲高清在线精品| 91在线观看地址| 国产欧美一区二区精品性色超碰 | 在线播放/欧美激情| 久久奇米777| 国产一区二区在线视频| 欧美tickling挠脚心丨vk| 日韩电影在线一区二区| 91麻豆精品国产自产在线| 午夜一区二区三区视频| 欧美三级电影精品| 亚洲观看高清完整版在线观看| 欧美主播一区二区三区美女| 亚洲午夜av在线| 欧美片在线播放| 美国欧美日韩国产在线播放| 精品少妇一区二区三区日产乱码 | 欧美一区二区免费| 蜜臀av一区二区在线免费观看| 91精品在线免费| 激情久久五月天| 国产精品视频一区二区三区不卡| 成人综合激情网| 日韩毛片视频在线看| 欧美亚洲动漫精品| 亚洲va欧美va国产va天堂影院| 3atv在线一区二区三区| 日本欧美一区二区三区乱码| 精品国产三级a在线观看| 精品一区二区在线观看| 亚洲欧洲三级电影| 91精品福利在线| 亚洲地区一二三色| wwww国产精品欧美| 成人永久看片免费视频天堂| 亚洲精品美国一| 精品国产一区二区在线观看| 国产suv精品一区二区6| 亚洲欧洲99久久| 欧美一级高清大全免费观看| 国产成人一级电影| 一区二区三区在线看| 精品国产百合女同互慰| 不卡av免费在线观看| 亚洲国产视频直播| 国产欧美日韩麻豆91| 91天堂素人约啪| 天天做天天摸天天爽国产一区| 精品国产sm最大网站| 91理论电影在线观看| 精品中文字幕一区二区小辣椒| 亚洲国产精品av| 9人人澡人人爽人人精品| 亚洲一区二区精品视频| 国产三级一区二区三区| 欧美精选在线播放| 成人av在线网站| 日本欧美韩国一区三区| 中文字幕欧美日韩一区| 精品精品欲导航| 欧美日韩在线电影| heyzo一本久久综合| 久久精品国产亚洲5555| 亚洲综合视频在线| 久久久久久久久蜜桃| 91麻豆精品国产91久久久久久| 91蝌蚪porny成人天涯| 丰满岳乱妇一区二区三区| 蜜臀久久99精品久久久久久9| 亚洲欧美自拍偷拍色图| 欧美激情自拍偷拍| 国产欧美一区二区精品性色超碰 | 国产在线乱码一区二区三区| 亚洲女性喷水在线观看一区| 欧美国产精品一区二区| 欧美tickling网站挠脚心| 欧美日韩国产经典色站一区二区三区| 粉嫩绯色av一区二区在线观看| 精品一区二区免费| 韩国一区二区三区| 久久精品二区亚洲w码| 天堂va蜜桃一区二区三区| 一区二区三区四区中文字幕| 一区二区三区在线观看国产| 中文字幕人成不卡一区| 中文字幕不卡三区| 中文字幕免费不卡| 国产精品激情偷乱一区二区∴| 国产精品视频第一区| 国产精品久久久久久久久搜平片| 国产婷婷色一区二区三区四区 | 亚洲少妇30p| 国产精品网友自拍| 亚洲欧美色一区| 亚洲成av人片在线观看无码| 日日摸夜夜添夜夜添国产精品| 日韩中文字幕区一区有砖一区 | 午夜久久福利影院| 亚洲电影一级黄| 首页亚洲欧美制服丝腿| 日韩av在线免费观看不卡| 日韩电影在线一区二区三区| 韩国女主播一区| 韩国女主播成人在线观看| 美国十次了思思久久精品导航| 婷婷成人激情在线网| 日本成人中文字幕在线视频| 久久99精品国产麻豆婷婷| 国产高清亚洲一区| 99久免费精品视频在线观看| 在线欧美日韩国产| 日韩欧美久久久| 精品国产乱码91久久久久久网站| 久久综合视频网| 国产精品免费aⅴ片在线观看| 一区二区视频在线| 亚洲婷婷国产精品电影人久久| 视频精品一区二区| 国产真实精品久久二三区| 欧美综合一区二区| 精品国产一区二区在线观看| 国产亚洲一区二区三区四区| 伊人婷婷欧美激情| 黄色成人免费在线| 色噜噜狠狠成人中文综合| 日韩无一区二区|