workman2002
驱动牛犊
驱动牛犊
  • 注册日期2002-06-04
  • 最后登录2002-10-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2222回复:2

极度郁闷,有关2000下epp数据采集挂接中断

楼主#
更多 发布于:2002-06-14 22:00
为了将本人开发驱动程序的水平升级到2000下,我将以前开发的nt4下的运行良好的数据采集驱动程序改造成了2000下的驱动,没想到竟然怎么也不能响应中断,经查中断挂接没有问题,端口分配也没有问题,就是不能响应中断,请教高手加以指点,是2000的问题(我没有安装sp2),还是我的程序存在缺陷?急救!!!SOS!!!提供源码供分析。
.inf文件如下:

[Version]
Signature=\"$WINDOWS NT$\"
Class=Sample
ClassGuid={8D900B83-2261-4684-8928-FF8C26FB7CE0}
Provider=%MSFT%
DriverVer=06/16/1999,5.00.2072

[DestinationDirs]
DefaultDestDir = 12

; ================= Class section =====================

[ClassInstall32]
Addreg=SampleClassReg    

[SampleClassReg]
HKR,,,0,%ClassName%
HKR,,Icon,,-5

; ================= Device Install section =====================

[Manufacturer]
%MSFT%=MSFT

[SourceDisksFiles]
genport.sys=1

[SourceDisksNames]
1=%DISK_NAME%,

[MSFT]
; DisplayName            Section           DeviceId
; -----------       -------           --------
%PortIO.DRVDESC%=PortIO_Inst,root\\portio

[PortIO_Inst.NT]
CopyFiles=PortIO.CopyFiles
LogConfig=PortIO.LC0, PortIO.LC1

[PortIO.CopyFiles]
genport.sys

[PortIO_Inst.NT.Services]
AddService=portio,0x00000002,PortIO_Service

;Uncomment following lines if your device can only work with factory default settings
;[PortIO.NT.FactDef]
;ConfigPriority=HARDRECONFIG
;IOConfig=300-303(3ff::)  ; 10 bit decode ranging from 300 - 303

[PortIO.LC0]
ConfigPriority=DESIRED
IOConfig=378-37F
IRQConfig=7

[PortIO.LC1]
ConfigPriority=NORMAL
IOConfig=278-27F
IRQConfig=7

[PortIO_Service]
DisplayName    = %PortIO.SVCDESC%                            
ServiceType    = 1                  ; SERVICE_KERNEL_DRIVER
StartType      = 3                  ; SERVICE_DEMAND_START
ErrorControl   = 1                  ; SERVICE_ERROR_NORMAL
ServiceBinary  = %12%\\genport.sys                            

[Strings]
MSFT = \"Microsoft\"
ClassName = \"Sample Drivers\"
PortIO.SVCDESC = \"Sample PortIO Service\"
PortIO.DRVDESC = \"Sample PortIO Driver\"
DISK_NAME = \"Portio Sample Install Disk\"

头文件如下:

#include <ntddk.h>

#if     !defined(__GENPORT_H__)
#define __GENPORT_H__

#define GPD_DEVICE_NAME L\"\\\\Device\\\\Gpd0\"

#define DOS_DEVICE_NAME L\"\\\\DosDevices\\\\GpdDev\"

#define PORTIO_TAG \'TROP\'

#define PORT_A 2
#define PORT_B 3
#define PORT_C 4

#define EPP_TYPE   40000
#define IOCTL_EPP_INIT CTL_CODE(EPP_TYPE, 3, METHOD_BUFFERED, FILE_ANY_ACCESS)

ULONG TestPortBase;
ULONG TestPortCount;
KIRQL TestIRQL;
UCHAR TestReceiveData[9];
ULONG TestBufferLen;
NTSTATUS TestStatus;
// driver local data structure specific to each device object
typedef struct _LOCAL_DEVICE_INFO {
PUCHAR              PortBase;       // base port address
ULONG               PortCount;      // Count of I/O addresses used.
ULONG               PortMemoryType; // HalTranslateBusAddress MemoryType
PDEVICE_OBJECT      DeviceObject;   // The Gpd device object.
PDEVICE_OBJECT      NextLowerDriver;     // The top of the stack
BOOLEAN             Started;
BOOLEAN             Removed;
BOOLEAN             PortWasMapped;  // If TRUE, we have to unmap on unload  
BOOLEAN             Filler[1]; //bug fix
IO_REMOVE_LOCK      RemoveLock;

KIRQL IRQL; // Irq for parallel port
ULONG Vector;
KAFFINITY Affinity;
PKINTERRUPT pIntObj; // the interrupt object
BOOLEAN     GotInterrupt;

UCHAR ReceiveData[9];
} LOCAL_DEVICE_INFO, *PLOCAL_DEVICE_INFO;


#if DBG
#define DebugPrint(_x_) \\
               DbgPrint (\"PortIo:\"); \\
               DbgPrint _x_;

#define TRAP() DbgBreakPoint()

#else
#define DebugPrint(_x_)
#define TRAP()
#endif


/********************* function prototypes ***********************************/
//

NTSTATUS    
DriverEntry(      
    IN  PDRIVER_OBJECT DriverObject,
    IN  PUNICODE_STRING RegistryPath
    );


NTSTATUS    
GpdDispatch(      
    IN  PDEVICE_OBJECT pDO,
    IN  PIRP pIrp                    
    );

void        
GpdUnload(        
    IN  PDRIVER_OBJECT DriverObject
    );


NTSTATUS
GpdAddDevice(
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT PhysicalDeviceObject
    );


NTSTATUS
GpdDispatchPnp (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    );

NTSTATUS
GpdStartDevice (
    IN PDEVICE_OBJECT    DeviceObject,
    IN PIRP             Irp
    );

NTSTATUS
GpdDispatchPower(
    IN PDEVICE_OBJECT    DeviceObject,
    IN PIRP              Irp
    );
NTSTATUS
GpdDispatchSystemControl(
    IN PDEVICE_OBJECT    DeviceObject,
    IN PIRP              Irp
    );
PCHAR
PnPMinorFunctionString (
    UCHAR MinorFunction
);
BOOLEAN Isr (
IN PKINTERRUPT pIntObj,
IN PVOID pServiceContext
);
VOID DpcForIsr(
IN PKDPC pDpc,
IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp,
IN PVOID pContext
);
void GpdCancel(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
VOID GpdStartIo(
IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp
);
NTSTATUS
GpdRead(
        IN PDEVICE_OBJECT DeviceObject,
        IN PIRP Irp);
#endif


源程序如下:

#include \"genport.h\"


NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT  DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
{

    UNREFERENCED_PARAMETER (RegistryPath);

    DebugPrint ((\"Entered Driver Entry\\n\"));
    
    
    DriverObject->MajorFunction[IRP_MJ_CREATE]          = GpdDispatch;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]           = GpdDispatch;
    DriverObject->MajorFunction[IRP_MJ_READ] = GpdRead;    
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]  = GpdDispatch;
    DriverObject->DriverUnload                          = GpdUnload;
    DriverObject->MajorFunction[IRP_MJ_PNP]           = GpdDispatchPnp;
    DriverObject->MajorFunction[IRP_MJ_POWER]           = GpdDispatchPower;
    DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = GpdDispatchSystemControl;
    DriverObject->DriverExtension->AddDevice           = GpdAddDevice;
    DriverObject->DriverStartIo = GpdStartIo;

    return STATUS_SUCCESS;
}


NTSTATUS
GpdAddDevice(
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT PhysicalDeviceObject
    )
{
    NTSTATUS                status = STATUS_SUCCESS;
    PDEVICE_OBJECT          deviceObject = NULL;
    PLOCAL_DEVICE_INFO      deviceInfo;
    UNICODE_STRING          ntDeviceName;
    UNICODE_STRING          win32DeviceName;

//    PAGED_CODE();

    RtlInitUnicodeString(&ntDeviceName, GPD_DEVICE_NAME);

    //
    // Create a device object.
    //

    status = IoCreateDevice (DriverObject,
                             sizeof (LOCAL_DEVICE_INFO),
                             &ntDeviceName,
                             EPP_TYPE,
                             0,
                             FALSE,
                             &deviceObject);

    
    if (!NT_SUCCESS (status)) {
        //
        // Either not enough memory to create a deviceobject or another
        // deviceobject with the same name exits. This could happen
        // if you install another instance of this device.
        //
        return status;
    }

    RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);

    status = IoCreateSymbolicLink( &win32DeviceName, &ntDeviceName );

    if (!NT_SUCCESS(status))    // If we we couldn\'t create the link then
    {                           //  abort installation.
        IoDeleteDevice(deviceObject);
        return status;
    }
// We need a DpcForIsr registration
    IoInitializeDpcRequest( deviceObject, DpcForIsr );

    deviceInfo = (PLOCAL_DEVICE_INFO) deviceObject->DeviceExtension;
    
    deviceInfo->NextLowerDriver = IoAttachDeviceToDeviceStack (
                                       deviceObject,
                                       PhysicalDeviceObject);
    if(NULL == deviceInfo->NextLowerDriver) {
        IoDeleteSymbolicLink(&win32DeviceName);
        IoDeleteDevice(deviceObject);
        return STATUS_NO_SUCH_DEVICE;
    }

    IoInitializeRemoveLock (&deviceInfo->RemoveLock ,
                            PORTIO_TAG,
                            1, // MaxLockedMinutes
                            5); // HighWatermark, this parameter is
                                // used only on checked build.
    //
    // Set the flag if the device is not holding a pagefile
    // crashdump file or hibernate file.
    //
    
//    deviceObject->Flags |=  DO_POWER_PAGABLE;
    deviceObject->Flags |= DO_BUFFERED_IO;
    deviceInfo->DeviceObject = deviceObject;
    deviceInfo->Removed = FALSE;
    deviceInfo->Started = FALSE;
    deviceInfo->pIntObj = NULL;
    deviceInfo->GotInterrupt = FALSE;
    deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

    //
    // This values is based on the hardware design.
    // Let us assume the address is in I/O space.
    //
//    deviceInfo->PortMemoryType = 1;

    DebugPrint((\"AddDevice: %p to %p->%p \\n\", deviceObject,
                       deviceInfo->NextLowerDriver,
                       PhysicalDeviceObject));


    return STATUS_SUCCESS;

}

NTSTATUS
GpdCompletionRoutine(
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP             Irp,
    IN PVOID            Context
    )

{
    PKEVENT             event;

    event = (PKEVENT) Context;

    UNREFERENCED_PARAMETER(DeviceObject);

    if (Irp->PendingReturned) {
        IoMarkIrpPending(Irp);
    }

    //
    // We could switch on the major and minor functions of the IRP to perform
    // different functions, but we know that Context is an event that needs
    // to be set.
    //
    KeSetEvent(event, 0, FALSE);

    //
    // Allows the caller to reuse the IRP
    //
    return STATUS_MORE_PROCESSING_REQUIRED;
}


NTSTATUS
GpdDispatchPnp (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )

{
    PIO_STACK_LOCATION          irpStack;
    NTSTATUS                    status = STATUS_SUCCESS;
    KEVENT                      event;        
    UNICODE_STRING              win32DeviceName;
    PLOCAL_DEVICE_INFO          deviceInfo;
 
    PAGED_CODE();

    deviceInfo = (PLOCAL_DEVICE_INFO) DeviceObject->DeviceExtension;
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    status = IoAcquireRemoveLock (&deviceInfo->RemoveLock, Irp);
    if (!NT_SUCCESS (status)) {
        Irp->IoStatus.Status = status;
        IoCompleteRequest (Irp, IO_NO_INCREMENT);
        return status;
    }

    DebugPrint((\"%s\\n\",PnPMinorFunctionString(irpStack->MinorFunction)));

    switch (irpStack->MinorFunction) {
    case IRP_MN_START_DEVICE:

        //
        // The device is starting.
        //
        // We cannot touch the device (send it any non pnp irps) until a
        // start device has been passed down to the lower drivers.
        //
        IoCopyCurrentIrpStackLocationToNext(Irp);
        KeInitializeEvent(&event,
                          NotificationEvent,
                          FALSE
                          );

        IoSetCompletionRoutine(Irp,
                               (PIO_COMPLETION_ROUTINE) GpdCompletionRoutine,
                               &event,
                               TRUE,
                               TRUE,
                               TRUE);
                              
        status = IoCallDriver(deviceInfo->NextLowerDriver, Irp);

        if (STATUS_PENDING == status) {
            KeWaitForSingleObject(
               &event,
               Executive, // Waiting for reason of a driver
               KernelMode, // Must be kernelmode if event memory is in stack
               FALSE, // No allert
               NULL); // No timeout
        }

        if (NT_SUCCESS(status) && NT_SUCCESS(Irp->IoStatus.Status)) {

            status = GpdStartDevice(DeviceObject, Irp);
            if(NT_SUCCESS(status))
            {
                //
                // As we are successfully now back from our start device
                // we can do work.
                //
                
                deviceInfo->Started = TRUE;
                deviceInfo->Removed = FALSE;
            }
        }

        //
        // We must now complete the IRP, since we stopped it in the
        // completion routine with STATUS_MORE_PROCESSING_REQUIRED.
        //
        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        break;

    case IRP_MN_QUERY_STOP_DEVICE:

        //
        // Fail the query stop to prevent the system from taking away hardware
        // resources. If you do support this you must have a queue to hold
        // incoming requests between stop and subsequent start with new set of
        // resources.
        //
        
        Irp->IoStatus.Status = status = STATUS_UNSUCCESSFUL;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        break;
        
    case IRP_MN_QUERY_REMOVE_DEVICE:
        //
        // The device can be removed without disrupting the machine.
        //
        Irp->IoStatus.Status = STATUS_SUCCESS;
        IoSkipCurrentIrpStackLocation(Irp);
        status = IoCallDriver(deviceInfo->NextLowerDriver, Irp);
        break;

    case IRP_MN_SURPRISE_REMOVAL:

        //
        // The device has been unexpectedly removed from the machine
        // and is no longer available for I/O. Stop all access to the device.
        // Release any resources associated with the device, but leave the
        // device object attached to the device stack until the PnP Manager
        // sends a subsequent IRP_MN_REMOVE_DEVICE request.
        // You should fail any outstanding I/O to the device. You will
        // not get a remove until all the handles open to the device
        // have been closed.
        //

        deviceInfo->Removed = TRUE;
        deviceInfo->Started = FALSE;
      
        if (deviceInfo->PortWasMapped)
        {
            MmUnmapIoSpace(deviceInfo->PortBase, deviceInfo->PortCount);
            deviceInfo->PortWasMapped = FALSE;
        }
            if (deviceInfo->GotInterrupt)
            {
                IoDisconnectInterrupt(deviceInfo->pIntObj);
   }
         RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);
        IoDeleteSymbolicLink(&win32DeviceName);          
        
        IoSkipCurrentIrpStackLocation(Irp);
        Irp->IoStatus.Status = STATUS_SUCCESS;
        status = IoCallDriver(deviceInfo->NextLowerDriver, Irp);
        break;      
        
    case IRP_MN_REMOVE_DEVICE:

        //
        // Relinquish all resources here.
        // Detach and delete the device object so that
        // your driver can be unloaded. You get remove
        // either after query_remove or surprise_remove.
        //

        if(!deviceInfo->Removed)
        {
            deviceInfo->Removed = TRUE;
            deviceInfo->Started = FALSE;

            if (deviceInfo->PortWasMapped)
            {
                MmUnmapIoSpace(deviceInfo->PortBase, deviceInfo->PortCount);
                deviceInfo->PortWasMapped = FALSE;
            }
            if (deviceInfo->GotInterrupt)
            {
                IoDisconnectInterrupt(deviceInfo->pIntObj);
   }
            RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);
            IoDeleteSymbolicLink(&win32DeviceName);          
        }        

        //
        // Wait for all outstanding requests to complete
        //
        DebugPrint((\"Waiting for outstanding requests\\n\"));
        IoReleaseRemoveLockAndWait(&deviceInfo->RemoveLock, Irp);

        Irp->IoStatus.Status = STATUS_SUCCESS;
        IoSkipCurrentIrpStackLocation(Irp);
        status = IoCallDriver(deviceInfo->NextLowerDriver, Irp);

        IoDetachDevice(deviceInfo->NextLowerDriver);
        IoDeleteDevice(DeviceObject);
        
        return status;
                
    case IRP_MN_STOP_DEVICE:
        // Since you failed query stop, you will not get this request.
    case IRP_MN_CANCEL_REMOVE_DEVICE:
        // No action required in this case. Just pass it down.
    case IRP_MN_CANCEL_STOP_DEVICE:
        //No action required in this case.
        Irp->IoStatus.Status = STATUS_SUCCESS;
    default:
        //
        // Please see PnP documentation for use of these IRPs.
        //
        IoSkipCurrentIrpStackLocation (Irp);
        status = IoCallDriver(deviceInfo->NextLowerDriver, Irp);
        break;
    }
    IoReleaseRemoveLock(&deviceInfo->RemoveLock, Irp);      
    return status;
}

NTSTATUS
GpdStartDevice (
    IN PDEVICE_OBJECT    DeviceObject,
    IN PIRP             Irp
    )
{
PCM_RESOURCE_LIST pResourceList;
PCM_FULL_RESOURCE_DESCRIPTOR pFullDescriptor;
PCM_PARTIAL_RESOURCE_LIST pPartialList;
PCM_PARTIAL_RESOURCE_DESCRIPTOR pPartialDescriptor;
     NTSTATUS     status;

PIO_STACK_LOCATION   pIrpStack;
     PLOCAL_DEVICE_INFO deviceInfo;
     ULONG i;
     UCHAR Str;


     deviceInfo = (PLOCAL_DEVICE_INFO) DeviceObject->DeviceExtension;
pIrpStack  = IoGetCurrentIrpStackLocation (Irp);

        KdPrint( (\"StartDevice \\n\") );

if (deviceInfo->Removed) {
//
// Some kind of surprise removal arrived. We will fail the IRP
// The dispatch routine that called us will take care of
// completing the IRP.
//
return STATUS_DELETE_PENDING;
}

    //
    // Do whatever initialization needed when starting the device:
    // gather information about it,  update the registry, etc.
    //

    if ((NULL == pIrpStack->Parameters.StartDevice.AllocatedResources) &&
        (NULL == pIrpStack->Parameters.StartDevice.AllocatedResourcesTranslated)) {

        return STATUS_INSUFFICIENT_RESOURCES;
    }
    //
    // Parameters.StartDevice.AllocatedResources points to a
    // CM_RESOURCE_LIST describing the hardware resources that
    // the PnP Manager assigned to the device. This list contains
    // the resources in raw form. Use the raw resources to program
    // the device.
    //

pResourceList = pIrpStack->Parameters.StartDevice.AllocatedResourcesTranslated;
pFullDescriptor =
pResourceList->List;
pPartialList =
&pFullDescriptor->PartialResourceList;
for (i=0; i<(int)pPartialList->Count; i++) {
pPartialDescriptor = &pPartialList->PartialDescriptors;
switch (pPartialDescriptor->Type) {
         case CmResourceTypeInterrupt:
deviceInfo->IRQL = (KIRQL)pPartialDescriptor->u.Interrupt.Level;
deviceInfo->Vector = pPartialDescriptor->u.Interrupt.Vector;
deviceInfo->Affinity = pPartialDescriptor->u.Interrupt.Affinity;
deviceInfo->GotInterrupt = TRUE;
       KdPrint( (\"IRQL Translated : %d Vector :%x Affinity :%x\\n\",
        deviceInfo->IRQL,deviceInfo->Vector,deviceInfo->Affinity) );
         break;
case CmResourceTypePort:
deviceInfo->PortBase  = (PUCHAR)pPartialDescriptor->u.Port.Start.LowPart;
               deviceInfo->PortCount = pPartialDescriptor->u.Port.Length;
                 DebugPrint((\"Resource Translated Port: (%x) Length: (%d)\\n\", pPartialDescriptor->u.Port.Start.LowPart, pPartialDescriptor->u.Port.Length));
               break;
       default:
DebugPrint((\"Unhandled resource type \\n\"));
             status = STATUS_UNSUCCESSFUL;
             break;
} // end of switch
     } // end of for
if (deviceInfo->IRQL == 0 || deviceInfo->PortBase == 0)
return STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT;
        Str=READ_PORT_UCHAR((PUCHAR)((ULONG)deviceInfo->PortBase+PORT_A))&0xef;
        WRITE_PORT_UCHAR((PUCHAR)((ULONG)deviceInfo->PortBase+PORT_A),Str);
// IoInitializeDpcRequest( DeviceObject, DpcForIsr );
        KdPrint( (\"Begin Connect Interrupt!\\n\") );
        if(deviceInfo->GotInterrupt)
        {
status = IoConnectInterrupt(
&deviceInfo->pIntObj, // the Interrupt object
Isr, // our ISR
deviceInfo, // Service Context
NULL, // no spin lock
deviceInfo->Vector, // vector
deviceInfo->IRQL, // DIRQL
deviceInfo->IRQL, // DIRQL
Latched, // Latched or LevelSensitive
FALSE, // Shared?
deviceInfo->Affinity, // processors in an MP set
FALSE ); // save FP registers?
TestStatus = status;
if(NT_SUCCESS(status))
{
KdPrint( (\"Connect Interrupt Over! Connect Status is %x\\n\",status) );
}
else
{
KdPrint((\"Connect Interrupt Over! But not connect successfully!\\n\"));
}
}

        KdPrint( (\"IoConnectInterrupt OK!\\n\") );

        Str=READ_PORT_UCHAR((PUCHAR)((ULONG)deviceInfo->PortBase+PORT_A))&0xef;
        WRITE_PORT_UCHAR((PUCHAR)((ULONG)deviceInfo->PortBase+PORT_A),Str);

    return status;

}


NTSTATUS
GpdDispatchPower(
    IN PDEVICE_OBJECT    DeviceObject,
    IN PIRP              Irp
    )
{
    PLOCAL_DEVICE_INFO   deviceInfo;
    
    deviceInfo = (PLOCAL_DEVICE_INFO) DeviceObject->DeviceExtension;

    //
    // If the device has been removed, the driver should not pass
    // the IRP down to the next lower driver.
    //
    
    if (deviceInfo->Removed) {
        
        PoStartNextPowerIrp(Irp);
        Irp->IoStatus.Status =  STATUS_DELETE_PENDING;
        IoCompleteRequest(Irp, IO_NO_INCREMENT );
        return STATUS_DELETE_PENDING;
    }
    
    PoStartNextPowerIrp(Irp);
    IoSkipCurrentIrpStackLocation(Irp);
    return PoCallDriver(deviceInfo->NextLowerDriver, Irp);
}

NTSTATUS
GpdDispatchSystemControl(
    IN PDEVICE_OBJECT    DeviceObject,
    IN PIRP              Irp
    )
{
    PLOCAL_DEVICE_INFO   deviceInfo;

    PAGED_CODE();

    deviceInfo = (PLOCAL_DEVICE_INFO) DeviceObject->DeviceExtension;
    IoSkipCurrentIrpStackLocation(Irp);
    return IoCallDriver(deviceInfo->NextLowerDriver, Irp);
}

    
VOID
GpdUnload(
    IN PDRIVER_OBJECT DriverObject
    )

{
    PAGED_CODE ();

    //
    // The device object(s) should be NULL now
    // (since we unload, all the devices objects associated with this
    // driver must have been deleted.
    //
    ASSERT(DriverObject->DeviceObject == NULL);
    
    DebugPrint ((\"unload\\n\"));

    return;
}

void GpdCancel(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{

        if(DeviceObject->CurrentIrp==Irp)
        {
                IoReleaseCancelSpinLock(Irp->CancelIrql);
                IoStartNextPacket(DeviceObject,TRUE);
        }
        else
        {
                KeRemoveEntryDeviceQueue(&DeviceObject->DeviceQueue,&Irp->Tail.Overlay.DeviceQueueEntry);
                IoReleaseCancelSpinLock(Irp->CancelIrql);
        }
        Irp->IoStatus.Status=STATUS_CANCELLED;
        Irp->IoStatus.Information=0;
        IoCompleteRequest(Irp,IO_NO_INCREMENT);
        return;
}
NTSTATUS GpdRead(
        IN PDEVICE_OBJECT DeviceObject,
        IN PIRP Irp)
{
        PIO_STACK_LOCATION      IrpStack;
        PLOCAL_DEVICE_INFO      Extension;
        ULONG BufferLen;

        IrpStack=IoGetCurrentIrpStackLocation(Irp);
        Extension=DeviceObject->DeviceExtension;

        BufferLen=IrpStack->Parameters.Read.Length;
        TestBufferLen=BufferLen;///////////////////////////////////////////
        if(BufferLen<9)
        {
                Irp->IoStatus.Status=STATUS_INVALID_PARAMETER;
                Irp->IoStatus.Information=0;
                return STATUS_INVALID_PARAMETER;
        }
        IoSetCancelRoutine(Irp,GpdCancel);
        IoMarkIrpPending(Irp);
        IoStartPacket(DeviceObject,Irp,NULL,GpdCancel);
        KdPrint( (\"ReadIrp \\n\") );

        return STATUS_PENDING;
}
NTSTATUS
GpdDispatch(
    IN    PDEVICE_OBJECT pDO,
    IN    PIRP pIrp            
    )
{
    PLOCAL_DEVICE_INFO pLDI;
    PIO_STACK_LOCATION pIrpStack;
    NTSTATUS Status;
    UCHAR Str;
    ULONG i;
    PAGED_CODE();

    pIrp->IoStatus.Information = 0;
    pLDI = (PLOCAL_DEVICE_INFO)pDO->DeviceExtension;    // Get local info struct

TestPortBase = (ULONG)pLDI->PortBase;
TestPortCount = (ULONG)pLDI->PortCount;
TestIRQL = pLDI->IRQL;
Status = TestStatus;


    DebugPrint ((\"Entered GpdDispatch\\n\"));

    Status = IoAcquireRemoveLock (&pLDI->RemoveLock, pIrp);
    if (!NT_SUCCESS (Status)) {
        pIrp->IoStatus.Information = 0;
        pIrp->IoStatus.Status = Status;
        IoCompleteRequest (pIrp, IO_NO_INCREMENT);
        return Status;
    }

    if (!pLDI->Started) {
        //
        // We fail all the IRPs that arrive before the device is started.
        //
        pIrp->IoStatus.Status = Status = STATUS_DEVICE_NOT_READY;
        IoCompleteRequest(pIrp, IO_NO_INCREMENT );
        IoReleaseRemoveLock(&pLDI->RemoveLock, pIrp);      
        return Status;
    }
    
    pIrpStack = IoGetCurrentIrpStackLocation(pIrp);

    // Dispatch based on major fcn code.

    switch (pIrpStack->MajorFunction)
    {
        case IRP_MJ_CREATE:
     Status = STATUS_SUCCESS;
                pIrp->IoStatus.Information=1;            
     break;
        case IRP_MJ_CLOSE:
            // We don\'t need any special processing on open/close so we\'ll
            // just return success.
    WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_A),(UCHAR)0x00);
WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_B),0x5b);
     WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_C),0x3a);
WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_B),0x5b);
     WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_C),0x7a);
WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_B),0x5b);
     WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_C),0xba);
     Status = STATUS_SUCCESS;
                pIrp->IoStatus.Information=1;            
            break;

        case IRP_MJ_DEVICE_CONTROL:
            //  Dispatch on IOCTL
            switch (pIrpStack->Parameters.DeviceIoControl.IoControlCode)
            {
            case IOCTL_EPP_INIT:
     DebugPrint ((\"Entered Init\\n\"));
                        for(i=0;i<5;i++)
                        {
                                READ_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+0));
                                READ_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+1));
                                READ_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+2));
                                READ_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+3));
                                READ_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+4));
                                READ_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+5));
                                READ_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+6));
                        }
               Str=READ_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_A))&0xef;
                 WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_A),Str);

                        WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_A),(UCHAR)0x04);
//////////////////////////////////////////////////////////////////
//                      Initialize RemoteBoard
//////////////////////////////////////////////////////////////////
                        WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_B),0x5b);
                        WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_C),0x34);
                        WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_B),0x58);
                        WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_C),0xd0);
                        WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_B),0x58);
                        WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_C),0x07);



                        WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_B),0x5b);
                        WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_C),0x76);
                        WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_B),0x59);
                        WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_C),0x32);
                        WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_B),0x59);
                        WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_C),0x00);


                        WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_B),0x5b);
                        WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_C),0xb2);
                        WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_B),0x5a);
                        WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_C),0x48);
                        WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_B),0x5a);
                        WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_C),0x00);


       Str=READ_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_A))|0x10;
                    WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_A),Str);

                        WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_B),0x5c);
                        WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_C),0x02);
                        
                 Str=READ_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_A))&0xef;
                 WRITE_PORT_UCHAR((PUCHAR)((ULONG)pLDI->PortBase+PORT_A),Str);

                        Status = STATUS_SUCCESS;
                        pIrp->IoStatus.Information=1;            
             break;
            default:      
                Status = STATUS_INVALID_PARAMETER;
            }
            break;
        default:
            Status = STATUS_NOT_IMPLEMENTED;
            break;
    }

    // We\'re done with I/O request.  Record the status of the I/O action.
    pIrp->IoStatus.Status = Status;

    // Don\'t boost priority when returning since this took little time.
    IoCompleteRequest(pIrp, IO_NO_INCREMENT );
    IoReleaseRemoveLock(&pLDI->RemoveLock, pIrp);      
    return Status;
}
VOID
GpdStartIo(
IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp
)
{
        PIO_STACK_LOCATION      ioStack;
        KIRQL                   cancelIrql;

        IoAcquireCancelSpinLock(&cancelIrql);
        if(pIrp->Cancel)
        {
                IoReleaseCancelSpinLock(cancelIrql);
                return;
        }
        return;
}

BOOLEAN Isr (
    IN PKINTERRUPT Interrupt,
    IN OUT PVOID Context)
{
        UCHAR   Str;
        ULONG   i;
        ULONG   Num=9;
        PDEVICE_OBJECT   DeviceObject =(PDEVICE_OBJECT)Context;
     PLOCAL_DEVICE_INFO      deviceInfo = DeviceObject->DeviceExtension;

       KdPrint( (\"ISR \\n\") );

        for(i=0;i<Num;i++)
        {
                WRITE_PORT_UCHAR((PUCHAR)((ULONG)deviceInfo->PortBase+PORT_B),0x58);
                deviceInfo->ReceiveData=READ_PORT_UCHAR((PUCHAR)((ULONG)deviceInfo->PortBase+PORT_C));
        }

        Str=READ_PORT_UCHAR((PUCHAR)((ULONG)deviceInfo->PortBase+PORT_A));
        Str=Str|0x10;
        WRITE_PORT_UCHAR((PUCHAR)((ULONG)deviceInfo->PortBase+PORT_A),Str);

WRITE_PORT_UCHAR((PUCHAR)((ULONG)deviceInfo->PortBase+PORT_B),0x5c);
        WRITE_PORT_UCHAR((PUCHAR)((ULONG)deviceInfo->PortBase+PORT_C),0x02);

if(DeviceObject->CurrentIrp)
    IoRequestDpc(DeviceObject,DeviceObject->CurrentIrp,NULL);

     return TRUE;
}
VOID
DpcForIsr(
IN PKDPC pDpc,
IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp,
IN PVOID pContext
)
{
PLOCAL_DEVICE_INFO      deviceInfo;
     PIO_STACK_LOCATION   IrpStack;
        KIRQL CancelIrql;
        ULONG                   Length;
        
deviceInfo = (PLOCAL_DEVICE_INFO)pContext;
pIrp->IoStatus.Status = STATUS_SUCCESS;
        IrpStack=IoGetCurrentIrpStackLocation(pIrp);
        if(!IrpStack)
                return;

        if(IrpStack->MajorFunction==IRP_MJ_READ)
        {
                IoAcquireCancelSpinLock(&CancelIrql);
                if(pIrp->Cancel)
                {
                        IoReleaseCancelSpinLock(CancelIrql);
                        return;
                }
                IoSetCancelRoutine(pIrp,NULL);
                IoReleaseCancelSpinLock(CancelIrql);
/////////////////////////////////////////////////////////////////////////
//// Should Add Return Parameter to App
/////////////////////////////////////////////////////////////////////////
                Length=IrpStack->Parameters.Read.Length;
                if(Length>9)
                        Length=9;
                RtlCopyMemory(pIrp->AssociatedIrp.SystemBuffer,deviceInfo->ReceiveData,Length);
                pIrp->IoStatus.Status=STATUS_SUCCESS;
                pIrp->IoStatus.Information=Length;
        }
        IoCompleteRequest(pIrp,IO_NO_INCREMENT);
//
// This one\'s done. Begin working on the next
//
IoStartNextPacket( pDevObj, FALSE );
}
#if DBG
PCHAR
PnPMinorFunctionString (
    UCHAR MinorFunction
)
{
    switch (MinorFunction)
    {
        case IRP_MN_START_DEVICE:
            return \"IRP_MN_START_DEVICE\";
        case IRP_MN_QUERY_REMOVE_DEVICE:
            return \"IRP_MN_QUERY_REMOVE_DEVICE\";
        case IRP_MN_REMOVE_DEVICE:
            return \"IRP_MN_REMOVE_DEVICE\";
        case IRP_MN_CANCEL_REMOVE_DEVICE:
            return \"IRP_MN_CANCEL_REMOVE_DEVICE\";
        case IRP_MN_STOP_DEVICE:
            return \"IRP_MN_STOP_DEVICE\";
        case IRP_MN_QUERY_STOP_DEVICE:
            return \"IRP_MN_QUERY_STOP_DEVICE\";
        case IRP_MN_CANCEL_STOP_DEVICE:
            return \"IRP_MN_CANCEL_STOP_DEVICE\";
        case IRP_MN_QUERY_DEVICE_RELATIONS:
            return \"IRP_MN_QUERY_DEVICE_RELATIONS\";
        case IRP_MN_QUERY_INTERFACE:
            return \"IRP_MN_QUERY_INTERFACE\";
        case IRP_MN_QUERY_CAPABILITIES:
            return \"IRP_MN_QUERY_CAPABILITIES\";
        case IRP_MN_QUERY_RESOURCES:
            return \"IRP_MN_QUERY_RESOURCES\";
        case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
            return \"IRP_MN_QUERY_RESOURCE_REQUIREMENTS\";
        case IRP_MN_QUERY_DEVICE_TEXT:
            return \"IRP_MN_QUERY_DEVICE_TEXT\";
        case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
            return \"IRP_MN_FILTER_RESOURCE_REQUIREMENTS\";
        case IRP_MN_READ_CONFIG:
            return \"IRP_MN_READ_CONFIG\";
        case IRP_MN_WRITE_CONFIG:
            return \"IRP_MN_WRITE_CONFIG\";
        case IRP_MN_EJECT:
            return \"IRP_MN_EJECT\";
        case IRP_MN_SET_LOCK:
            return \"IRP_MN_SET_LOCK\";
        case IRP_MN_QUERY_ID:
            return \"IRP_MN_QUERY_ID\";
        case IRP_MN_QUERY_PNP_DEVICE_STATE:
            return \"IRP_MN_QUERY_PNP_DEVICE_STATE\";
        case IRP_MN_QUERY_BUS_INFORMATION:
            return \"IRP_MN_QUERY_BUS_INFORMATION\";
        case IRP_MN_DEVICE_USAGE_NOTIFICATION:
            return \"IRP_MN_DEVICE_USAGE_NOTIFICATION\";
        case IRP_MN_SURPRISE_REMOVAL:
            return \"IRP_MN_SURPRISE_REMOVAL\";
            
        default:
            return \"IRP_MN_?????\";
    }
}

#endif


如果有高手伸出援手,感激不尽!!!
wuqix
驱动小牛
驱动小牛
  • 注册日期2001-03-23
  • 最后登录2008-06-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-06-28 05:44
瓦赛,这么多代码,我看的也是非常之郁闷,下次时间充裕了再好好看吧,呵呵。
Reehac
驱动牛犊
驱动牛犊
  • 注册日期2001-06-27
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-07-23 13:00
你是不是直接拿到2000下用,没改成WDM的框架
游客

返回顶部