public override EusbPdu ParsePdu(byte[] data)
        {
            EusbPdu pdu;

            switch (GetPduType(data))
            {
                case EusbType.RIM_EXCHANGE_CAPABILITY_REQUEST:
                    pdu = new EusbRimExchangeCapRequestPdu();
                    break;
                case EusbType.CHANNEL_CREATED:
                    pdu = new EusbChannelCreatedPdu(true);
                    break;
                case EusbType.REGISTER_REQUEST_CALLBACK:
                    pdu = new EusbRegisterRequestCallbackPdu();
                    break;
                case EusbType.QUERY_DEVICE_TEXT:
                    pdu = new EusbQueryDeviceTextRequestPdu();
                    break;
                case EusbType.IO_CONTROL:
                    pdu = new EusbIoControlPdu();
                    break;
                case EusbType.INTERNAL_IO_CONTROL:
                    pdu = new EusbInternalIoControlPdu();
                    break;
                case EusbType.TRANSFER_IN_REQUEST:
                    pdu = new EusbTransferInRequestPdu();
                    break;
                case EusbType.TRANSFER_OUT_REQUEST:
                    pdu = new EusbTransferOutRequestPdu();
                    break;
                case EusbType.CANCEL_REQUEST:
                    pdu = new EusbCancelRequestPdu();
                    break;
                case EusbType.RETRACT_DEVICE:
                    pdu = new EusbRetractDevicePdu();
                    break;
                default:
                    return base.ParsePdu(data);
            }

            if (!PduMarshaler.Unmarshal(data, pdu))
            {
                pdu = new EusbUnknownPdu();
                PduMarshaler.Unmarshal(data, pdu);
            }
            return pdu;
        }
        /// <summary>
        /// Registers a request completion interface on the client for a specific device.
        /// </summary>
        /// <param name="device">The information of the device which is being operated.</param>
        /// <param name="numRequestCompletion">If this field is set to 0x00000001 or greater, then the RequestCompletion field
        /// is also present. If this field is set to 0x0000000, the RequestCompletion field is not present.</param>
        /// <param name="requestCompletion">A unique InterfaceID to be used by all Request Completion messages defined in the
        /// Request Completion Interface.</param>
        public void RegisterCallback(EusbDeviceContext device, uint numRequestCompletion, uint requestCompletion)
        {
            Site.Log.Add(
                LogEntryKind.Debug,
                "Sending REGISTER_REQUEST_CALLBACK. Device: {0}, Num request Completion {1}, Request completion {2}.",
                device,
                numRequestCompletion,
                requestCompletion
                );

            EusbRegisterRequestCallbackPdu requestPdu = new EusbRegisterRequestCallbackPdu(
                device.UsbDeviceInterfaceId,
                numRequestCompletion,
                requestCompletion
                );
            SendPdu(requestPdu, device.VirtualChannel);

            // Record the interface ID for parsing Completion UDPs.
            rdpeusbServer.RequestCompletionInterfaceId = requestCompletion;
        }