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

📄 dpnp.c

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

#ifdef DOWNLOAD_KEIL_MONITOR

extern INTEL_HEX_RECORD mon_ext_sio1_fx2[];
extern INTEL_HEX_RECORD loader[];

#endif // ifdef DOWNLOAD_KEIL_MONITOR


void d_DumpBuffer(PVOID pvBuffer, ULONG length);

NTSTATUS d_DispatchPnp(
   IN PDEVICE_OBJECT fdo,
   IN PIRP           Irp
   )
/*++
Routine Description:
   Process Plug and Play IRPs sent to this device.

Arguments:
   fdo - pointer to a device object
   Irp          - pointer to an I/O Request Packet

Return Value:
   NTSTATUS
--*/
{
   PIO_STACK_LOCATION irpStack;
   PDEVICE_EXTENSION pdx = fdo->DeviceExtension;
   ULONG fcn;
   NTSTATUS ntStatus;

   Ezusb_KdPrint (("Enter Ezusb_DispatchPnp\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);

   ASSERT(irpStack->MajorFunction == IRP_MJ_PNP);

   fcn = irpStack->MinorFunction;

   switch (fcn)
   {
      case IRP_MN_START_DEVICE:

         Ezusb_KdPrint (("IRP_MN_START_DEVICE\n"));

         ntStatus = d_HandleStartDevice(fdo,Irp);

         if (ntStatus == STATUS_SUCCESS)
         {
            pdx->Started = TRUE;
         }

         break; //IRP_MN_START_DEVICE

      case IRP_MN_STOP_DEVICE:

         Ezusb_KdPrint (("IRP_MN_STOP_DEVICE\n"));

         //
         // first pass the request down the stack
         //
         d_DefaultPnpHandler(fdo,Irp);

         ntStatus = d_StopDevice(fdo);

         break; //IRP_MN_STOP_DEVICE

      case IRP_MN_REMOVE_DEVICE:

         Ezusb_KdPrint (("IRP_MN_REMOVE_DEVICE\n"))

         ntStatus = d_HandleRemoveDevice(fdo,Irp);

         break; //IRP_MN_REMOVE_DEVICE

      case IRP_MN_QUERY_CAPABILITIES:
      {
         //
         // This code swiped from Walter Oney.  Please buy his book!!
         //

      	PDEVICE_CAPABILITIES pdc = irpStack->Parameters.DeviceCapabilities.Capabilities;

         Ezusb_KdPrint (("IRP_MN_QUERY_CAPABILITIES\n"))

         // Check to be sure we know how to handle this version of the capabilities structure

	      if (pdc->Version < 1)
         {
		      ntStatus = d_DefaultPnpHandler(fdo, Irp);
            break;
         }

         ntStatus = d_ForwardAndWait(fdo, Irp);
	      if (NT_SUCCESS(ntStatus))
   		{						// IRP succeeded
      		pdc = irpStack->Parameters.DeviceCapabilities.Capabilities;
            // 用户删除设备时,阻止 NT5 发出警告.
		      pdc->SurpriseRemovalOK = 0;//TRUE;//1;//
   		}						// IRP succeeded

	      ntStatus = CompleteRequest(Irp, ntStatus, Irp->IoStatus.Information);
		  //Irp->IoStatus.Status = ntStatus;
		  //Irp->IoStatus.Information = Irp->IoStatus.Information;
		  //IoCompleteRequest(Irp, IO_NO_INCREMENT);

      }
         break; //IRP_MN_QUERY_CAPABILITIES


      //
      // All other PNP IRP's are just passed down the stack by the default handler
      //
      default:
        Ezusb_KdPrint (("Passing down unhandled PnP IOCTL 0x%x\n", fcn));
        ntStatus = d_DefaultPnpHandler(fdo, Irp);

   } // switch MinorFunction

	if (fcn != IRP_MN_REMOVE_DEVICE)
      UnlockDevice(fdo);

   Ezusb_KdPrint (("Exit Ezusb_DispatchPnp %x\n", ntStatus));
   return ntStatus;

}//Ezusb_Dispatch

NTSTATUS d_HandleStartDevice(
   IN PDEVICE_OBJECT fdo,
   IN PIRP Irp
   )
{
   NTSTATUS ntStatus;

   //
   // First let all lower-level drivers handle this request.
   //
   ntStatus = d_ForwardAndWait(fdo, Irp);
	if (!NT_SUCCESS(ntStatus))
		return CompleteRequest(Irp, ntStatus, Irp->IoStatus.Information);

   //
   // now do whatever we need to do to start the device
   //
   ntStatus = d_StartDevice(fdo);

	return CompleteRequest(Irp, ntStatus, 0);
}

NTSTATUS d_DefaultPnpHandler(
   IN PDEVICE_OBJECT fdo,
   IN PIRP Irp
   )
{
   PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

   IoSkipCurrentIrpStackLocation(Irp);
   return IoCallDriver(pdx->StackDeviceObject, Irp);
}


NTSTATUS d_HandleRemoveDevice(
   IN PDEVICE_OBJECT fdo,
   IN PIRP Irp
   )
{
   NTSTATUS ntStatus;
   PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
   ULONG i;

   // set the removing flag to prevent any new I/O's
   pdx->removing = TRUE;

   // brute force - send an abort pipe message to all pipes to cancel any
   // pending transfers.  this should solve the problem of the driver blocking
   // on a REMOVE message because there is a pending transfer.
   for (i = 0; i < pdx->Interface->NumberOfPipes; i++)
   {
      c_AbortPipe(fdo,(USBD_PIPE_HANDLE) pdx->Interface->Pipes[i].PipeHandle);
   }

   UnlockDevice(fdo);			// once for LockDevice at start of dispatch
   UnlockDevice(fdo);			// once for initialization during AddDevice
   KeWaitForSingleObject(&pdx->evRemove, Executive, KernelMode, FALSE, NULL);

	d_RemoveDevice(fdo);

   ntStatus = d_DefaultPnpHandler(fdo, Irp);

   return ntStatus;				// lower-level completed IoStatus already

}


NTSTATUS d_StopDevice(
   IN  PDEVICE_OBJECT fdo
   )
/*++
Routine Description:
   Stops a given instance of a Ezusb Device device on USB.

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

Return Value:
   NT status code

  --*/
{
   PDEVICE_EXTENSION pdx;
   NTSTATUS ntStatus = STATUS_SUCCESS;
   PURB urb;
   ULONG siz;

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

   pdx = fdo->DeviceExtension;

   //
   // Send the select configuration urb with a NULL pointer for the configuration
   // handle, this closes the configuration and puts the device in the 'unconfigured'
   // state.
   //

   siz = sizeof(struct _URB_SELECT_CONFIGURATION);

   urb = ExAllocatePool(NonPagedPool,
                      siz);

   if (urb)
   {
      NTSTATUS status;

      UsbBuildSelectConfigurationRequest(urb,
                                       (USHORT) siz,
                                       NULL);

      status = Ezusb_CallUSBD(fdo, urb);

      Ezusb_KdPrint (("Device Configuration Closed status = %x usb status = %x.\n",
                     status, urb->UrbHeader.Status));

      ExFreePool(urb);
   }
   else
   {
      ntStatus = STATUS_NO_MEMORY;
   }

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

   return ntStatus;
}


NTSTATUS d_ForwardAndWait(
   IN PDEVICE_OBJECT fdo,
   IN PIRP Irp
   )
/*++
Routine Description:
   Forward request to lower level and await completion

   The only purpose of this routine in this particular driver is to pass down
   IRP_MN_START_DEVICE requests and wait for the PDO to handle them.
   
   The processor must be at PASSIVE IRQL because this function initializes
   and waits for non-zero time on a kernel event object.

Arguments:
   fdo - pointer to a device object
   Irp          - pointer to an I/O Request Packet

Return Value:
   STATUS_SUCCESS if successful,
   STATUS_UNSUCCESSFUL otherwise
--*/
{
	KEVENT event;
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
	NTSTATUS ntStatus;

   ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
	
	//
   // Initialize a kernel event object to use in waiting for the lower-level
	// driver to finish processing the object. 
   //
	KeInitializeEvent(&event, NotificationEvent, FALSE);

	IoCopyCurrentIrpStackLocationToNext(Irp);
	IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) OnRequestComplete,
		(PVOID) &event, TRUE, TRUE, TRUE);

	ntStatus = IoCallDriver(pdx->StackDeviceObject, Irp);

	if (ntStatus == STATUS_PENDING)
	{
      KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
      ntStatus = Irp->IoStatus.Status;
   }

	return ntStatus;
}

NTSTATUS d_StartDevice(
    IN  PDEVICE_OBJECT fdo
    )
/*++

Routine Description:
   Initializes a given instance of the Ezusb Device on the USB.

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

Return Value:
   NT status code
--*/
{
    PDEVICE_EXTENSION pdx;
    NTSTATUS ntStatus;
    PUSB_DEVICE_DESCRIPTOR deviceDescriptor = NULL;
    PURB urb;
    ULONG siz;

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

    pdx = fdo->DeviceExtension;
    pdx->NeedCleanup = TRUE;

    /*
    // Get some memory from then non paged pool (fixed, locked system memory)
    // for use by the USB Request Block (urb) for the specific USB Request we
    // will be performing below (a USB device request).
    */
    urb = ExAllocatePool( NonPagedPool,
                          sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));

    if (urb) {

        siz = sizeof(USB_DEVICE_DESCRIPTOR);

        // Get some non paged memory for the device descriptor contents
        deviceDescriptor = ExAllocatePool(NonPagedPool,
                                          siz);

        if (deviceDescriptor) {

            // Use a macro in the standard USB header files to build the URB
            UsbBuildGetDescriptorRequest(urb,
                                         (USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),
                                         USB_DEVICE_DESCRIPTOR_TYPE,
                                         0,
                                         0,
                                         deviceDescriptor,
                                         NULL,
                                         siz,
                                         NULL);

            // Get the device descriptor
            ntStatus = Ezusb_CallUSBD(fdo, urb);

        } else {
            ntStatus = STATUS_NO_MEMORY;
        }

⌨️ 快捷键说明

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