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

📄 ezusbsys.c

📁 usb 驱动程序源码
💻 C
📖 第 1 页 / 共 5 页
字号:

        } else {
            // Failed getting data buffer (configurationDescriptor) memory
            ntStatus = STATUS_NO_MEMORY;
            goto Exit_EzusbConfigureDevice;
        }//if-else

    } else {
        // failed getting urb memory
        ntStatus = STATUS_NO_MEMORY;
        goto Exit_EzusbConfigureDevice;
    }//if-else

    /*
    // We have the configuration descriptor for the configuration
    // we want.
    //
    // Now we issue the SelectConfiguration command to get
    // the  pipes associated with this configuration.
    */
    if (configurationDescriptor) {
        // Get our pipes
        ntStatus = Ezusb_SelectInterfaces(fdo,
                                           configurationDescriptor,
                                           NULL // Device not yet configured
                                           );
    } //if

Exit_EzusbConfigureDevice:

    // Clean up and exit this routine
    if (urb != NULL) {
        ExFreePool(urb);                    // Free urb memory
    }//if

    if (configurationDescriptor != NULL) {
        ExFreePool(configurationDescriptor);// Free data buffer
    }//if

    Ezusb_KdPrint (("exit Ezusb_ConfigureDevice (%x)\n", ntStatus));
    return ntStatus;
}//Ezusb_ConfigureDevice


NTSTATUS
Ezusb_SelectInterfaces(
    IN PDEVICE_OBJECT fdo,
    IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
    IN PUSBD_INTERFACE_INFORMATION Interface
    )
/*++

Routine Description:
    Initializes an Ezusb Device with multiple interfaces

Arguments:
    fdo            - pointer to the device object for this instance of the Ezusb Device
    ConfigurationDescriptor - pointer to the USB configuration descriptor containing the interface and endpoint
                              descriptors.
    Interface               - pointer to a USBD Interface Information Object
                            - If this is NULL, then this driver must choose its interface based on driver-specific
                              criteria, and the driver must also CONFIGURE the device.
                            - If it is NOT NULL, then the driver has already been given an interface and
                              the device has already been configured by the parent of this device driver.

Return Value:
    NT status code
--*/
{
   PDEVICE_EXTENSION pdx;
   NTSTATUS ntStatus;
   PURB urb;
   ULONG j;
   UCHAR alternateSetting, MyInterfaceNumber;
   PUSBD_INTERFACE_INFORMATION interfaceObject;
   USBD_INTERFACE_LIST_ENTRY interfaceList[2];

   Ezusb_KdPrint (("enter Ezusb_SelectInterfaces\n"));

   pdx = fdo->DeviceExtension;
   MyInterfaceNumber = SAMPLE_INTERFACE_NBR;

	// Search the configuration descriptor for the first interface/alternate setting

   interfaceList[0].InterfaceDescriptor =
   USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor,
                                       ConfigurationDescriptor,
                                       -1,         // Interface - don't care
                                       -1,         // Alternate Setting - don't care
                                       -1,         // Class - don't care
                                       -1,         // SubClass - don't care
                                       -1);        // Protocol - don't care

   ASSERT(interfaceList[0].InterfaceDescriptor != NULL);

   interfaceList[1].InterfaceDescriptor = NULL;
   interfaceList[1].Interface = NULL;

   urb = USBD_CreateConfigurationRequestEx(ConfigurationDescriptor,&interfaceList[0]);

   if (!urb)
   {
      Ezusb_KdPrint ((" USBD_CreateConfigurationRequestEx failed\n"));            
   }

   DumpBuffer(urb, urb->UrbHeader.Length);

   interfaceObject = (PUSBD_INTERFACE_INFORMATION) (&(urb->UrbSelectConfiguration.Interface));

   /*
   // We set up a default max transfer size for the endpoints.  Your driver will
   // need to change this to reflect the capabilities of your device's endpoints.
   */
   for (j=0; j<interfaceList[0].InterfaceDescriptor->bNumEndpoints; j++)
      interfaceObject->Pipes[j].MaximumTransferSize = (Transsize * 1024) - 1;


   ntStatus = Ezusb_CallUSBD(fdo, urb);

   DumpBuffer(urb, urb->UrbHeader.Length);

   if (NT_SUCCESS(ntStatus) && USBD_SUCCESS(urb->UrbHeader.Status))
   {

      // Save the configuration handle for this device
      pdx->ConfigurationHandle =
         urb->UrbSelectConfiguration.ConfigurationHandle;

      pdx->Interface = ExAllocatePool(NonPagedPool,
                                                interfaceObject->Length);

      // save a copy of the interfaceObject information returned
      RtlCopyMemory(pdx->Interface, interfaceObject, interfaceObject->Length);

      // Dump the interfaceObject to the debugger
      Ezusb_KdPrint (("---------\n"));
      Ezusb_KdPrint (("NumberOfPipes 0x%x\n", pdx->Interface->NumberOfPipes));
      Ezusb_KdPrint (("Length 0x%x\n", pdx->Interface->Length));
      Ezusb_KdPrint (("Alt Setting 0x%x\n", pdx->Interface->AlternateSetting));
      Ezusb_KdPrint (("Interface Number 0x%x\n", pdx->Interface->InterfaceNumber));

      // Dump the pipe info
      for (j=0; j<interfaceObject->NumberOfPipes; j++)
      {
         PUSBD_PIPE_INFORMATION pipeInformation;

         pipeInformation = &pdx->Interface->Pipes[j];

         Ezusb_KdPrint (("---------\n"));
         Ezusb_KdPrint (("PipeType 0x%x\n", pipeInformation->PipeType));
         Ezusb_KdPrint (("EndpointAddress 0x%x\n", pipeInformation->EndpointAddress));
         Ezusb_KdPrint (("MaxPacketSize 0x%x\n", pipeInformation->MaximumPacketSize));
         Ezusb_KdPrint (("Interval 0x%x\n", pipeInformation->Interval));
         Ezusb_KdPrint (("Handle 0x%x\n", pipeInformation->PipeHandle));
         Ezusb_KdPrint (("MaximumTransferSize 0x%x\n", pipeInformation->MaximumTransferSize));
      }

      Ezusb_KdPrint (("---------\n"));
   }


   Ezusb_KdPrint (("exit Ezusb_SelectInterfaces (%x)\n", ntStatus));

   return ntStatus;

}/* Ezusb_SelectInterfaces */


NTSTATUS
Ezusb_Read_Write(
   IN  PDEVICE_OBJECT fdo,
   IN  PIRP Irp
   )
/*++
Routine Description:
    
Arguments:

Return Value:
    NT status code
        STATUS_SUCCESS:                 Read was done successfully
        STATUS_INVALID_PARAMETER_3:     The Endpoint Index does not specify an IN pipe 
        STATUS_NO_MEMORY:               Insufficient data memory was supplied to perform the READ

    This routine fills the status code into the Irp
    
--*/
{
   PDEVICE_EXTENSION          pdx = fdo->DeviceExtension;
   NTSTATUS                   ntStatus;
   PIO_STACK_LOCATION         irpStack = IoGetCurrentIrpStackLocation (Irp);
   PBULK_TRANSFER_CONTROL     bulkControl =
                              (PBULK_TRANSFER_CONTROL)Irp->AssociatedIrp.SystemBuffer;
   ULONG                      bufferLength =
                              irpStack->Parameters.DeviceIoControl.OutputBufferLength;
   PURB                       urb = NULL;
   ULONG                      urbSize = 0;
   ULONG                      transferFlags = 0;
   PUSBD_INTERFACE_INFORMATION interfaceInfo = NULL;
   PUSBD_PIPE_INFORMATION     pipeInfo = NULL;
   USBD_PIPE_HANDLE           pipeHandle = NULL;


   Ezusb_KdPrint(("enter Ezusb_Read_Write()\n"));
   
   //
   // verify that the selected pipe is valid, and get a handle to it. If anything
   // is wrong, return an error
   //
   interfaceInfo = pdx->Interface;

   if (!interfaceInfo)
   {
      Ezusb_KdPrint(("Ezusb_Read_Write() no interface info - Exiting\n"));
      return STATUS_UNSUCCESSFUL;
   }
   
   if (bulkControl->pipeNum > interfaceInfo->NumberOfPipes)
   {
      Ezusb_KdPrint(("Ezusb_Read_Write() invalid pipe - Exiting\n"));
      return STATUS_INVALID_PARAMETER;
   }

   pipeInfo = &(interfaceInfo->Pipes[bulkControl->pipeNum]);

   if (!((pipeInfo->PipeType == UsbdPipeTypeBulk) ||
         (pipeInfo->PipeType == UsbdPipeTypeInterrupt)))
   {
      Ezusb_KdPrint(("Ezusb_Read_Write() invalid pipe - Exiting\n"));
      return STATUS_INVALID_PARAMETER;
   }

   pipeHandle = pipeInfo->PipeHandle;

   if (!pipeHandle)
   {
      Ezusb_KdPrint(("Ezusb_Read_Write() invalid pipe - Exiting\n"));
      return STATUS_UNSUCCESSFUL;
   }

   if (bufferLength > pipeInfo->MaximumTransferSize)
   {
      Ezusb_KdPrint(("Ezusb_Read_Write() invalid transfer size - Exiting\n"));
      return STATUS_INVALID_PARAMETER;
   }

   //
   // allocate and fill in the Usb request (URB)
   //
   urbSize = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER);

   urb = ExAllocatePool(NonPagedPool,urbSize);

   if (!urb)
   {
      Ezusb_KdPrint(("Ezusb_Read_Write() unable to alloc URB - Exiting\n"));
      return STATUS_NO_MEMORY;
   }
   

   transferFlags = USBD_SHORT_TRANSFER_OK;

   //
   // get direction info from the endpoint address
   //
   if (USB_ENDPOINT_DIRECTION_IN(pipeInfo->EndpointAddress))
      transferFlags |= USBD_TRANSFER_DIRECTION_IN;

   UsbBuildInterruptOrBulkTransferRequest(urb,        //ptr to urb
                        (USHORT) urbSize,             //size of urb
							   pipeHandle,                   //usbd pipe handle
							   NULL,                         //TransferBuffer
							   Irp->MdlAddress,              //mdl
							   bufferLength,                 //bufferlength
							   transferFlags,                //flags
							   NULL);                        //link

   //
   // Call the USB Stack.
   //
	ntStatus = Ezusb_CallUSBD(fdo, urb);

   //
   // If the transfer was successful, report the length of the transfer to the
   // caller by setting IoStatus.Information
   //
   if (NT_SUCCESS(ntStatus))
   {
      Irp->IoStatus.Information = urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
      Ezusb_KdPrint(("Successfully transfered 0x%x bytes\n",Irp->IoStatus.Information));
   }

   //
   // free the URB
   //
   ExFreePool(urb);

   return ntStatus;
}


NTSTATUS
Ezusb_Create(
    IN PDEVICE_OBJECT fdo,
    IN PIRP Irp
    )
/*++
Routine Description:
     This is the Entry point for CreateFile calls from user mode apps (apps may open "\\.\Ezusb-x\yyzz"
     where yy is the interface number and zz is the endpoint address).

     Here is where you would add code to create symbolic links between endpoints
     (i.e., pipes in USB software terminology) and User Mode file names.  You are
     free to use any convention you wish to create these links, although the above
     convention offers a way to identify resources on a device by familiar file and
     directory structure nomenclature.

Arguments:
    fdo - pointer to the device object for this instance of the Ezusb device

Return Value:
    NT status code
--*/
{
   NTSTATUS ntStatus;
   PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION )fdo->DeviceExtension;

   Ezusb_KdPrint(("Enter Ezusb_Create()\n"));

   if (!pdx->Started)
   {
      return STATUS_UNSUCCESSFUL;
   }

   // increment the open handle counter
   pdx->OpenHandles++;

   Irp->IoStatus.Status = STATUS_SUCCESS;
   Irp->IoStatus.Information = 0;

   // Create all the symbolic links here
   ntStatus = Irp->IoStatus.Status;

   IoCompleteRequest (Irp,
                    IO_NO_INCREMENT
                    );

   return ntStatus;

}//Ezusb_Create


NTSTATUS
Ezusb_Close(
    IN PDEVICE_OBJECT fdo,
    IN PIRP Irp
    )
/*++
Routine Description:
    Entry point for CloseHandle calls from user mode apps to close handles they have opened

Arguments:
    fdo - pointer to the device object for this instance of the Ezusb device
    Irp          - pointer to an irp

Return Value:
    NT status code

--*/
{
   NTSTATUS ntStatus;
   PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION )fdo->DeviceExtension;

   Ezusb_KdPrint(("Enter Ezusb_Close()\n"));

   // decrement the open handle counter
   pdx->OpenHandles--;

   Irp->IoStatus.Status = STATUS_SUCCESS;
   Irp->IoStatus.Information = 0;

   ntStatus = Irp->IoStatus.Status;

   IoCompleteRequest (Irp,
                    IO_NO_INCREMENT
                    );

   return ntStatus;

}//Ezusb_Close


NTSTATUS
Ezusb_ProcessIOCTL(
    IN PDEVICE_OBJECT fdo,
    IN PIRP Irp
    )
/*++

Routine Description:
   This where all the DeviceIoControl c

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -