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

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? readwrite.cpp

?? 一本在講述USB驅(qū)動程式的書 及其范例原碼
?? CPP
?? 第 1 頁 / 共 2 頁
字號:
	// so it's safe to use DriverContext as a pointer to the context structure.

	PRWCONTEXT ctx = (PRWCONTEXT) Irp->Tail.Overlay.DriverContext[0];
	for (ULONG i = 0; i < ctx->numirps; ++i)
		IoCancelIrp(ctx->sub[i].irp);

	// Release our claim on the context structure and subsidiary IRP pointers. If
	// the completion routine has already run, it's up to us to finish the
	// completion process for this IRP.

	PDEVICE_EXTENSION pdx = ctx->pdx;

	if (DestroyContextStructure(ctx))
		{						// we're last
		CompleteRequest(Irp, STATUS_CANCELLED, 0);
		IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
		}						// we're last
	}							// OnCancelReadWrite

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

#pragma LOCKEDCODE

NTSTATUS OnReadWriteComplete(PDEVICE_OBJECT fdo, PIRP Irp, PRWCONTEXT ctx)
	{							// OnReadWriteComplete
	ASSERT(ctx->mainirp == Irp);
	PDEVICE_EXTENSION pdx = ctx->pdx;

	if (NT_SUCCESS(Irp->IoStatus.Status))
		Irp->IoStatus.Information = ctx->numxfer;

	// Release the context structure. If the cancel routine has run (or can't ever
	// run), we'll return a normal status. If the cancel routine is working now as
	// well, however, return STATUS_MORE_PROCESSING_REQUIRED to stop the completion
	// process for the time being.

	if (DestroyContextStructure(ctx))
		{						// we're last
		IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
		return STATUS_SUCCESS;
		}						// we're last
	else
		return STATUS_MORE_PROCESSING_REQUIRED;
	}							// OnReadWriteComplete

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

#pragma LOCKEDCODE

NTSTATUS OnStageComplete(PDEVICE_OBJECT fdo, PIRP Irp, PRWCONTEXT ctx)
	{							// OnStageComplete
	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
	PIRP mainirp = ctx->mainirp;
	PURB urb = (PURB) stack->Parameters.Others.Argument1;

	NTSTATUS status = Irp->IoStatus.Status;
	if (NT_SUCCESS(status))
		{
		InterlockedExchangeAdd((PLONG) &ctx->numxfer, (LONG) urb->UrbIsochronousTransfer.TransferBufferLength);
		}
	else
		{
		KdPrint((DRIVERNAME " - read failed with status %X (USBD status %X)\n", status, URB_STATUS(urb)));
		ctx->status = status;
		}

#if DBG
	KdPrint((DRIVERNAME " - iso transfer started in frame %8.8lX, %d packets had errors\n",
		urb->UrbIsochronousTransfer.StartFrame, urb->UrbIsochronousTransfer.ErrorCount));
	for (ULONG i = 0; i < urb->UrbIsochronousTransfer.NumberOfPackets; ++i)
		{						// for each packet
		PUSBD_ISO_PACKET_DESCRIPTOR pipd = &urb->UrbIsochronousTransfer.IsoPacket[i];
		KdPrint((DRIVERNAME " - Packet %d, %d bytes, ending status %8.8lX\n", i, pipd->Length, pipd->Status));
		}						// for each packet
#endif

	ExFreePool(urb);
	IoFreeMdl((PMDL) stack->Parameters.Others.Argument2);

	if (InterlockedDecrement(&ctx->numpending) == 0)
		{						// complete main IRP

		// Clear the main IRP's cancel pointer in preparation for completing it. If
		// the cancel routine has already run (or is now running), it called/will call
		// DestroyContextStructure. If IoSetCancelRoutine returns a non-NULL value,
		// however, it means that the cancel routine can never be called. We should
		// therefore use up its reference to the context structure so the main
		// completion routine can delete it.

		if (IoSetCancelRoutine(mainirp, NULL))
			InterlockedDecrement(&ctx->refcnt);	// cancel routine can no longer run
		mainirp->IoStatus.Status = ctx->status;
		IoCompleteRequest(mainirp, IO_NO_INCREMENT);
		}						// complete main IRP

	// Return STATUS_MORE_PROCESSING_REQUIRED to prevent IoCompleteRequest from
	// queuing an APC to release the memory for this subsidiary IRP. A comment
	// in OnReadWriteComplete explains what's going on here

	return STATUS_MORE_PROCESSING_REQUIRED;
	}							// OnStageComplete

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

#pragma PAGEDCODE

NTSTATUS SelectAlternateInterface(PDEVICE_OBJECT fdo)
	{							// SelectAlternateInterface
	NTSTATUS status;
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

	// Locate the descriptor for the alternate interface we want

	PUSB_INTERFACE_DESCRIPTOR pid = USBD_ParseConfigurationDescriptorEx(pdx->pcd, pdx->pcd,
		0, 1, -1, -1, -1);

	if (!pid)
		{
		KdPrint((DRIVERNAME " - No alternatate interface defined\n"));
		return STATUS_DEVICE_CONFIGURATION_ERROR;
		}

	// Verify the characteristics of the interface

	PUSB_CONFIGURATION_DESCRIPTOR pcd = pdx->pcd;
	PUSB_ENDPOINT_DESCRIPTOR ped = (PUSB_ENDPOINT_DESCRIPTOR) pid;
	ped = (PUSB_ENDPOINT_DESCRIPTOR) USBD_ParseDescriptors(pcd, pcd->wTotalLength, ped, USB_ENDPOINT_DESCRIPTOR_TYPE);

	if (!ped || ped->bmAttributes != USB_ENDPOINT_TYPE_ISOCHRONOUS || ped->wMaxPacketSize < 16)
		{
		KdPrint((DRIVERNAME " - Alternate interface has wrong attributes\n"));
		return STATUS_DEVICE_CONFIGURATION_ERROR;
		}
	
	// Allocate an URB big enough to describe the alternate interface. First determine
	// how many pipes will be opened

	ULONG size = GET_SELECT_INTERFACE_REQUEST_SIZE(pid->bNumEndpoints);
	PURB urb = (PURB) ExAllocatePool(NonPagedPool, size);
	if (!urb)
		{
		KdPrint((DRIVERNAME " - can't allocate %d bytes for Select Interface URB\n", size));
		return STATUS_INSUFFICIENT_RESOURCES;
		}
	RtlZeroMemory(urb, size);

	// Build and submit the URB

	UsbBuildSelectInterfaceRequest(urb, (USHORT) size, pdx->hconfig, 0, 1);
	urb->UrbSelectInterface.Interface.Length = GET_USBD_INTERFACE_SIZE(pid->bNumEndpoints);
	urb->UrbSelectInterface.Interface.Pipes[0].MaximumTransferSize = PAGE_SIZE;

	status = SendAwaitUrb(fdo, urb);
	if (NT_SUCCESS(status))
		{
		pdx->hinpipe = urb->UrbSelectInterface.Interface.Pipes[0].PipeHandle;
		MSGUSBSTRING(fdo, DRIVERNAME " - Selecting interface named %ws\n", pid->iInterface);
		status = STATUS_SUCCESS;
		}
	else
		KdPrint((DRIVERNAME " - Error %X trying to select alternate interface\n", status));


	ExFreePool(urb);
	return status;
	}							// SelectAlternateInterface

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

#pragma PAGEDCODE

NTSTATUS SelectDefaultInterface(PDEVICE_OBJECT fdo)
	{							// SelectDefaultInterface
	NTSTATUS status;
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
	
	// Allocate an URB big enough to describe the default interface. First determine
	// how many pipes will be opened

	PUSB_INTERFACE_DESCRIPTOR pid = USBD_ParseConfigurationDescriptorEx(pdx->pcd, pdx->pcd,
		0, 0, -1, -1, -1);
	ASSERT(pid);
	ULONG size = GET_SELECT_INTERFACE_REQUEST_SIZE(pid->bNumEndpoints);
	PURB urb = (PURB) ExAllocatePool(NonPagedPool, size);
	if (!urb)
		{
		KdPrint((DRIVERNAME " - can't allocate %d bytes for Select Interface URB\n", size));
		return STATUS_INSUFFICIENT_RESOURCES;
		}
	RtlZeroMemory(urb, size);

	// Build and submit the URB

	UsbBuildSelectInterfaceRequest(urb, (USHORT) size, pdx->hconfig, 0, 0);
	urb->UrbSelectInterface.Interface.Length = GET_USBD_INTERFACE_SIZE(pid->bNumEndpoints);
	status = SendAwaitUrb(fdo, urb);
	if (NT_SUCCESS(status))
		{
		pdx->hinpipe = NULL;
		MSGUSBSTRING(fdo, DRIVERNAME " - Selecting interface named %ws\n", pid->iInterface);
		status = STATUS_SUCCESS;
		}
	else
		KdPrint((DRIVERNAME " - Error %X trying to select default interface\n", status));


	ExFreePool(urb);
	return status;
	}							// SelectDefaultInterface

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

#pragma PAGEDCODE

NTSTATUS SendAwaitUrb(PDEVICE_OBJECT fdo, PURB urb)
	{							// SendAwaitUrb
	PAGED_CODE();
	ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

	KEVENT event;
	KeInitializeEvent(&event, NotificationEvent, FALSE);

	IO_STATUS_BLOCK iostatus;
	PIRP Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB,
		pdx->LowerDeviceObject, NULL, 0, NULL, 0, TRUE, &event, &iostatus);

	if (!Irp)
		{
		KdPrint((DRIVERNAME " - Unable to allocate IRP for sending URB\n"));
		return STATUS_INSUFFICIENT_RESOURCES;
		}

	PIO_STACK_LOCATION stack = IoGetNextIrpStackLocation(Irp);
	stack->Parameters.Others.Argument1 = (PVOID) urb;
	NTSTATUS status = IoCallDriver(pdx->LowerDeviceObject, Irp);
	if (status == STATUS_PENDING)
		{
		KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
		status = iostatus.Status;
		}
	return status;
	}							// SendAwaitUrb

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

#pragma PAGEDCODE

NTSTATUS StartDevice(PDEVICE_OBJECT fdo, PCM_PARTIAL_RESOURCE_LIST raw, PCM_PARTIAL_RESOURCE_LIST translated)
	{							// StartDevice
	PAGED_CODE();
	NTSTATUS status;
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

	URB urb;					// URB for use in this subroutine

	// Read our device descriptor. The only real purpose to this would be to find out how many
	// configurations there are so we can read their descriptors. In this simplest of examples,
	// there's only one configuration.

	UsbBuildGetDescriptorRequest(&urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_DEVICE_DESCRIPTOR_TYPE,
		0, 0, &pdx->dd, NULL, sizeof(pdx->dd), NULL);
	status = SendAwaitUrb(fdo, &urb);
	if (!NT_SUCCESS(status))
		{
		KdPrint((DRIVERNAME " - Error %X trying to read device descriptor\n", status));
		return status;
		}

	MSGUSBSTRING(fdo, DRIVERNAME " - Configuring device from %ws\n", pdx->dd.iManufacturer);
	MSGUSBSTRING(fdo, DRIVERNAME " - Product is %ws\n", pdx->dd.iProduct);
	MSGUSBSTRING(fdo, DRIVERNAME " - Serial number is %ws\n", pdx->dd.iSerialNumber);

	// Read the descriptor of the first configuration. This requires two steps. The first step
	// reads the fixed-size configuration descriptor alone. The second step reads the
	// configuration descriptor plus all imbedded interface and endpoint descriptors.

	USB_CONFIGURATION_DESCRIPTOR tcd;
	UsbBuildGetDescriptorRequest(&urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_CONFIGURATION_DESCRIPTOR_TYPE,
		0, 0, &tcd, NULL, sizeof(tcd), NULL);
	status = SendAwaitUrb(fdo, &urb);
	if (!NT_SUCCESS(status))
		{
		KdPrint((DRIVERNAME " - Error %X trying to read configuration descriptor 1\n", status));
		return status;
		}

	ULONG size = tcd.wTotalLength;
	PUSB_CONFIGURATION_DESCRIPTOR pcd = (PUSB_CONFIGURATION_DESCRIPTOR) ExAllocatePool(NonPagedPool, size);
	if (!pcd)
		{
		KdPrint((DRIVERNAME " - Unable to allocate %X bytes for configuration descriptor\n", size));
		return STATUS_INSUFFICIENT_RESOURCES;
		}

	__try
		{
		UsbBuildGetDescriptorRequest(&urb, sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST), USB_CONFIGURATION_DESCRIPTOR_TYPE,
			0, 0, pcd, NULL, size, NULL);
		status = SendAwaitUrb(fdo, &urb);
		if (!NT_SUCCESS(status))
			{
			KdPrint((DRIVERNAME " - Error %X trying to read configuration descriptor 1\n", status));
			return status;
			}
                                   
		MSGUSBSTRING(fdo, DRIVERNAME " - Selecting configuration named %ws\n", pcd->iConfiguration);

		// Locate the descriptor for the one and only interface we expect to find

		PUSB_INTERFACE_DESCRIPTOR pid = USBD_ParseConfigurationDescriptorEx(pcd, pcd,
			-1, -1, -1, -1, -1);
		ASSERT(pid);
                                   
		MSGUSBSTRING(fdo, DRIVERNAME " - Selecting interface named %ws\n", pid->iInterface);

		// Create a URB to use in selecting a configuration.

		USBD_INTERFACE_LIST_ENTRY interfaces[2] = {
			{pid, NULL},
			{NULL, NULL},		// fence to terminate the array
			};

		PURB selurb = USBD_CreateConfigurationRequestEx(pcd, interfaces);
		if (!selurb)
			{
			KdPrint((DRIVERNAME " - Unable to create configuration request\n"));
			return STATUS_INSUFFICIENT_RESOURCES;
			}

		__try
			{

			// Verify that the interface describes exactly the endpoints we expect

			if (pid->bNumEndpoints != 0)
				{
				KdPrint((DRIVERNAME " - %d is the wrong number of endpoints\n", pid->bNumEndpoints));
				return STATUS_DEVICE_CONFIGURATION_ERROR;
				}

			PUSBD_INTERFACE_INFORMATION pii = interfaces[0].Interface;
			ASSERT(pii->NumberOfPipes == pid->bNumEndpoints);

			// Submit the set-configuration request

			status = SendAwaitUrb(fdo, selurb);
			if (!NT_SUCCESS(status))
				{
				KdPrint((DRIVERNAME " - Error %X trying to select configuration\n", status));
				return status;
				}

			// Save the configuration and pipe handles

			pdx->hconfig = selurb->UrbSelectConfiguration.ConfigurationHandle;
			pdx->hinpipe = NULL;

			// Transfer ownership of the configuration descriptor to the device extension
			
			pdx->pcd = pcd;
			pcd = NULL;
			}
		__finally
			{
			ExFreePool(selurb);
			}

		}
	__finally
		{
		if (pcd)
			ExFreePool(pcd);
		}

	return STATUS_SUCCESS;
	}							// StartDevice

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

#pragma PAGEDCODE

VOID StopDevice(IN PDEVICE_OBJECT fdo, BOOLEAN oktouch /* = FALSE */)
	{							// StopDevice
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

	// If it's okay to touch our hardware (i.e., we're processing an IRP_MN_STOP_DEVICE),
	// deconfigure the device.
	
	if (oktouch)
		{						// deconfigure device
		URB urb;
		UsbBuildSelectConfigurationRequest(&urb, sizeof(_URB_SELECT_CONFIGURATION), NULL);
		NTSTATUS status = SendAwaitUrb(fdo, &urb);
		if (!NT_SUCCESS(status))
			KdPrint((DRIVERNAME " - Error %X trying to deconfigure device\n", status));
		}						// deconfigure device

	if (pdx->pcd)
		ExFreePool(pdx->pcd);
	pdx->pcd = NULL;
	}							// StopDevice

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
成人国产精品免费观看| 久久精品国产久精国产爱| 91小视频免费观看| 亚洲已满18点击进入久久| 欧美日韩你懂得| 蜜臀av一级做a爰片久久| 日韩一区二区高清| 国产精品亚洲专一区二区三区| 国产精品无码永久免费888| av电影在线观看完整版一区二区| 亚洲少妇屁股交4| 91精品国产综合久久久久| 国内精品不卡在线| 亚洲日本护士毛茸茸| 国产精品你懂的在线| 一本久久a久久免费精品不卡| 亚洲高清免费一级二级三级| 久久毛片高清国产| 欧美亚洲另类激情小说| 国产成人免费视频网站| 国产精品久久久久国产精品日日| 欧美天堂亚洲电影院在线播放| 久久精品99国产精品| 综合色天天鬼久久鬼色| 精品日韩在线一区| 欧美亚一区二区| 国产精品一二三区在线| 日本大胆欧美人术艺术动态| 亚洲婷婷综合色高清在线| 欧美成人精精品一区二区频| 色综合天天综合在线视频| 国产精品99久久久久| 亚洲福利视频三区| 中文字幕一区二区三区在线不卡 | 国产一区三区三区| 国产在线乱码一区二区三区| 亚洲欧美在线另类| 欧美激情一二三区| 欧美精品一区二区蜜臀亚洲| 欧美一区在线视频| 欧美日韩精品电影| 欧美日韩三级视频| 欧美性生活影院| 精品少妇一区二区三区| 欧美伊人久久大香线蕉综合69| 成人永久看片免费视频天堂| 久久国产剧场电影| 日韩国产欧美一区二区三区| 亚洲二区视频在线| 亚洲成人av电影| 亚洲成av人片在线观看无码| 亚洲最大成人综合| 一区二区激情小说| 一区二区三区日韩| 蜜臀va亚洲va欧美va天堂| 亚洲一区二区在线观看视频 | 亚洲电影激情视频网站| 亚洲午夜久久久久久久久久久| 亚洲二区在线视频| 免费人成精品欧美精品| 另类欧美日韩国产在线| 国产精品一区二区在线看| 国产一区二区伦理| 成人听书哪个软件好| 一本大道av一区二区在线播放| 在线观看亚洲一区| 91精品一区二区三区在线观看| 精品国产3级a| 国产精品不卡一区| 日韩激情av在线| 日韩高清一级片| 国产成人午夜视频| 不卡一区二区在线| 日韩色在线观看| 日韩一区二区三区四区五区六区| 欧美日精品一区视频| 日韩欧美久久一区| 国产日韩精品一区二区三区| 国产精品久久久久永久免费观看| 国产精品久久久久久久久免费相片| 一区二区免费视频| 久久国产综合精品| 成人18视频在线播放| 在线视频观看一区| 欧美日韩在线三区| 中文字幕欧美国产| 亚洲精品欧美在线| 日本 国产 欧美色综合| 成人激情综合网站| 3d动漫精品啪啪1区2区免费| 欧美mv日韩mv国产| 亚洲午夜日本在线观看| 国产激情91久久精品导航| 91黄色激情网站| 日本一区二区三区电影| 奇米一区二区三区av| 9l国产精品久久久久麻豆| 欧美一区二区三区在线观看 | 精品一区二区三区免费播放| 92国产精品观看| 欧美韩国日本不卡| 亚洲黄色性网站| 精品美女被调教视频大全网站| 69堂精品视频| 亚洲丝袜美腿综合| 国产成人在线视频网址| 日韩欧美的一区| 午夜精品免费在线观看| 国产福利精品导航| 精品动漫一区二区三区在线观看| 一区二区三区四区蜜桃| youjizz国产精品| 欧美精品国产精品| 亚洲精品国产成人久久av盗摄| 国产成人精品免费| 国产亚洲一本大道中文在线| 水野朝阳av一区二区三区| 色婷婷久久综合| 亚洲精品少妇30p| 91小视频在线观看| 亚洲精品日韩专区silk| 欧美午夜在线观看| 亚洲不卡av一区二区三区| 在线免费观看视频一区| 亚洲欧美一区二区三区国产精品| 美女精品自拍一二三四| 欧美成人vr18sexvr| 激情五月激情综合网| 久久久久久黄色| 色综合夜色一区| 婷婷中文字幕综合| 日韩片之四级片| 国产成人在线视频免费播放| 国产婷婷色一区二区三区在线| 色菇凉天天综合网| 亚洲一区二区三区自拍| 91欧美一区二区| 五月婷婷久久综合| 久久久久久久久伊人| 99视频热这里只有精品免费| 亚洲不卡一区二区三区| 91色婷婷久久久久合中文| 亚洲国产精品影院| 久久一区二区三区四区| 色婷婷国产精品综合在线观看| 一区二区三区在线观看国产| 日韩一区二区三区观看| 99久久99久久综合| 老司机精品视频在线| 亚洲精品免费在线观看| 欧美一区二区大片| 成人激情免费网站| 美女尤物国产一区| 最新国产の精品合集bt伙计| 欧美一级一级性生活免费录像| 成人在线一区二区三区| 免费高清成人在线| 一区二区三区.www| 欧美高清在线精品一区| 制服丝袜国产精品| 91小视频免费看| 成人小视频免费观看| 亚洲成人777| 亚洲综合丁香婷婷六月香| 精品99一区二区三区| 7777精品伊人久久久大香线蕉最新版| 国产精品亚洲第一区在线暖暖韩国| 亚洲一区在线视频| 久久综合九色综合97_久久久| 欧美在线免费视屏| 97se亚洲国产综合在线| 蜜桃视频在线观看一区| 午夜视频在线观看一区二区三区| 亚洲欧美在线观看| 国产精品美女久久久久久2018 | 色呦呦一区二区三区| 国产激情一区二区三区四区 | 国产精品对白交换视频| 久久久亚洲国产美女国产盗摄 | 亚洲国产综合在线| 亚洲精品中文在线观看| 中文字幕一区二区三区不卡在线 | 97久久久精品综合88久久| 日韩av电影免费观看高清完整版| 一个色综合网站| 一区二区三区电影在线播| 尤物在线观看一区| 亚洲天堂av老司机| 夜夜精品视频一区二区| 亚洲成人一二三| 免费成人在线观看视频| 国产一区二区三区在线观看免费 | 一区二区三区欧美日| 亚洲精品视频在线看| 亚洲色图视频免费播放| 亚洲小少妇裸体bbw| 亚洲国产cao| 国产精品中文有码| 91色porny| 欧美一级理论片|