⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ezusbsys.c

📁 ezmon, VC程序
💻 C
📖 第 1 页 / 共 4 页
字号:
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 + -