📄 ezusbsys.c
字号:
Ezusb_GetOtherSpeedConfigDescriptor(
IN PDEVICE_OBJECT fdo,
PVOID pvOutputBuffer,
ULONG ulLength
)
/*++
Routine Description:
Gets a configuration descriptor from the given device object
Arguments:
fdo - pointer to the sample device object
pvOutputBuffer - pointer to the buffer where the data is to be placed
ulLength - length of the buffer
Return Value:
Number of valid bytes in data buffer
--*/
{
return (c_GetDescriptor(fdo,
pvOutputBuffer,
ulLength,
7));
}
ULONG
Ezusb_DownloadTest(
IN PDEVICE_OBJECT fdo,
IN PVENDOR_REQUEST_IN pVendorRequest
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PURB urb = NULL;
ULONG length = 0;
ULONG i;
PUCHAR buffer1 = NULL;
PUCHAR buffer2 = NULL;
ULONG CompareCount = 0;
Ezusb_KdPrint (("Enter Ezusb_VendorRequest - yahoooo\n"));
urb = ExAllocatePool(NonPagedPool,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
buffer1 = ExAllocatePool(NonPagedPool, CHUNKLENGTH);
buffer2 = ExAllocatePool(NonPagedPool, CHUNKLENGTH);
for (i=0; i < CHUNKLENGTH; i++)
{
buffer1[i] = (UCHAR) i;
}
if (urb)
{
for (i=0; i < 5120 / CHUNKLENGTH; i++)
{
RtlZeroMemory(urb,sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
//
// fill in the URB
//
urb->UrbHeader.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
urb->UrbHeader.Function = URB_FUNCTION_VENDOR_DEVICE;
urb->UrbControlVendorClassRequest.TransferBufferLength = CHUNKLENGTH;
urb->UrbControlVendorClassRequest.TransferBuffer = buffer1;
urb->UrbControlVendorClassRequest.TransferBufferMDL = NULL;
urb->UrbControlVendorClassRequest.Request = 0xA0;
urb->UrbControlVendorClassRequest.Value = (unsigned short) i * CHUNKLENGTH;
urb->UrbControlVendorClassRequest.Index = 0;
ntStatus = Ezusb_CallUSBD(fdo, urb);
}
for (i=0; i < 5120 / CHUNKLENGTH; i++)
{
RtlZeroMemory(urb,sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
RtlZeroMemory(buffer2, CHUNKLENGTH);
//
// fill in the URB
//
urb->UrbHeader.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
urb->UrbHeader.Function = URB_FUNCTION_VENDOR_DEVICE;
urb->UrbControlVendorClassRequest.TransferBufferLength = CHUNKLENGTH;
urb->UrbControlVendorClassRequest.TransferBuffer = buffer2;
urb->UrbControlVendorClassRequest.TransferBufferMDL = NULL;
urb->UrbControlVendorClassRequest.Request = 0xA0;
urb->UrbControlVendorClassRequest.Value = (unsigned short) i * CHUNKLENGTH;
urb->UrbControlVendorClassRequest.Index = 0;
urb->UrbControlVendorClassRequest.TransferFlags |= USBD_TRANSFER_DIRECTION_IN;
ntStatus = Ezusb_CallUSBD(fdo, urb);
CompareCount = RtlCompareMemory(buffer1,buffer2,CHUNKLENGTH);
Ezusb_KdPrint (("%d matched\n",CompareCount))
if (CompareCount != CHUNKLENGTH)
{
Ezusb_KdPrint (("**** Compare Error *****************************************************\n"));
}
}
}
return length;
}
NTSTATUS
ConfigureDevice(
IN PDEVICE_OBJECT fdo
)
/*++
Routine Description:
Configures the USB device via USB-specific device requests and interaction
with the USB software subsystem.
Arguments:
fdo - pointer to the device object for this instance of the Ezusb Device
Return Value:
NT status code
--*/
{
PDEVICE_EXTENSION pdx = fdo->DeviceExtension;
NTSTATUS ntStatus;
PURB urb = NULL;
ULONG numberOfPipes;
PUSB_CONFIGURATION_DESCRIPTOR configurationDescriptor = NULL;
PUSB_INTERFACE_DESCRIPTOR interfaceDescriptor = NULL;
Ezusb_KdPrint (("enter ConfigureDevice\n"));
//
// Get the configuration Descriptor
//
configurationDescriptor = GetConfigDescriptor(fdo);
if (!configurationDescriptor)
{
Ezusb_KdPrint (("Get Configuration Descriptor Failed\n"));
ntStatus = STATUS_UNSUCCESSFUL;
goto CleanupConfigureDevice;
}
#define INTERFACENUMBER 0
#define ALTERNATESETTING 1
//
// Get the interface Descriptor for the interface we want
//
interfaceDescriptor = USBD_ParseConfigurationDescriptorEx(
configurationDescriptor,
configurationDescriptor,
INTERFACENUMBER,
ALTERNATESETTING,
-1,
-1,
-1);
if (!interfaceDescriptor)
{
ntStatus = STATUS_UNSUCCESSFUL;
goto CleanupConfigureDevice;
}
numberOfPipes = interfaceDescriptor->bNumEndpoints;
//
// Configure the Device, but don't select any interfaces
//
urb = USBD_CreateConfigurationRequestEx(configurationDescriptor, NULL);
if (!urb)
{
Ezusb_KdPrint (("USBD_CreateConfigurationRequestEx Failed\n"));
ntStatus = STATUS_UNSUCCESSFUL;
goto CleanupConfigureDevice;
}
ntStatus = Ezusb_CallUSBD(fdo, urb);
if (NT_SUCCESS(ntStatus))
{
pdx->ConfigurationHandle = urb->UrbSelectConfiguration.ConfigurationHandle;
}
else
{
Ezusb_KdPrint (("Configuration Request Failed\n"));
ntStatus = STATUS_UNSUCCESSFUL;
goto CleanupConfigureDevice;
}
CleanupConfigureDevice:
// Clean up and exit this routine
if (urb != NULL)
{
ExFreePool(urb);
}
if (configurationDescriptor != NULL)
{
ExFreePool(configurationDescriptor);
}
Ezusb_KdPrint (("exit Ezusb_ConfigureDevice (%x)\n", ntStatus));
return ntStatus;
}
///////////////////////////////////////////////////////////////////////////////
// @func Lock a SIMPLE device object
// @parm Address of our device extension
// @rdesc TRUE if it was possible to lock the device, FALSE otherwise.
// @comm A FALSE return value indicates that we're in the process of deleting
// the device object, so all new requests should be failed
BOOLEAN LockDevice(
IN PDEVICE_OBJECT fdo
)
{
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
// Increment use count on our device object
LONG usage = InterlockedIncrement(&pdx->usage);
// AddDevice initialized the use count to 1, so it ought to be bigger than
// one now. HandleRemoveDevice sets the "removing" flag and decrements the
// use count, possibly to zero. So if we find a use count of "1" now, we
// should also find the "removing" flag set.
ASSERT(usage > 1 || pdx->removing);
// If device is about to be removed, restore the use count and return FALSE.
// If we're in a race with HandleRemoveDevice (maybe running on another CPU),
// the sequence we've followed is guaranteed to avoid a mistaken deletion of
// the device object. If we test "removing" after HandleRemoveDevice sets it,
// we'll restore the use count and return FALSE. In the meantime, if
// HandleRemoveDevice decremented the count to 0 before we did our increment,
// its thread will have set the remove event. Otherwise, we'll decrement to 0
// and set the event. Either way, HandleRemoveDevice will wake up to finish
// removing the device, and we'll return FALSE to our caller.
//
// If, on the other hand, we test "removing" before HandleRemoveDevice sets it,
// we'll have already incremented the use count past 1 and will return TRUE.
// Our caller will eventually call UnlockDevice, which will decrement the use
// count and might set the event HandleRemoveDevice is waiting on at that point.
if (pdx->removing)
{
if (InterlockedDecrement(&pdx->usage) == 0)
KeSetEvent(&pdx->evRemove, 0, FALSE);
return FALSE;
}
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
// @func Unlock a SIMPLE device object
// @parm Address of our device extension
// @comm If the use count drops to zero, set the evRemove event because we're
// about to remove this device object.
void UnlockDevice(
PDEVICE_OBJECT fdo
)
{
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
LONG usage = InterlockedDecrement(&pdx->usage);
ASSERT(usage >= 0);
if (usage == 0)
{ // removing device
ASSERT(pdx->removing); // HandleRemoveDevice should already have set this
KeSetEvent(&pdx->evRemove, 0, FALSE);
} // removing device
}
NTSTATUS IsoTransferComplete(
IN PDEVICE_OBJECT bunkfdo,
IN PIRP Irp,
IN PVOID Context
)
{
NTSTATUS ntStatus,status;
PISO_TRANSFER_OBJECT transferObject = (PISO_TRANSFER_OBJECT) Context;
PISO_STREAM_OBJECT streamObject = transferObject->StreamObject;
PDEVICE_OBJECT fdo = streamObject->DeviceObject;
PDEVICE_EXTENSION pdx = fdo->DeviceExtension;
PIO_STACK_LOCATION nextStack;
PURB urb = transferObject->Urb;
ULONG urbSize = 0;
ULONG i;
Ezusb_KdPrint(("IsoTransferComplete Irp Status 0x%x\n",Irp->IoStatus.Status));
//
// copy the ISO transfer descriptors to the callers buffer. The user mode caller passed
// in a large buffer. That buffer holds both the data and also provides space for the ISO
// descriptors. This way, the caller can verify the status of each ISO packet transmitted
// or sent.
//
RtlCopyMemory((PUCHAR) streamObject->IsoDescriptorBuffer + (transferObject->Frame * sizeof(USBD_ISO_PACKET_DESCRIPTOR)),
urb->UrbIsochronousTransfer.IsoPacket,
(streamObject->FramesPerBuffer * sizeof(USBD_ISO_PACKET_DESCRIPTOR)));
for (i=0;i<streamObject->FramesPerBuffer; i++)
{
Ezusb_KdPrint (("Packet %d length = %d status = %d\n",i,
urb->UrbIsochronousTransfer.IsoPacket[i].Length,urb->UrbIsochronousTransfer.IsoPacket[i].Status));
}
transferObject->Frame += (streamObject->FramesPerBuffer * streamObject->BufferCount);
if (transferObject->Frame < streamObject->NumPackets)
{
Ezusb_KdPrint(("IsoTransferComplete setting up the next transfer at frame %d\n",transferObject->Frame));
//
// reinitialize the URB for the next transfer.
//
urbSize = GET_ISO_URB_SIZE(streamObject->FramesPerBuffer);
RtlZeroMemory(urb,urbSize);
urb->UrbHeader.Length = urbSize;
urb->UrbHeader.Function = URB_FUNCTION_ISOCH_TRANSFER;
urb->UrbIsochronousTransfer.PipeHandle = streamObject->PipeInfo->PipeHandle;
urb->UrbIsochronousTransfer.TransferFlags =
USB_ENDPOINT_DIRECTION_IN(streamObject->PipeInfo->EndpointAddress) ? USBD_TRANSFER_DIRECTION_IN : 0;
urb->UrbIsochronousTransfer.TransferFlags |=
USBD_START_ISO_TRANSFER_ASAP;
urb->UrbIsochronousTransfer.TransferFlags |=
USBD_SHORT_TRANSFER_OK;
urb->UrbIsochronousTransfer.TransferBufferLength =
streamObject->PacketSize * streamObject->FramesPerBuffer;
urb->UrbIsochronousTransfer.TransferBuffer =
((PUCHAR) streamObject->TransferBuffer) + (transferObject->Frame * streamObject->PacketSize);
urb->UrbIsochronousTransfer.NumberOfPackets = streamObject->FramesPerBuffer;
for (i=0; i<streamObject->FramesPerBuffer; i++)
{
urb->UrbIsochronousTransfer.IsoPacket[i].Offset = i * streamObject->PacketSize;
urb->UrbIsochronousTransfer.IsoPacket[i].Length = streamObject->PacketSize;
}
//
// initialize the IRP for the next transfer
// cuz lynn says I hafta
//
IoInitializeIrp(Irp,
IoSizeOfIrp((pdx->StackDeviceObject->StackSize + 1)),
(CCHAR)(pdx->StackDeviceObject->StackSize + 1));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -