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

📄 genport.c

📁 win2000下
💻 C
📖 第 1 页 / 共 5 页
字号:
			}
			deviceInfo->ComBase [i] = (PVOID)((ULONG)deviceInfo->PortBase + (ULONG)COMBASE_PORT[i]);
			deviceInfo->Inited [i] = FALSE;
		}
		//结束
    } else {

        ASSERT(addressSpace == 0x01);

#if DBG
        DbgPrint("Address space is port\n");
#endif
        //
        // Port I/O space is only 16 bits long, so we can grab the low 32 bits
        // of the address only.
        //
        deviceInfo->PortBase = (PULONG)address.LowPart;
		deviceInfo->PortCount = portLength;
    }
	deviceInfo->Started = TRUE;//原来的代码
	deviceInfo->Removed = FALSE;//原来的代码    
	//---------------查找PCI分配的954IO地址   结束
 
/////////////////////////////////////////////////////////////////////////////
    return STATUS_SUCCESS;
}


NTSTATUS
GpdAddDevice(
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT PhysicalDeviceObject
    )
/*++

Routine Description:

    The Plug & Play subsystem is handing us a brand new PDO, for which we
    (by means of INF registration) have been asked to provide a driver.

    We need to determine if we need to be in the driver stack for the device.
    Create a functional device object to attach to the stack
    Initialize that device object
    Return status success.

    Remember: we can NOT actually send ANY non pnp IRPS to the given driver
    stack, UNTIL we have received an IRP_MN_START_DEVICE.

Arguments:

    DeviceObject - pointer to a device object.

    PhysicalDeviceObject -  pointer to a device object created by the
                            underlying bus driver.

Return Value:

    NT status code.

--*/
{
    NTSTATUS                status = STATUS_SUCCESS;
    PDEVICE_OBJECT          deviceObject = NULL;
    PLOCAL_DEVICE_INFO      deviceInfo; 
    UNICODE_STRING          ntDeviceName;
    UNICODE_STRING          win32DeviceName;

    DebugPrint (("-- Entered GpdAddDevice\n"));

    PAGED_CODE();

    RtlInitUnicodeString(&ntDeviceName, GPD_DEVICE_NAME);       //GPD_DEVICE_NAME 就是宏定义 L"\\Device\\Gpd0"
	DebugPrint((">>> ntDeviceName.len=%d Buffer=%s\n"
		,ntDeviceName.Length
		,ntDeviceName.Buffer));
    //
    // Create a device object.
    //

    status = IoCreateDevice (DriverObject,
                             sizeof (LOCAL_DEVICE_INFO),
                             &ntDeviceName,
                             GPD_TYPE,
                             0,
                             FALSE,
                             &deviceObject);//分配内存并初始化一个设备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);//#define DOS_DEVICE_NAME L"\\DosDevices\\GpdDev"
	DebugPrint((">>> win32DeviceName.Buffer=%s \n",win32DeviceName.Buffer));

    status = IoCreateSymbolicLink( &win32DeviceName, &ntDeviceName );//在设备和用户可见设备名之间建立连接

    if (!NT_SUCCESS(status))    // If we we couldn't create the link then
    {                           //  abort installation.
        IoDeleteDevice(deviceObject);
        return status;
    }

    deviceInfo = (PLOCAL_DEVICE_INFO) deviceObject->DeviceExtension;//提取设备信息(包括地址:地址范围等)
	DebugPrint((">>> PortAddr=%X PortCount=%d\n",
		(unsigned int)deviceInfo->PortBase ,
		deviceInfo->PortCount ));
	DebugPrint((">>> PortMemyType=%d \n",
		(unsigned int)deviceInfo->PortMemoryType   ));
    deviceInfo->NextLowerDriver = IoAttachDeviceToDeviceStack (//把deviceObject 附属到 物理设备PhysicalDeviceObject上
                                       deviceObject,
                                       PhysicalDeviceObject);//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;

    deviceInfo->DeviceObject = deviceObject;//deviceInfo就是我们自己定义的设备参数(地址,地址空间等)
    deviceInfo->Removed = FALSE;
    deviceInfo->Started = FALSE;

    deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
//	deviceObject->Flags |= DO_BUFFERED_IO;
    //
    // This values is based on the hardware design.
    // Let us assume the address is in I/O space. 
    //
    deviceInfo->PortMemoryType = 0;//存贮器访问 20060216 

    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
    )
/*++

Routine Description:

    The completion routine for plug & play irps that needs to be
    processed first by the lower drivers. 

Arguments:

   DeviceObject - pointer to a device object.   

   Irp - pointer to an I/O Request Packet.

   Context - pointer to an event object.

Return Value:

      NT status code

--*/
{
    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
    )
/*++

Routine Description:

    The plug and play dispatch routines.

    Most of these the driver will completely ignore.
    In all cases it must pass the IRP to the next lower driver.

Arguments:

   DeviceObject - pointer to a device object.

   Irp - pointer to an I/O Request Packet.

Return Value:

      NT status code

--*/
{
    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;//原来的代码
				//我增加的代码
				//IoConnectInterrupt(,,,);
/*				status = IoConnectInterrupt(&deviceInfo->InterruptObject,
											GpdInterruptService,
											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->Started = TRUE;//原来的代码
					deviceInfo->Removed = FALSE;//原来的代码
					deviceInfo->TestIsr = 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:

⌨️ 快捷键说明

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