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

📄 cioctl.c

📁 ezmon, VC程序
💻 C
📖 第 1 页 / 共 4 页
字号:
// #define DRIVER
//
// Include files needed for WDM driver support
//
#include <wdm.h>
#include "stdarg.h"
#include "stdio.h"

//
// Include files needed for USB support
//
#include "usbdi.h"
#include "usbdlib.h"

//
// Include file for the Ezusb Device
//
#include "ezusbsys.h"

//
// incude file containing driver version
//
#include "version.h"

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

Routine Description:
   This where all the DeviceIoControl codes are handled.  You can add more code
   here to handle IOCTL codes that are specific to your device driver.

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

Return Value:
   NT status code
--*/
{
   PIO_STACK_LOCATION irpStack;
   PVOID ioBuffer;
   ULONG inputBufferLength;
   ULONG outputBufferLength;
   PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION )fdo->DeviceExtension;
   ULONG ioControlCode;
   NTSTATUS ntStatus;
   ULONG length;
   PUCHAR pch;

   Ezusb_KdPrint (("IRP_MJ_DEVICE_CONTROL\n"));

   if (!LockDevice(fdo))
      return CompleteRequest(Irp, STATUS_DELETE_PENDING, 0);

   //
   // Get a pointer to the current location in the Irp. This is where
   //     the function codes and parameters are located.
   //
   irpStack = IoGetCurrentIrpStackLocation (Irp);

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

   ioBuffer           = Irp->AssociatedIrp.SystemBuffer;
   inputBufferLength  = irpStack->Parameters.DeviceIoControl.InputBufferLength;
   outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;

   ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;

   //
   // Handle Ioctls from User mode
   //
   switch (ioControlCode)
   {

      case IOCTL_Ezusb_VENDOR_REQUEST:
         length = c_VendorRequest (fdo, (PVENDOR_REQUEST_IN) ioBuffer);

         if (length)
         {
            Irp->IoStatus.Information = length;
            Irp->IoStatus.Status = STATUS_SUCCESS;
         }
         else
         {
            Irp->IoStatus.Status = STATUS_SUCCESS;
         }
   
         Ezusb_KdPrint(("Vendor Request returned %d bytes\n", length));

         break;

      case IOCTL_Ezusb_ANCHOR_DOWNLOAD:
      {
         PURB                urb             = NULL;
         int   chunkcount;
         int   chunklength = 1024;
         PVOID ioBufferPtr = NULL;
         int i;

         urb = ExAllocatePool(NonPagedPool, 
                             sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));

         Ezusb_KdPrint (("IOCTL_Ezusb_ANCHOR_DOWNLOAD\n"));
                
         if (urb)
         {
            chunkcount = inputBufferLength / CHUNKLENGTH;
            ioBufferPtr = ioBuffer;

            for (i=0;i<chunkcount;i++)
            {
               RtlZeroMemory(urb,sizeof(struct  _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));

               urb->UrbHeader.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
               urb->UrbHeader.Function = URB_FUNCTION_VENDOR_DEVICE;

               Ezusb_KdPrint (("ioBuffer: %x | inputBufferLength: %d | outputBufferLength: %d\n",
                                 ioBuffer, inputBufferLength, outputBufferLength));

               urb->UrbControlVendorClassRequest.TransferBufferLength = CHUNKLENGTH;
               urb->UrbControlVendorClassRequest.TransferBuffer = ioBufferPtr;
               urb->UrbControlVendorClassRequest.TransferBufferMDL = NULL;
               urb->UrbControlVendorClassRequest.Request = 0xA0;
               urb->UrbControlVendorClassRequest.Value = (i * CHUNKLENGTH);
               urb->UrbControlVendorClassRequest.Index = 0;

               ntStatus = Ezusb_CallUSBD(fdo, urb);

               (char *) ioBufferPtr += CHUNKLENGTH;
            }

            ExFreePool(urb);
         }
      }

      break;

      case IOCTL_EZUSB_ANCHOR_DOWNLOAD:
      {
         PANCHOR_DOWNLOAD_CONTROL downloadControl = (PANCHOR_DOWNLOAD_CONTROL) ioBuffer;

         Ezusb_KdPrint (("IOCTL_EZUSB_ANCHOR_DOWNLOAD\n"));

         //
         // check the arguments
         //
         if (inputBufferLength != sizeof(ANCHOR_DOWNLOAD_CONTROL) ||
             outputBufferLength == 0)
         {
            Ezusb_KdPrint (("Error: Invalid Parameter\n"));
            ntStatus = STATUS_INVALID_PARAMETER;
         }
         else
         {
            ntStatus = c_AnchorDownload(fdo,
                                            downloadControl->Offset,
                                            (PUCHAR) MmGetSystemAddressForMdl(Irp->MdlAddress),
                                            outputBufferLength);
         }

         break;
      }
      case IOCTL_Ezusb_GET_CURRENT_CONFIG:

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

         break;

      case IOCTL_EZUSB_GET_CURRENT_FRAME_NUMBER:
      {
         ULONG frameNumber = 0;

         //
         // make sure the output buffer is valid
         //
         if (outputBufferLength < sizeof(ULONG))
         {
            Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
            break;
         }
         
         frameNumber = c_GetCurrentFrameNumber (fdo);

         if (frameNumber)
         {
            *((PULONG)ioBuffer) = frameNumber;
            Irp->IoStatus.Information = sizeof(ULONG);
            Irp->IoStatus.Status = STATUS_SUCCESS;
         }
         else
            Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
      }

         break;

      case IOCTL_Ezusb_RESETPIPE:
      {
         ULONG pipenum = *((PULONG) ioBuffer);

         Irp->IoStatus.Status = c_ResetPipe(fdo,pipenum);
      }

      break;

      case IOCTL_Ezusb_ABORTPIPE:
      {
         int pipenum = *((PULONG) ioBuffer);

         c_AbortPipe(fdo,
                        (USBD_PIPE_HANDLE) pdx->Interface->Pipes[pipenum].PipeHandle);

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

      case IOCTL_Ezusb_GET_PIPE_INFO:
         //
         // inputs  - none
         // outputs - we copy the interface information structure that we have
         //           stored in our device extension area to the output buffer which
         //           will be reflected to the user mode application by the IOS.
         //
         length = 0;
         pch = (PUCHAR) ioBuffer;

         if (pdx->Interface)
         {
            RtlCopyMemory(pch+length,
                          (PUCHAR) pdx->Interface,
                          pdx->Interface->Length);

            length += pdx->Interface->Length;
         }


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

         break;

      case IOCTL_Ezusb_GET_DEVICE_DESCRIPTOR:
         //
         // inputs  - pointer to a buffer in which to place descriptor data
         // outputs - we put the device descriptor data, if any is returned by the device
         //           in the system buffer and then we set the length inthe Information field
         //           in the Irp, which will then cause the system to copy the buffer back
         //           to the user's buffer
         //
         length = c_GetDeviceDescriptor (fdo, ioBuffer);

         Ezusb_KdPrint(("Get Device Descriptor returned %d bytes\n", length));

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

         break;

      case IOCTL_Ezusb_GET_STRING_DESCRIPTOR:
         {
            PGET_STRING_DESCRIPTOR_IN Input = ioBuffer;

            if ((inputBufferLength = sizeof(GET_STRING_DESCRIPTOR_IN)) &&
                (outputBufferLength > 0))
            {
               length = c_GetStringDescriptor (fdo,
                                                   Input->Index,
                                                   Input->LanguageId,
                                                   ioBuffer,
                                                   outputBufferLength);

               if (length)
               {
                  Irp->IoStatus.Information = length;
                  Irp->IoStatus.Status = STATUS_SUCCESS;
               }
               else
               {
                  Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
               }
            }
            else
            {
               Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
            }
         }      
         break;

         case IOCTL_Ezusb_GET_CONFIGURATION_DESCRIPTOR:
            //
            // inputs  - pointer to a buffer in which to place descriptor data
            // outputs - we put the configuration descriptor data, if any is returned by the device
            //           in the system buffer and then we set the length in the Information field
            //           in the Irp, which will then cause the system to copy the buffer back
            //           to the user's buffer
            //
            length = c_GetConfigDescriptor (fdo, ioBuffer, outputBufferLength);

            Ezusb_KdPrint(("Get Config Descriptor returned %d bytes\n", length));

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

            break;

      case IOCTL_Ezusb_SETINTERFACE:
      {
         PSET_INTERFACE_IN input = ioBuffer;

         Irp->IoStatus.Status = c_SetInterface(fdo,
                                             input->interfaceNum,
                                             input->alternateSetting);
         Irp->IoStatus.Status = 0;
      }
      break;
    
      case IOCTL_Ezusb_RESET:

         c_ResetParentPort(fdo);

         break;

      case IOCTL_EZUSB_BULK_WRITE:
      case IOCTL_EZUSB_BULK_READ:

         Irp->IoStatus.Status = Ezusb_Read_Write(fdo,Irp);

         break;

      case IOCTL_EZUSB_VENDOR_OR_CLASS_REQUEST:

         Irp->IoStatus.Status = c_VendorRequest2(fdo,Irp);

         break;

      case IOCTL_EZUSB_GET_LAST_ERROR:

         //
         // make sure the output buffer is ok, and then copy the most recent
         // URB status from the device extension to it
         //
         if (outputBufferLength >= sizeof(ULONG))
         {
            *((PULONG)ioBuffer) = pdx->LastFailedUrbStatus;
            Irp->IoStatus.Status = STATUS_SUCCESS;
            Irp->IoStatus.Information = sizeof(ULONG);
         }
         else
         {
            Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
         }

         break;

         case IOCTL_EZUSB_ISO_READ:
         case IOCTL_EZUSB_ISO_WRITE:
            Irp->IoStatus.Status = Ezusb_StartIsoTransfer(fdo,Irp);
            Irp->IoStatus.Information = 0;
         break;

         case IOCTL_EZUSB_START_ISO_STREAM:
            Irp->IoStatus.Status = Ezusb_StartIsoStream(fdo,Irp);
            Irp->IoStatus.Information = 0;
         break;

         case IOCTL_EZUSB_STOP_ISO_STREAM:
            pdx->StopIsoStream = TRUE;
            Irp->IoStatus.Status = STATUS_SUCCESS;
            Irp->IoStatus.Information = 0;
         break;

         case IOCTL_EZUSB_READ_ISO_BUFFER:
         {
            ULONG dataBytesToRead;
            ULONG descriptorBytesToRead;
            ULONG dataBytesRead;
            ULONG descriptorBytesRead;

            PISO_TRANSFER_CONTROL isoControl =
               (PISO_TRANSFER_CONTROL)Irp->AssociatedIrp.SystemBuffer;

            //
            // verify the input and output params
            //

⌨️ 快捷键说明

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