NTSTATUS kmdf1394_SubmitIrpSynch ( IN WDFIOTARGET IoTarget, IN WDFREQUEST Request, IN PIRB Irb) /*++ Routine Description: Synchronous Irp submission routine Arguments: IoTarget - pointer to the IoTarget object. Request - the WDF Request packet to use Irb - 1394 I/O Request Block to submit Return Value: NTSTATUS value --*/ { NTSTATUS ntStatus = STATUS_SUCCESS; WDF_REQUEST_SEND_OPTIONS option; WDF_MEMORY_DESCRIPTOR descriptor; UNREFERENCED_PARAMETER (Request); ENTER ("kmdf1394_SubmitIrpSynch"); ASSERT (KeGetCurrentIrql() < DISPATCH_LEVEL); ASSERT (Irb); WDF_REQUEST_SEND_OPTIONS_INIT (&option, WDF_REQUEST_SEND_OPTION_SYNCHRONOUS); WDF_MEMORY_DESCRIPTOR_INIT_BUFFER (&descriptor, Irb, sizeof (IRB)); ntStatus = WdfIoTargetSendInternalIoctlOthersSynchronously ( IoTarget, NULL, IOCTL_1394_CLASS, &descriptor, NULL, NULL, &option, NULL); if (!NT_SUCCESS(ntStatus)) { TRACE(TL_ERROR, ("WdfIoTargetSendInternalIoctlSynchronously " "Failed with status %x\n",ntStatus)); } EXIT ("kmdf1394_SubmitIrpSynch", ntStatus); return ntStatus; } //kmdf1394_SubmitIrpSynch
VOID Rio500_EvtIoDeviceControl( _In_ WDFQUEUE Queue, _In_ WDFREQUEST Request, _In_ size_t OutputBufferLength, _In_ size_t InputBufferLength, _In_ ULONG IoControlCode ) /*++ Routine Description: This event is called when the framework receives IRP_MJ_DEVICE_CONTROL requests from the system. Arguments: Queue - Handle to the framework queue object that is associated with the I/O request. Request - Handle to a framework request object. OutputBufferLength - length of the request's output buffer, if an output buffer is available. InputBufferLength - length of the request's input buffer, if an input buffer is available. IoControlCode - the driver-defined or system-defined I/O control code (IOCTL) that is associated with the request. Return Value: VOID --*/ { WDFDEVICE device; PVOID ioBuffer; PRIO_IOCTL_BLOCK ioBufferRio; size_t bufLength; NTSTATUS status; PDEVICE_CONTEXT pDevContext; ULONG length = 0; URB urb; PMDL pMdl = NULL; WDF_MEMORY_DESCRIPTOR memoryDesc; #ifdef _WIN64 BOOLEAN isWowRequest = FALSE; #endif // _WIN64 UNREFERENCED_PARAMETER(OutputBufferLength); UNREFERENCED_PARAMETER(InputBufferLength); Rio500_DbgPrint(3, ("Entered Rio500_DispatchDevCtrl\n")); PAGED_CODE(); // // initialize variables // device = WdfIoQueueGetDevice(Queue); pDevContext = GetDeviceContext(device); switch(IoControlCode) { case IOCTL_RIO500_RESET_PIPE: status = ResetPipe(pDevContext->ReadPipe); if (NT_SUCCESS(status)) { status = ResetPipe(pDevContext->WritePipe); } break; case IOCTL_RIO500_GET_CONFIG_DESCRIPTOR: if (pDevContext->UsbConfigurationDescriptor) { length = pDevContext->UsbConfigurationDescriptor->wTotalLength; status = WdfRequestRetrieveOutputBuffer(Request, length, &ioBuffer, &bufLength); if (!NT_SUCCESS(status)) { Rio500_DbgPrint(1, ("WdfRequestRetrieveInputBuffer failed\n")); break; } RtlCopyMemory(ioBuffer, pDevContext->UsbConfigurationDescriptor, length); status = STATUS_SUCCESS; } else { status = STATUS_INVALID_DEVICE_STATE; } break; case IOCTL_RIO500_RESET_DEVICE: status = ResetDevice(device); break; case IOCTL_RIO500_RIO_COMMAND: #ifdef _WIN64 if (IoIs32bitProcess(NULL)) { bufLength = sizeof(RIO_IOCTL_BLOCK) - sizeof(DWORD32); isWowRequest = TRUE; } else #endif // _WIN64 { bufLength = sizeof(RIO_IOCTL_BLOCK); } status = WdfRequestRetrieveInputBuffer( Request, bufLength, &ioBufferRio, NULL ); if (NT_SUCCESS(status)) { #ifdef _WIN64 if (isWowRequest) { ioBuffer = (PVOID)ioBufferRio->MsgData.DataWow; } else #endif // _WIN64 { ioBuffer = ioBufferRio->MsgData.Data; } if (ioBufferRio->MsgLength != 0 && ioBuffer != NULL) { pMdl = IoAllocateMdl( ioBuffer, ioBufferRio->MsgLength, FALSE, FALSE, NULL ); MmProbeAndLockPages(pMdl, (KPROCESSOR_MODE)KernelMode, IoModifyAccess); } memset(&urb, 0, sizeof(urb)); urb.UrbControlVendorClassRequest.Hdr.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST); urb.UrbControlVendorClassRequest.Hdr.Function = URB_FUNCTION_VENDOR_DEVICE; urb.UrbControlVendorClassRequest.TransferBuffer = NULL; urb.UrbControlVendorClassRequest.RequestTypeReservedBits = 0x00; urb.UrbControlVendorClassRequest.TransferBufferLength = ioBufferRio->MsgLength; urb.UrbControlVendorClassRequest.TransferBufferMDL = pMdl; urb.UrbControlVendorClassRequest.Request = ioBufferRio->RequestCode; urb.UrbControlVendorClassRequest.Value = ioBufferRio->MsgValue; urb.UrbControlVendorClassRequest.Index = ioBufferRio->MsgIndex; urb.UrbControlVendorClassRequest.TransferFlags = USBD_SHORT_TRANSFER_OK; if (ioBufferRio->RequestType & 0x80) { urb.UrbControlVendorClassRequest.TransferFlags |= USBD_TRANSFER_DIRECTION_IN; } urb.UrbControlVendorClassRequest.UrbLink = NULL; WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memoryDesc, &urb, sizeof(urb)); status = WdfIoTargetSendInternalIoctlOthersSynchronously( WdfDeviceGetIoTarget(device), Request, IOCTL_INTERNAL_USB_SUBMIT_URB, &memoryDesc, NULL, NULL, NULL, NULL ); if (pMdl != NULL) { MmUnlockPages(pMdl); IoFreeMdl(pMdl); } } break; default: status = STATUS_INVALID_DEVICE_REQUEST; break; } WdfRequestCompleteWithInformation(Request, status, length); Rio500_DbgPrint(3, ("Exit Rio500_DispatchDevCtrl\n")); }
NTSTATUS FORCEINLINE BthEchoSharedSendBrbSynchronously( _In_ WDFIOTARGET IoTarget, _In_ WDFREQUEST Request, _In_ PBRB Brb, _In_ ULONG BrbSize ) /*++ Routine Description: This routine formats a request with brb and sends it synchronously Arguments: IoTarget - Target to send the brb to Request - request object to be formatted with brb Brb - Brb to be sent BrbSize - size of the Brb data structure Return Value: NTSTATUS Status code. Notes: This routine does calls WdfRequestReuse on the Request passed in. Caller need not do so before passing in the request. This routine does not complete the request in case of failure. Caller must complete the request in case of failure. --*/ { NTSTATUS status; WDF_REQUEST_REUSE_PARAMS reuseParams; WDF_MEMORY_DESCRIPTOR OtherArg1Desc; WDF_REQUEST_REUSE_PARAMS_INIT( &reuseParams, WDF_REQUEST_REUSE_NO_FLAGS, STATUS_NOT_SUPPORTED ); status = WdfRequestReuse(Request, &reuseParams); if (!NT_SUCCESS(status)) { goto exit; } WDF_MEMORY_DESCRIPTOR_INIT_BUFFER( &OtherArg1Desc, Brb, BrbSize ); status = WdfIoTargetSendInternalIoctlOthersSynchronously( IoTarget, Request, IOCTL_INTERNAL_BTH_SUBMIT_BRB, &OtherArg1Desc, NULL, //OtherArg2 NULL, //OtherArg4 NULL, //RequestOptions NULL //BytesReturned ); exit: return status; }