📄 ul_wdusb.c
字号:
/******************************************************************* uLan Communication - uL_DRV - multiplatform uLan driver ul_wdusb.c - WDM support for USB devices (C) Copyright 1996-2004 by Pavel Pisa - project originator http://cmp.felk.cvut.cz/~pisa (C) Copyright 1996-2004 PiKRON Ltd. http://www.pikron.com (C) Copyright 2002-2004 Petr Smolik The uLan driver project can be used and distributed in compliance with any of next licenses - GPL - GNU Public License See file COPYING for details. - LGPL - Lesser GNU Public License - MPL - Mozilla Public License - and other licenses added by project originator Code can be modified and re-distributed under any combination of the above listed licenses. If contributor does not agree with some of the licenses, he/she can delete appropriate line. WARNING: if you delete all lines, you are not allowed to distribute code or sources in any form. *******************************************************************/#ifndef __WINDOWS_USB_H #include "ul_wdusb.h"#endif/** * usb_create_dev - * @dev: pointer to the usb device * @fdo: * * Return Value: NTSTATUS */ NTSTATUSusb_create_dev(IN usb_device **pdev,IN PDEVICE_OBJECT fdo) { usb_device *dev; dev=MALLOC(sizeof(usb_device)); if(!dev) return STATUS_INSUFFICIENT_RESOURCES; RtlZeroBytes(dev,sizeof(usb_device)); dev->fdo=fdo; *pdev=dev; return 0;}/** * usb_destroy_dev - delete usb device resources * @dev: pointer to the usb device * * Return Value: NTSTATUS */ NTSTATUSusb_destroy_dev(IN usb_device *dev) { usb_reset_configuration(dev);#if DBG_USB uLan_DbgPrint("ulan: device unconfigured\n");#endif /* deviceDescriptor */ if (dev->descriptor) { FREE(dev->descriptor);#if DBG_USB uLan_DbgPrint("ulan: deviceDescriptor freed\n");#endif } dev->descriptor=NULL; /* configurationDescriptor */ if (dev->rawdescriptors) { FREE(dev->rawdescriptors);#if DBG_USB uLan_DbgPrint("ulan: rawdescriptor freed\n");#endif } dev->rawdescriptors=NULL; FREE(dev); return 0;}/** * ul_CallUSBD - Passes a URB to the USBD class driver * @dev: pointer to the usb device * @usb: pointer to an already-formatted Urb request block * @timeout: not used at this moment * * Return Value: NTSTATUS */ NTSTATUS _usb_submit_urb( IN usb_device *dev, IN PURB urb,IN PLARGE_INTEGER timeout, IN _usb_completation_rtn rtn, IN PVOID rtn_param,OUT PIRP *pirp) { NTSTATUS ntStatus, status = STATUS_SUCCESS; PIRP irp; KEVENT event; IO_STATUS_BLOCK ioStatus; PIO_STACK_LOCATION nextStack; #if DBG_USB uLan_DbgPrint("ulan: _usb_submit_urb : enter\n");#endif if (!rtn) KeInitializeEvent( &event, NotificationEvent, FALSE); irp = IoBuildDeviceIoControlRequest( IOCTL_INTERNAL_USB_SUBMIT_URB, dev->fdo, NULL, 0, NULL, 0, TRUE, (!rtn) ? &event : NULL, &ioStatus); nextStack = IoGetNextIrpStackLocation( irp); nextStack->Parameters.Others.Argument1 = urb; if (rtn) { IoSetCompletionRoutine( irp, rtn, rtn_param, TRUE, FALSE, FALSE); IoMarkIrpPending( irp); } ntStatus = IoCallDriver( dev->fdo, irp); if (rtn) {#if DBG_USB uLan_DbgPrint("uLan: _usb_submit_urb done (rtn) with status:0x%X\n",ntStatus); #endif (*pirp)=irp; return ntStatus; }#if DBG_USB uLan_DbgPrint("ulan: _usb_submit_urb : return from IoCallDriver USBD %x\n", ntStatus);#endif if (ntStatus == STATUS_PENDING) { status = KeWaitForSingleObject( &event, Suspended, KernelMode, FALSE, NULL); } else { ioStatus.Status = ntStatus; } ntStatus = ioStatus.Status;#if DBG_USB uLan_DbgPrint("ulan: _usb_submit_urb : URB status = %x status = %x irp status %x\n", urb->UrbHeader.Status, status, ioStatus.Status); uLan_DbgPrint("uLan: _usb_submit_urb done with status:0x%X\n",ntStatus); #endif return ntStatus;}/** * usb_control_msg - Builds a control urb, sends it off and waits for completion * @dev: pointer to the usb device * @pipe: endpoint "pipe" to send the message to * @request: USB message request value * @requesttype: USB message request type value (only USB_TYPE_VENDOR) * @value: USB message value * @index: USB message value * @data: pointer to the data to send * @size: length in bytes of the data to send * @time: time to wait for the message to complete before timing out (if 0 the wait is forever) * * Return Value: NTSTATUS (data len) */ NTSTATUSusb_control_msg(IN usb_device *dev,IN ULONG pipe, IN UCHAR request,IN USHORT requesttype, IN USHORT value, IN USHORT index, IN PVOID data, IN ULONG size, IN ULONG time) { NTSTATUS ntStatus = STATUS_SUCCESS; LARGE_INTEGER timeout; ULONG flags = 0; PURB urb;#if DBG_USB uLan_DbgPrint("uLan: usb_control_msg pipe=0x%X, req=0x%X, reqtype=0x%X, value=0x%X, idx=0x%X, size=%d\n", pipe, request, requesttype, value , index, size);#endif if (!usb_pipecontrol(pipe)) { return STATUS_INVALID_PARAMETER; } if (usb_pipein(pipe)) flags = USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK; switch (requesttype) { case USB_TYPE_VENDOR: case USB_TYPE_CLASS: urb = MALLOC(sizeof( struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST)); if ( !urb) { uLan_DbgPrint("uLan: no memory for URB!!!\n"); return STATUS_INSUFFICIENT_RESOURCES; } UsbBuildVendorRequest( urb, URB_FUNCTION_VENDOR_DEVICE, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST), flags, 0, request, value, index, data, NULL, size, NULL); break; case USB_TYPE_STANDARD: /* to do */ /* urb = MALLOC(sizeof( struct _URB_CONTROL_TRANSFER)); */ break; default: break; } timeout.QuadPart = ((LONGLONG)time)*(-10000); /* time is in [ms] */ ntStatus = _usb_submit_urb( dev, urb, (time) ? &timeout : NULL, NULL, NULL, NULL); if (NT_SUCCESS(ntStatus)) { ntStatus = (LONG) urb->UrbControlVendorClassRequest.TransferBufferLength; } FREE( urb);#if DBG_USB uLan_DbgPrint("uLan: usb_control_msg done with status:0x%X\n",ntStatus); #endif return ntStatus; }/** * _usb_fill_bulk_urb - builds a bulk urb * @urb: pointer to filling urb * @usb_dev: pointer to the usb device to send the message to * @pipe: endpoint "pipe" to send the message to * @data: pointer to the data to send * @len: length in bytes of the data to send * * This function create bulk urb * * Return Value: NTSTATUS */ NTSTATUS_usb_fill_bulk_urb ( IN PURB urb, IN usb_device *dev,IN ULONG pipe, IN PVOID data, IN LONG len) { PUSBD_PIPE_INFORMATION pipe_info=NULL; PUSBD_INTERFACE_INFORMATION interface; ULONG flags = 0; ULONG endpoint; unsigned int j; if ((!usb_pipebulk(pipe)) || (!urb) || (!dev)) { return STATUS_INVALID_PARAMETER; } /* get handle of pipe */ endpoint=usb_pipeendpoint(pipe) | (pipe & USB_DIR_IN);#if DBG_USB uLan_DbgPrint("uLan: usb_bulk_msg selected endpoint=0x%X\n",endpoint);#endif interface=dev->interfaces.Interface; if ( !interface) { return STATUS_INVALID_PARAMETER; } /* trace all pipes */ for (j=0; j<interface->NumberOfPipes; j++) { pipe_info=&interface->Pipes[j]; if (pipe_info->EndpointAddress==endpoint) break; pipe_info=NULL; } if (!pipe_info) { return STATUS_INVALID_PARAMETER; } /* usb_show_endpoint_information(pipe_info); */ if (usb_pipein(pipe)) flags = USBD_TRANSFER_DIRECTION_IN; UsbBuildInterruptOrBulkTransferRequest( urb, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), pipe_info->PipeHandle, data, NULL, len, flags | USBD_SHORT_TRANSFER_OK, NULL ); return STATUS_SUCCESS;}/** * usb_bulk_msg - Builds a bulk urb, sends it off and waits for completion * @usb_dev: pointer to the usb device to send the message to * @pipe: endpoint "pipe" to send the message to * @data: pointer to the data to send * @len: length in bytes of the data to send * @actual_length: pointer to a location to put the actual length transferred in bytes * @timeout: time to wait for the message to complete before timing out (if 0 the wait is forever) * * This function sends a simple bulk message to a specified endpoint * and waits for the message to complete, or timeout. * * Return Value: NTSTATUS (data len) */ NTSTATUSusb_bulk_msg(IN usb_device *dev,IN ULONG pipe, IN PVOID data, IN LONG len, IN LONG *actual_length,IN ULONG time){ NTSTATUS ntStatus = STATUS_SUCCESS; LARGE_INTEGER timeout; PURB urb;#if DBG_USB uLan_DbgPrint("uLan: usb_bulk_msg pipe=0x%X, len=0x%X\n", pipe, len);#endif urb = MALLOC(sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER)); if ( !urb) { uLan_DbgPrint("uLan: no memory for URB!!!\n"); return STATUS_INSUFFICIENT_RESOURCES; } ntStatus=_usb_fill_bulk_urb (urb,dev,pipe,data,len); if ( !NT_SUCCESS( ntStatus)) { uLan_DbgPrint("uLan: error in filling bulk urb\n"); return ntStatus; } ntStatus = _usb_submit_urb(dev,urb,NULL,NULL,NULL,NULL); *actual_length = (LONG) urb->UrbBulkOrInterruptTransfer.TransferBufferLength; FREE( urb);#if DBG_USB uLan_DbgPrint("uLan: usb_bulk_msg done with status:0x%X\n",ntStatus); #endif return ntStatus;}/** * _usb_get_descriptor - Retrieves a descriptor from a device's default control pipe * @dev: pointer to the usb device * @desctype: (USB_DEVICE_DESCRIPTOR_TYPE, * USB_CONFIGURATION_TYPE, * USB_STRING_DESCRIPTOR_TYPE) * @descindex: the number of the descriptor * @buf: pointer ot pointer where to put the descriptor * @size: how big is buf? * * Return Value: NTSTATUS */ NTSTATUS _usb_get_descriptor(IN usb_device *dev, IN UCHAR desctype, IN UCHAR descindex, IN PVOID *buf, IN SHORT size) { NTSTATUS ntStatus = STATUS_SUCCESS; PURB urb; ULONG true_size = 4; PVOID new_ptr;#if DBG_USB uLan_DbgPrint("uLan: _usb_get_descriptor (type=0x%X,idx=0x%X)\n", desctype, descindex);#endif if (( *buf != NULL) && (size == -1)) { return STATUS_INVALID_PARAMETER; } urb = MALLOC(sizeof( struct _URB_CONTROL_DESCRIPTOR_REQUEST)); if ( !urb) { uLan_DbgPrint("uLan: no memory for URB\n"); return STATUS_INSUFFICIENT_RESOURCES; } if ( size != -1) { true_size = (ULONG) size; } AgainSendGetDescriptor: if (( size == -1) || (*buf == NULL)) { new_ptr = MALLOC(true_size); } else { new_ptr = *buf; } if ( new_ptr) { UsbBuildGetDescriptorRequest(urb, (USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST), desctype, descindex, 0, /* lang */ new_ptr, NULL, true_size, NULL); ntStatus = _usb_submit_urb(dev,urb,NULL,NULL,NULL,NULL); } else { ntStatus = STATUS_INSUFFICIENT_RESOURCES; } if (( size == -1) && NT_SUCCESS(ntStatus)) { if ( desctype == USB_CONFIGURATION_DESCRIPTOR_TYPE) true_size = (ULONG) *(((PUSHORT)new_ptr)+1); /* total_size */ else true_size = (ULONG) *((PUCHAR)new_ptr); size = 0; FREE( new_ptr); goto AgainSendGetDescriptor; } if ( NT_SUCCESS(ntStatus) && (*buf == NULL)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -