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

📄 genport.c

📁 win2000下ISA接口的串口板卡的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
												deviceInfo,
												NULL,
												deviceInfo->InterruptVector,
												deviceInfo->InterruptLevel,
												deviceInfo->InterruptLevel,
												deviceInfo->InterruptMode,
												TRUE,
												deviceInfo->InterruptAffinity,
												FALSE);
					if (!NT_SUCCESS(status))
					{
						DebugPrint((">>>  IoConnectInterrupt Failed!\n"));
					}
					else
					{
						DebugPrint((">>>  IoConnectInterrupt Succeeded!\n"));
						deviceInfo->TestIsr = 0;
					}
				}
				deviceInfo->Started = TRUE;//原来的代码
				deviceInfo->Removed = FALSE;//原来的代码
				//初始化缓存
				df = (PLOCAL_DEVICE_INFO) deviceInfo->DeviceObject->DeviceExtension;
				DebugPrint((">>>Init Begin! deviceInfo = %X df = %X\n",deviceInfo,df));
				DebugPrint((">>>Init Begin! deviceInfo->DeviceObject = %X DeviceObject = %X\n",deviceInfo->DeviceObject,DeviceObject));
				for(j = 0;j < COM_NUM;j++)
				{
					deviceInfo->Inited[j] = FALSE;
					DebugPrint((">>>deviceInfo->Inited[%d] = %d\n",j,deviceInfo->Inited[j]));
					for(i = 0;i < 2;i++)
					{
						KeInitializeSemaphore(&deviceInfo->BufSemaphore[i][j], 1, 1);
						status = BufInit(&deviceInfo->Buf[i][j] );
						if (!NT_SUCCESS(status))
						{
							DebugPrint((">>>i=%d j=%d BufInit Failed!\n",i,j));
						}
						else
						{
							DebugPrint((">>>i=%d j=%d  BufInit Succeeded! Size = %d\n",i,j,deviceInfo->Buf[i][j].MaxSize));
						}
					}
				}
				//启动定时器
				KeInitializeTimer(&deviceInfo->RecTimer);
				DebugPrint((">>>KeInitializeTimer Succeeded!\n"));
				KeInitializeDpc(&deviceInfo->RecDPC, DpcForRec, DeviceObject);
				DebugPrint((">>>KeInitializeDpc Succeeded!\n"));
				//其它定义
				deviceInfo->CallDpcForRecCount = 0;
				//增加结束
            }
			else
			{
				DebugPrint((">>>  GpdStartDevice Failed!\n"));
			}
        }
        //
        // 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;
        }
        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;

			//我增加的代码
			//IoDisconnectInterrupt(,,,);
			if(deviceInfo->FoundInterrupt )
			{
				IoDisconnectInterrupt(deviceInfo->InterruptObject);
				DebugPrint((">>>  IoDisconnectInterrupt Finished!\n"));
			}
			

//			KeCancelTimer(&deviceInfo->RecTimer);
			DebugPrint((">>>  KeCancelTimer Finished!\n"));
			for(j = 0;j < COM_NUM;j++)
			{
				deviceInfo->Inited[j] = FALSE;
			}
			//增加结束

            if (deviceInfo->PortWasMapped)
            {
                MmUnmapIoSpace(deviceInfo->PortBase, deviceInfo->PortCount);
                deviceInfo->PortWasMapped = FALSE;
            }
            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:
        DebugPrint((">>> IRP_MN_STOP_DEVICE\n"));
        // 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
    )
/*++

Routine Description:
    
    Get the resources, map the resources if required
    and initialize the device.    

Arguments:
    
   DeviceObject - pointer to a device object.

   Irp - pointer to an I/O Request Packet.
   
Return Value:

    NT status code
    

--*/
{
    NTSTATUS    status = STATUS_SUCCESS;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR resource;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR resourceTrans;
    PCM_PARTIAL_RESOURCE_LIST   partialResourceList;
    PCM_PARTIAL_RESOURCE_LIST   partialResourceListTranslated;
    PIO_STACK_LOCATION  stack;
    ULONG i,k;
    PLOCAL_DEVICE_INFO deviceInfo;
    DebugPrint (("-- Entered GpdStartDevice\n"));

    deviceInfo = (PLOCAL_DEVICE_INFO) DeviceObject->DeviceExtension;

    stack = IoGetCurrentIrpStackLocation (Irp);

    PAGED_CODE();//确保Irp操作所在的级别

    //
    // We need to check that we haven't received a surprise removal
    //

    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 == stack->Parameters.StartDevice.AllocatedResources) &&
        (NULL == stack->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.
    //

    partialResourceList = 
    &stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList;
	DebugPrint((">>> partialResourceList->count = %d\n",partialResourceList->Count));
    resource = &partialResourceList->PartialDescriptors[0];
    DebugPrint((">>>   resource->Type = %d\n", 
        resource->Type));
    DebugPrint((">>>   Resource Port: (%x) Length: (%d)\n", 
        resource->u.Port.Start.LowPart, 
        resource->u.Port.Length));
   
    //
    // Parameters.StartDevice.AllocatedResourcesTranslated points 
    // to a CM_RESOURCE_LIST describing the hardware resources that 
    // the PnP Manager assigned to the device. This list contains 
    // the resources in translated form. Use the translated resources 
    // to connect the interrupt vector, map I/O space, and map memory.
    //

    partialResourceListTranslated = 
    &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;

    resourceTrans = &partialResourceListTranslated->PartialDescriptors[0];

    for (i = 0;
            i < partialResourceList->Count; i++, resource++, resourceTrans++) {

        switch (resource->Type) {
        case CmResourceTypePort:

            switch (resourceTrans->Type) {

            case CmResourceTypePort:

                deviceInfo->PortWasMapped = FALSE;
                deviceInfo->PortBase = (PVOID)(resourceTrans->u.Port.Start.LowPart);
                deviceInfo->PortCount       = resourceTrans->u.Port.Length;
				for(k = 0;k < COM_NUM;k++)
				{
 					deviceInfo->ComBase[k] = (PVOID)((ULONG)deviceInfo->PortBase + (ULONG)0x08*k);
				   DebugPrint(("deviceInfo->ComBase[%d]: (%x)\n", k,deviceInfo->ComBase[k]));
				}
               DebugPrint((">>>   resourceTrans->Type = %d\n", 
                    CmResourceTypePort));
                DebugPrint(("Resource Translated Port: (%x) Length: (%d)\n", 
                    resourceTrans->u.Port.Start.LowPart, 
                    resourceTrans->u.Port.Length));
                DebugPrint(("deviceInfo->PortBase: (%x) Length: (%d)\n", 
                    deviceInfo->PortBase, 
                    deviceInfo->PortCount));
 
                break;

            case CmResourceTypeMemory:

                //
                // We need to map the memory
                //

                deviceInfo->PortBase = (PVOID)
                    MmMapIoSpace (resourceTrans->u.Memory.Start,
                                  resourceTrans->u.Memory.Length,
                                  MmNonCached);

                deviceInfo->PortCount = resourceTrans->u.Memory.Length;
                deviceInfo->PortWasMapped = TRUE;

                DebugPrint(("Resource Translated Memory: (%x) Length: (%d)\n", 
                    resourceTrans->u.Memory.Start.LowPart, 
                    resourceTrans->u.Memory.Length));

                break;

            default:
                DebugPrint(("Unhandled resource_type (0x%x)\n", resourceTrans->Type));
                status = STATUS_UNSUCCESSFUL;
                TRAP ();
            }             
            break;

        case CmResourceTypeMemory:

            deviceInfo->PortBase = (PVOID)
                MmMapIoSpace (resourceTrans->u.Memory.Start,
                              resourceTrans->u.Memory.Length,
                              MmNonCached);

            deviceInfo->PortCount = resourceTrans->u.Memory.Length;
            deviceInfo->PortWasMapped = TRUE;

            DebugPrint(("Resource Translated Memory: (%x) Length: (%d)\n", 
                resourceTrans->u.Memory.Start.LowPart, 
                resourceTrans->u.Memory.Length));

            break;

        case CmResourceTypeInterrupt:
			//我自己增加的代码
            deviceInfo->FoundInterrupt       = TRUE;
            deviceInfo->InterruptLevel       = (KIRQL)resourceTrans->u.Interrupt.Level;
            deviceInfo->InterruptVector      = resourceTrans->u.Interrupt.Vector;
            deviceInfo->InterruptAffinity    = resourceTrans->u.Interrupt.Affinity;
			
			DebugPrint((">>> InterruptLevel = %d \n",deviceInfo->InterruptLevel));
			DebugPrint((">>> InterruptVector = %d \n",deviceInfo->InterruptVector));
            
            if (resourceTrans->Flags & CM_RESOURCE_INTERRUPT_LATCHED) {
                
                deviceInfo->InterruptMode = Latched;
				DebugPrint((">>> InterruptMode = Latched \n"));
            } else {
                
                deviceInfo->InterruptMode = LevelSensitive;
				DebugPrint((">>> InterruptMode = LevelSensitive \n"));
            }
			break;
			//增加结束
        default:

            DebugPrint(("Unhandled resource type (0x%x)\n", resource->Type));
            status = STATUS_UNSUCCESSFUL;
            break;
    
        } // end of switch
    } // end of for

    return status;

}


NTSTATUS

⌨️ 快捷键说明

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