lab2.c

来自「通过VC源代码」· C语言 代码 · 共 859 行 · 第 1/2 页

C
859
字号
                ret = STATUS_UNSUCCESSFUL;

    } /* ioControlCode */

    KdPrint( ("%s: Device Control  -- return\n",   DBG_MSG_HDR) );
    //
    // Fill these in before calling IoCompleteRequest.
    //

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

    IoCompleteRequest( Irp, IO_NO_INCREMENT );


    return ret;
}

/****************************************************************************
    Function:
              Lab2Unload
    Arguments:

    Description:

    Returns:


*****************************************************************************/
VOID Lab2Unload( IN PDRIVER_OBJECT driverObject)
{
    UNICODE_STRING uniDosNameString;
    PLAB2_DEVICE_EXTENSION extension;
    BOOLEAN GotResources;

    extension = driverObject->DeviceObject->DeviceExtension;

    //
    // All *THIS* driver needs to do is to delete the allocated memory objects,
    // the device object and the
    // symbolic link between our device name and the Win32 visible name.
    //
    // Almost every other driver ever witten would need to do a
    // significant amount of work here deallocating stuff.
    //

    KdPrint( ("%s: Unloading!!\n",   DBG_MSG_HDR) );

    //
    // Disconnect the interrupt
    //
 //  IoDisconnectInterrupt(extension->InterruptObject);

//
// A PRODUCT DRIVER WOULD REPORT  RESOURCE USAGE HERE
//


    //
    // Create counted string version of our Win32 device name.
    //

    RtlInitUnicodeString( &uniDosNameString, DOS_DEVICE_NAME );

    //
    // Delete the link from our device name to a name in the Win32 namespace.
    //

    IoDeleteSymbolicLink( &uniDosNameString );

    //
    // Finally delete our device object
    //

    IoDeleteDevice( driverObject->DeviceObject );
}
  
/****************************************************************************
    Function:
              LowerIRQLandDelay
    Arguments:

    Description:

				The StartIo routine is called at DISPATCH IRQL.   Polling for 
				status bit changes, in the simulated hardware status registers, 
				will not show changes in the status bits since the simpuator 
				program (IRQL PASSIVE) will not execute. This function lowwers 
				the IRQL from DISPATCH to PASSIVE and allow the simulator program 
				to execute.

				This function violates the assumptions of the NT Kernal 
				and  MUST NOT BE USED IN A PRODUCTION DRIVER. 

    Returns:


*****************************************************************************/
NTSTATUS LowerIRQLandDelay()
{
   KIRQL previousIRQL;
   KIRQL notNeeded;
   LARGE_INTEGER delay = {0, 2000};
   NTSTATUS status;

#define DELAY_IN_MS 200   

   delay = RtlConvertLongToLargeInteger( (LONG) (-1 * 10 * 1000 * DELAY_IN_MS));

   previousIRQL = KeGetCurrentIrql();
   if (previousIRQL != PASSIVE_LEVEL)
   { 
      /// THIS FUNCTION IS NOT LEGAL IN PRODUCTION CODE BUT WILL WORK WELL ENOUGH FOR THIS LAB
      KeLowerIrql(PASSIVE_LEVEL);
      status = KeDelayExecutionThread( KernelMode, FALSE, &delay);  // wait 200 ms
      KeRaiseIrql( previousIRQL,  &notNeeded);  
      ///THIS FUNCTION IS NOT LEGAL IN PRODUCTION CODE BUT WILL WORK WELL ENOUGH FOR THIS LAB         
   }
   else
   {
      status = KeDelayExecutionThread( KernelMode, FALSE, &delay);  // wait 200 ms
   }
 //  +++++++++++THIS FUNCTION IS NOT LEGAL IN PRODUCTION CODE BUT WILL WORK WELL ENOUGH FOR THIS LAB++++++++
  
   return status;
}

/****************************************************************************
    Function:
              LabSetupISR
    Arguments:

    Description:

    Returns:


*****************************************************************************/


#if 0
static NTSTATUS LabSetupISR(
        PDEVICE_OBJECT deviceObject,
        ULONG interruptLine )
        {
        PLAB2_DEVICE_EXTENSION deviceExtension;
        NTSTATUS                        ioConnectStatus;
        KIRQL                           Irql;
        ULONG                           MappedSysVect;

        deviceExtension = deviceObject->DeviceExtension;

        KdPrint(("%s  LabSetupISR - Started\n",        DBG_MSG_HDR));
        //
        // register DPC routine
        //
        IoInitializeDpcRequest(deviceObject, LabDpcRoutine);

        KdPrint(("%s  LabSetupISR - Initialize DPC Request\n", DBG_MSG_HDR));

        //-------------------------------------
        //Get a mapped vector for our interrupt
        //--------------------------------------


        deviceExtension->Vector  = interruptLine;
        deviceExtension->Level   = interruptLine;


        MappedSysVect = HalGetInterruptVector(Isa,
                                              0,                            // BusNumber,
                                              deviceExtension->Level,       // Level
                                              deviceExtension->Vector,      // Vector,
                                              &Irql,                        // IRQL
                                              &deviceExtension->Affinity);  // Affinity mask


        //
        // Initialize the spinlock
        //
        KeInitializeSpinLock( &deviceExtension->ISRSpinLock);


        DbgPrint("%s  LabSetupISR - Vector        = 0x%08x\n",   DBG_MSG_HDR, deviceExtension->Vector);
        DbgPrint("%s  LabSetupISR - Level         = 0x%08x\n\n", DBG_MSG_HDR, deviceExtension->Level);

        DbgPrint("%s  LabSetupISR - MappedSysVect = 0x%08x\n", DBG_MSG_HDR, MappedSysVect);
        DbgPrint("%s  LabSetupISR - IRQL          = 0x%08x\n", DBG_MSG_HDR, Irql);
        DbgPrint("%s  LabSetupISR - Affinity      = 0x%08x\n", DBG_MSG_HDR, deviceExtension->Affinity);



        //
        // connect the device driver to the IRQ
        //
//        ioConnectStatus = IoConnectInterrupt(
//                                             &deviceExtension->InterruptObject,
//                                             LabInterruptServiceRoutine,
//                                             deviceExtension,
//                                             &deviceExtension->ISRSpinLock,
//                                             MappedSysVect,
//                                             Irql,
//                                             Irql,
//                                             Latched,          //LevelSensitive,                              //  Interrupt is not LevelSensitive
//                                             FALSE,                                // Interrupt vector is sharable
//                                             deviceExtension->Affinity,
//                                             FALSE                                 // Save Floating Point stack on interrupt
//                                            );

//        if ( !NT_SUCCESS (ioConnectStatus) )
//                {
//                   KdPrint(("%s  LabSetupISR - IoConnectInterrupt Failed (0x%08x)\n",     DBG_MSG_HDR, ioConnectStatus));
//                }
//        else
//                {
//                   KdPrint(("%s  LabSetupISR - IoConnectInterrupt Passed\n",      DBG_MSG_HDR));
//                }
//        return ioConnectStatus;

          return STATUS_SUCCESS;
        }

#endif

/****************************************************************************
    Function:
              LabInterruptServiceRoutine
    Arguments:

    Description:

    Returns:


*****************************************************************************/
#if 0
BOOLEAN LabInterruptServiceRoutine(
    IN PKINTERRUPT Interrupt,
    IN OUT PVOID Context
    )

  {
    PLAB2_DEVICE_EXTENSION  deviceExtension = Context;
    PDEVICE_OBJECT    deviceObject = deviceExtension->DeviceObject;

//    DbgBreakPoint();

     /*
    * Look at our Interrupt Status Register...
    */
    DbgPrint("%s  InterruptServiceRoutine - Got one!\n",    DBG_MSG_HDR);


    /*
    * Make sure that we keep track of all Interrupts for future reference...
    */

    /*
    * Clear the Interrupt ASAP, or get out if it isn't us...
    */
    /*
    * restore the ISR mask Register to its original value
    */


    //
    // Note: the CurrentIrp field of the device object gets filled in
    // by IoStartPacket or IoStartNextPacket (which eventually leads
    // calling the drivers StartIo routine, which should lead to the
    // interrupt).
    //
    // If this interrupt was not the result of driver initiated I/O
    // then this field would not be accurate.
    //
    IoRequestDpc(deviceObject,
                 deviceObject->CurrentIrp,
                 NULL
                 );

    return TRUE;
}
#endif

/****************************************************************************
    Function:
              LabDPCRoutine
    Arguments:

    Description:

    Returns:


*****************************************************************************/
//
// This is the deferred procedure call that gets queued by the ISR to
// finish any interrupt relate processing
//
#if 0
VOID LabDpcRoutine(
    IN PKDPC Dpc,
    PDEVICE_OBJECT  deviceObject,
    IN PVOID SystemArgument1,
    IN PVOID SystemArgument2
    )
{

    PLAB2_DEVICE_EXTENSION        deviceExtension;
    PIRP                             Irp;

    Irp = deviceObject->CurrentIrp;

    deviceExtension = deviceObject->DeviceExtension;
    deviceExtension->InterruptCount++;

    if (Irp) {
        //
        // need to fill in this field to get the I/O manager to copy the data
        // back to user address space
        //
        Irp->IoStatus.Information = sizeof(LAB2_DATA_OUTPUT);

       // ?? size of data for pending IO completion

        Irp->IoStatus.Status = STATUS_SUCCESS;

        IoCompleteRequest(Irp, IO_NO_INCREMENT);
    }

    return;
}
#endif

/****************************************************************************
    Function:
              Macros for Simulator register access
    Arguments:

    Description:

    Returns:


*****************************************************************************/
#define IN_COMMAND      (0)
#define IN_STATUS       (1)
#define IN_DATA         (2)

#define OUT_COMMAND     (3)
#define OUT_STATUS      (4)
#define OUT_DATA        (5)


//
// Macros to test Status and command bits -- YOU MAY WANT MACROS TO SET COMMAND BITS AS WELL
//

#define IN_ERROR_STATE (READ_REGISTER_UCHAR(&extension->registerAddress[IN_STATUS]) & HELLO_STATUS_IN_MASK_ERR)
#define IN_OVERFLOW_STATE (IN_ERROR_STATE && (READ_REGISTER_UCHAR(&extension->registerAddress[IN_STATUS]) & HELLO_STATUS_IN_MASK_OVR))
#define IN_END_OF_PACKET_STATE (READ_REGISTER_UCHAR(&extension->registerAddress[IN_STATUS]) & HELLO_STATUS_IN_MASK_EOP)
#define IN_INTERRUPT_STATE (READ_REGISTER_UCHAR(&extension->registerAddress[IN_STATUS]) & HELLO_STATUS_IN_MASK_INT)
#define IN_DONE_STATE (READ_REGISTER_UCHAR(&extension->registerAddress[IN_STATUS]) & HELLO_STATUS_IN_MASK_DONE)

#define IN_GO_SET (READ_REGISTER_UCHAR(&extension->registerAddress[IN_COMMAND]) & HELLO_COMMAND_IN_MASK_GO)


#define OUT_ERROR_STATE (READ_REGISTER_UCHAR(&extension->registerAddress[OUT_STATUS]) & HELLO_STATUS_OUT_MASK_ERR)
#define OUT_UNDERFLOW_STATE (OUT_ERROR_STATE && (READ_REGISTER_UCHAR(&extension->registerAddress[OUT_STATUS]) & HELLO_STATUS_OUT_MASK_UND))
        
#define OUT_BUSY_STATE (READ_REGISTER_UCHAR(&extension->registerAddress[OUT_STATUS]) & HELLO_STATUS_OUT_MASK_BUSY)
#define OUT_INTERRUPT_STATE (READ_REGISTER_UCHAR(&extension->registerAddress[OUT_STATUS]) & HELLO_STATUS_OUT_MASK_INT)
#define OUT_DONE_STATE (READ_REGISTER_UCHAR(&extension->registerAddress[OUT_STATUS]) & HELLO_STATUS_OUT_MASK_DONE)

#define OUT_GO_SET (READ_REGISTER_UCHAR(&extension->registerAddress[OUT_COMMAND]) & HELLO_COMMAND_OUT_MASK_GO)

/****************************************************************************
    Function:
              Lab2GetPacket
    Arguments:

    Description:

    Returns:


*****************************************************************************/
NTSTATUS Lab2GetPacket(  
                        PDEVICE_OBJECT deviceObject,
                        UCHAR   *pBuffer,
                        ULONG   outBufferLength,
                        ULONG   *charCount)                         // RETURN transfer SIZE
{
    PLAB2_DEVICE_EXTENSION     extension = deviceObject->DeviceExtension;
      return STATUS_UNSUCCESSFUL ;   
}                   


/****************************************************************************
    Function:
              Lab2PutPacket
    Arguments:

    Description:

    Returns:


*****************************************************************************/
NTSTATUS Lab2PutPacket(  
                        PDEVICE_OBJECT deviceObject,
                        UCHAR   *pBuffer,
                        ULONG   inBufferLength,
                        ULONG   *charCount)                         // RETURN transfer SIZE
{
    PLAB2_DEVICE_EXTENSION     extension = deviceObject->DeviceExtension;

      *charCount =  count;
      return STATUS_UNSUCCESSFUL ;   
}                   

  







⌨️ 快捷键说明

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