阅读:2222回复:2
极度郁闷,有关2000下epp数据采集挂接中断
为了将本人开发驱动程序的水平升级到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 如果有高手伸出援手,感激不尽!!! |
|
沙发#
发布于:2002-06-28 05:44
瓦赛,这么多代码,我看的也是非常之郁闷,下次时间充裕了再好好看吧,呵呵。
|
|
板凳#
发布于:2002-07-23 13:00
你是不是直接拿到2000下用,没改成WDM的框架
|
|