void setLed (int led, int value) {

    unsigned int ledValue = 0;

    ledValue = GetLEDs();

    ledValue = value ? ledValue | (1 << led) : ledValue & ~(1 << led);

    SetLEDs(ledValue);

}
// 这里面的IO操作是经过序列化的。一个挨着一个,所以绝不会发生重入问题。
//
VOID CY001Drv::DeviceIoControlSerial(IN WDFQUEUE  Queue,
						 IN WDFREQUEST  Request,
						 IN size_t  OutputBufferLength,
						 IN size_t  InputBufferLength,
						 IN ULONG  IoControlCode)
{
	NTSTATUS ntStatus = STATUS_SUCCESS;
	ULONG ulRetLen = 0;
	size_t size;

	void* pBufferInput = NULL;
	void* pBufferOutput = NULL;

	KDBG(DPFLTR_INFO_LEVEL, "[DeviceIoControlSerial]");

	// 取得输入/输出缓冲区
	if(InputBufferLength)WdfRequestRetrieveInputBuffer(Request, InputBufferLength, &pBufferInput, &size);
	if(OutputBufferLength)WdfRequestRetrieveOutputBuffer(Request, OutputBufferLength, &pBufferOutput, &size);

	switch(IoControlCode)
	{
		// 设置数码管
	case IOCTL_USB_SET_DIGITRON:
		{
			CHAR ch = *(CHAR*)pBufferInput;
			KDBG(DPFLTR_INFO_LEVEL, "IOCTL_USB_SET_DIGITRON");
			SetDigitron(ch);
			break;
		}

		// 读数码管
	case IOCTL_USB_GET_DIGITRON:
		{
			UCHAR* pCh = (UCHAR*)pBufferOutput;
			KDBG(DPFLTR_INFO_LEVEL, "IOCTL_USB_GET_DIGITRON");
			GetDigitron(pCh);
			ulRetLen = 1;
			break;
		}

		// 设置LED灯(共4盏)
	case IOCTL_USB_SET_LEDs:
		{
			CHAR ch = *(CHAR*)pBufferInput;
			KDBG(DPFLTR_INFO_LEVEL, "IOCTL_USB_SET_LEDs");
			SetLEDs(ch);
			break;
		}

		// 读取LED灯(共4盏)的当前状态
	case IOCTL_USB_GET_LEDs:
		{
			UCHAR* pCh = (UCHAR*)pBufferOutput;
			KDBG(DPFLTR_INFO_LEVEL, "IOCTL_USB_GET_LEDs");
			GetLEDs(pCh);
			ulRetLen = 1;
			break;
		}

		// 控制命令。
		// 分为:USB协议预定义命令、Vendor自定义命令、特殊类(class)命令。
	case IOCTL_USB_CTL_REQUEST:
		{
			KDBG(DPFLTR_INFO_LEVEL, "IOCTL_USB_CTL_REQUEST");
			ntStatus = UsbControlRequest(Request);
			if(NT_SUCCESS(ntStatus))return;
			break;
		}

		// 开启中断读
	case IOCTL_START_INT_READ:	
		KDBG(DPFLTR_INFO_LEVEL, "IOCTL_START_INT_READ");	
		ntStatus = InterruptReadStart();
		break;

		// 控制程序发送读请求。它们是被阻塞的,放至Queue中排队,所以不要即可完成他们。
	case IOCTL_INT_READ_KEYs:
		KDBG(DPFLTR_INFO_LEVEL, "IOCTL_INT_READ_KEYs");
		ntStatus = WdfRequestForwardToIoQueue(Request, m_hInterruptManualQueue);

		if(NT_SUCCESS(ntStatus))
			return;// 成功,直接返回;异步完成。
		break;

		// 终止中断读
	case IOCTL_STOP_INT_READ:
		KDBG(DPFLTR_INFO_LEVEL, "IOCTL_STOP_INT_READ");
		InterruptReadStop();
		ntStatus = STATUS_SUCCESS;
		break;

	default:
		// 不应该到这里。
		// 对于不能识别的IO控制命令,这里做错误处理。
		KDBG(DPFLTR_INFO_LEVEL, "Unknown Request: %08x(%d)!!!", IoControlCode, IoControlCode);
		ntStatus = STATUS_INVALID_PARAMETER;
		break;
	}

	WdfRequestCompleteWithInformation(Request, ntStatus, ulRetLen);
	return;
}