阅读:1117回复:5
请问如何在内核态driver中读写201 I/O port
请问各位高手一个问题:
现在我要在内核态访问一个I/O port: 0x201 port. 我写了一个driver在内核driver中去读写0x201 port.原以为很容易.但我发现我在driver中无法从201 port中读到数据.我想可能是PnP没有给201 port分配资源.所以我的driver就无法访问这个端口设备(201 port). 以前我在应用程序中通过挂上一些Direct Io 之类的driver,可以很容易的在AP下访问任意的I/O .可是现在我在Dreiver中指定访问一个I/O port就这么难,我不知道该如何做,请问有没有人,做过在driver中访问读写一个以前遗留下来的I/O 的程序.为什么在AP下挂driver可以达到访问I/O port,而在内核态driver中直接读写一个I/O port却不行呢? 如果PnP没有枚举到这个端口设备,请问有什么方法,可以自己向PnP申请访问这个I/O port. 有源程序的话做好可以让我参考一下,谢谢! 如果大家不嫌弃的话我也可以把我的driver给大家看看,希望能得到大家的帮助. |
|
沙发#
发布于:2003-06-10 20:40
请问班竹遇到过这样的问题没有?帮小弟一吧吧.
我想的话可以人为的向PnP管理器请求分配资源吧. |
|
板凳#
发布于:2003-06-10 21:50
能不能说的详细点,你是怎么做的?具体怎么做的!
我想最基本的I/O读写,应该不难! 用READFILE或DEVICEIOCTL来实现,在应用层开辟缓冲区,然后映射到驱动层,利用最基本的读函数就能实现了,我用DS实现过,没什么难度! |
|
|
地板#
发布于:2003-06-10 21:58
不用分配资源
直接读写就可以的 :D |
|
|
地下室#
发布于:2003-06-10 22:46
我的driver是这样做的:
#include <ntddk.h> #define IOPM_SIZE 0x2000 typedef char IOPM[IOPM_SIZE]; IOPM *pIOPM = NULL; // Define the various device type values. Note that values used by Microsoft // Corporation are in the range 0-32767, and 32768-65535 are reserved for use // by customers. #define FILE_DEVICE_JOYSTICK 0x00008020 // Macro definition for defining IOCTL and FSCTL function control codes. // Note that function codes 0-2047 are reserved for Microsoft Corporation, // and 2048-4095 are reserved for customers. #define JOYSTICK_IOCTL_INDEX 0x820 // Define our own private IOCTL #define IOCTL_JOYSTICK_TEST CTL_CODE(FILE_DEVICE_JOYSTICK, \\ JOYSTICK_IOCTL_INDEX + 1, \\ METHOD_BUFFERED, \\ FILE_ANY_ACCESS) KSPIN_LOCK BufferLock; KIRQL irql; struct OutputData { BOOLEAN fAllResult; BOOLEAN fFail_pin_button; BOOLEAN fFail_pin_3; BOOLEAN fFail_pin_6; BOOLEAN fFail_pin_11; BOOLEAN fFail_pin_13; USHORT TpinB_low; USHORT TpinB_high; USHORT Tpin3_high; USHORT Tpin3_low; USHORT Tpin6_high; USHORT Tpin6_low; USHORT Tpin11_high; USHORT Tpin11_low; USHORT Tpin13_high; USHORT Tpin13_low; } OutputBufferData = {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; UCHAR PORT = (UCHAR)0x201; // ----------------------------------------------------------------- NTSTATUS JoyStickDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); void JoyStickUnload(IN PDRIVER_OBJECT DriverObject); void Ke386SetIoAccessMap(int, IOPM *); void Ke386IoSetAccessProcess(PEPROCESS, int); void WinbondGamePortTest(); void ViaGamePortTest(); // ----------------------------------------------------------------- // Installable driver initialization entry point. // This entry point is called directly by the I/O system. NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { UNICODE_STRING DeviceNameUnicodeString; UNICODE_STRING DeviceLinkUnicodeString; NTSTATUS ntStatus; PDEVICE_OBJECT DeviceObject = NULL; // //BOOLEAN ConflictDetected = FALSE; //CM_RESOURCE_LIST HardwareResources; RtlInitUnicodeString (&DeviceNameUnicodeString, L\"\\\\Device\\\\JoyStick\"); // Create an EXCLUSIVE device object (only 1 thread at a time // can make requests to this device). ntStatus = IoCreateDevice (DriverObject, 0, &DeviceNameUnicodeString, FILE_DEVICE_JOYSTICK, 0, TRUE, &DeviceObject); if (NT_SUCCESS(ntStatus)) { // Create dispatch points for device control, create, close. DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = JoyStickDispatch; DriverObject->DriverUnload = JoyStickUnload; // Create a symbolic link, e.g. a name that a Win32 app can specify // to open the device. RtlInitUnicodeString (&DeviceLinkUnicodeString, L\"\\\\DosDevices\\\\JoyStick\"); ntStatus = IoCreateSymbolicLink (&DeviceLinkUnicodeString, &DeviceNameUnicodeString); if (!NT_SUCCESS(ntStatus)) // Symbolic link creation failed- note this & then delete the // device object (it\'s useless if a Win32 app can\'t get at it). IoDeleteDevice (DeviceObject); } /* HardwareResources.Count = 1; HardwareResources.List[0].InterfaceType = -1; HardwareResources.List[0].BusNumber = -1; HardwareResources.List[0].PartialResourceList.Version = 1; HardwareResources.List[0].PartialResourceList.Revision = 1; HardwareResources.List[0].PartialResourceList.Count = 1; HardwareResources.List[0].PartialResourceList.PartialDescriptors[0].Type = CmResourceTypePort; HardwareResources.List[0].PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareDeviceExclusive; HardwareResources.List[0].PartialResourceList.PartialDescriptors[0].Flags = CM_RESOURCE_PORT_IO; HardwareResources.List[0].PartialResourceList.PartialDescriptors[0].u.Port.Start.QuadPart = (LONGLONG)PORT; HardwareResources.List[0].PartialResourceList.PartialDescriptors[0].u.Port.Length = 1; ntStatus = IoReportResourceForDetection (DriverObject, &HardwareResources, sizeof(HardwareResources), NULL, NULL, 0, &ConflictDetected); //Debug KdPrint((\"ConflictDetected = %d\\n\", ConflictDetected)); if (!NT_SUCCESS(ntStatus)) { KdPrint((\" IoReportResourceForDetection Error \")); return ntStatus; } */ return ntStatus; } // Process the IRPs sent to this device NTSTATUS JoyStickDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION IrpStack; ULONG dwInputBufferLength; ULONG dwOutputBufferLength; ULONG dwIoControlCode; PVOID pvIOBuffer; NTSTATUS ntStatus; // Init to default settings Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IrpStack = IoGetCurrentIrpStackLocation(Irp); // Get the pointer to the input/output buffer and it\'s length pvIOBuffer = Irp->AssociatedIrp.SystemBuffer; //struct OutputData * pvio =(struct OutputData) pvIOBuffer; dwInputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength; dwOutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength; switch (IrpStack->MajorFunction) { case IRP_MJ_CREATE: break; case IRP_MJ_CLOSE: break; case IRP_MJ_DEVICE_CONTROL: dwIoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode; switch (dwIoControlCode) { case IOCTL_JOYSTICK_TEST: //Add pIOPM = MmAllocateNonCachedMemory(sizeof(IOPM)); KdPrint((\"pIOPM = %d\\n\", pIOPM)); if (pIOPM) { RtlZeroMemory(pIOPM, sizeof(IOPM)); Ke386IoSetAccessProcess(PsGetCurrentProcess(), 1); Ke386SetIoAccessMap(1, pIOPM); KdPrint((\"1\")); } else {Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; break; } //Debug KdPrint((\"2\")); KeInitializeSpinLock(&BufferLock); KeAcquireSpinLock(&BufferLock,&irql); //Debug KdPrint((\"ChipName = %d\\n\", *((PLONG)pvIOBuffer))); if (*((PLONG)pvIOBuffer)==0) WinbondGamePortTest(); if (*((PLONG)pvIOBuffer)==1) ViaGamePortTest(); KeReleaseSpinLock(&BufferLock,irql); //Add if (pIOPM) { Ke386IoSetAccessProcess(PsGetCurrentProcess(), 0); Ke386SetIoAccessMap(1, pIOPM); MmFreeNonCachedMemory(pIOPM, sizeof(IOPM)); pIOPM = NULL; } //Debug Information KdPrint((\"OutputBufferData.fAllResult = %d\\n\", OutputBufferData.fAllResult)); KdPrint((\"OutputBufferData.fFail_pin_button = %d\\n\", OutputBufferData.fFail_pin_button)); KdPrint((\"OutputBufferData.fFail_pin_3 = %d\\n\", OutputBufferData.fFail_pin_3)); KdPrint((\"OutputBufferData.fFail_pin_6 = %d\\n\", OutputBufferData.fFail_pin_6)); KdPrint((\"OutputBufferData.fFail_pin_11 = %d\\n\", OutputBufferData.fFail_pin_11)); KdPrint((\"OutputBufferData.fFail_pin_13 = %d\\n\", OutputBufferData.fFail_pin_13)); KdPrint((\"OutputBufferData.TpinB_low = %d\\n\", OutputBufferData.TpinB_low)); KdPrint((\"OutputBufferData.TpinB_high = %d\\n\", OutputBufferData.TpinB_high)); KdPrint((\"OutputBufferData.Tpin3_high = %d\\n\", OutputBufferData.Tpin3_high)); KdPrint((\"OutputBufferData.Tpin3_low = %d\\n\", OutputBufferData.Tpin3_low)); KdPrint((\"OutputBufferData.Tpin6_high = %d\\n\", OutputBufferData.Tpin6_high)); KdPrint((\"OutputBufferData.Tpin6_low = %d\\n\", OutputBufferData.Tpin6_low)); KdPrint((\"OutputBufferData.Tpin11_high = %d\\n\", OutputBufferData.Tpin11_high)); KdPrint((\"OutputBufferData.Tpin11_low = %d\\n\", OutputBufferData.Tpin11_low)); KdPrint((\"OutputBufferData.Tpin13_high = %d\\n\", OutputBufferData.Tpin13_high)); KdPrint((\"OutputBufferData.Tpin13_low = %d\\n\", OutputBufferData.Tpin13_low)); //pIrp->IoStatus.Information = DataBufferSize; RtlCopyMemory(pvIOBuffer, &OutputBufferData, sizeof(OutputBufferData)); Irp->IoStatus.Information = sizeof(OutputBufferData); break; default: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; break; } break; } // DON\'T get cute and try to use the status field of the irp in the // return status. That IRP IS GONE as soon as you call IoCompleteRequest. ntStatus = Irp->IoStatus.Status; IoCompleteRequest (Irp, IO_NO_INCREMENT); return ntStatus; } // Delete the associated device and return void JoyStickUnload(IN PDRIVER_OBJECT DriverObject) { UNICODE_STRING DeviceLinkUnicodeString; NTSTATUS ntStatus; RtlInitUnicodeString (&DeviceLinkUnicodeString, L\"\\\\DosDevices\\\\JoyStick\"); ntStatus = IoDeleteSymbolicLink (&DeviceLinkUnicodeString); if (NT_SUCCESS(ntStatus)) IoDeleteDevice (DriverObject->DeviceObject); } |
|
5楼#
发布于:2003-06-10 23:07
上接:我的两个测试函数的实现
(这两个函数是我的测试内容.其实大家不要搞清为什么要这样做,这是我们自己的代码,仅在driver中来调用,然后我的driver就把我要的结果返回给我的应用程序.) void WinbondGamePortTest(); void ViaGamePortTest(); void WinbondGamePortTest() { USHORT Tstart; // Test Button2,7,10,14 Tstart = 0; WRITE_PORT_UCHAR(&PORT,(UCHAR)0xff); Tstart++; while ((READ_PORT_UCHAR(&PORT)& 0xf0)!=0x00) { Tstart++; if (Tstart>=10000) { OutputBufferData.fFail_pin_button = TRUE; OutputBufferData.fAllResult = FALSE; break; } } OutputBufferData.TpinB_low = Tstart; while ((READ_PORT_UCHAR(&PORT)& (UCHAR)0xf0)!=0xf0) { Tstart++; if (Tstart>=10000) { OutputBufferData.fFail_pin_button = TRUE; OutputBufferData.fAllResult = FALSE; break; } } OutputBufferData.TpinB_high = Tstart; // Test Pin3--j1_x Tstart = 0; WRITE_PORT_UCHAR(&PORT,(UCHAR)0xff); Tstart++; while ((READ_PORT_UCHAR(&PORT)&0x01)!=0x01) { Tstart++; if (Tstart>=10000) { OutputBufferData.fFail_pin_3 = TRUE; OutputBufferData.fAllResult = FALSE; break; } } OutputBufferData.Tpin3_high = Tstart; while ((READ_PORT_UCHAR(&PORT)&0x01)!=0x00) { Tstart++; if (Tstart>=10000) { OutputBufferData.fFail_pin_3 = TRUE; OutputBufferData.fAllResult = FALSE; break; } } OutputBufferData.Tpin3_low = Tstart; // Test Pin6--j1_y Tstart = 0; WRITE_PORT_UCHAR(&PORT,0xff); Tstart++; while ((READ_PORT_UCHAR(&PORT)&0x02)!=0x02) { Tstart++; if (Tstart>=10000) { OutputBufferData.fFail_pin_6 = TRUE; OutputBufferData.fAllResult = FALSE; break; } } OutputBufferData.Tpin6_high = Tstart; while ((READ_PORT_UCHAR(&PORT)&0x02)!=0x00) { Tstart++; if (Tstart>=10000) { OutputBufferData.fFail_pin_6 = TRUE; OutputBufferData.fAllResult = FALSE; break; } } OutputBufferData.Tpin6_low = Tstart; // Test Pin11--j2_x Tstart = 0; WRITE_PORT_UCHAR(&PORT,0xff); // Test Pin11--j2_x Tstart++; while ((READ_PORT_UCHAR(&PORT)&0x04)!=0x04) { Tstart++; if (Tstart>=10000) { OutputBufferData.fFail_pin_11 = TRUE; OutputBufferData.fAllResult = FALSE; break; } } OutputBufferData.Tpin11_high = Tstart; while ((READ_PORT_UCHAR(&PORT)&0x04)!=0x00) { Tstart++; if (Tstart>=10000) { OutputBufferData.fFail_pin_11 = TRUE; OutputBufferData.fAllResult = FALSE; break; } } OutputBufferData.Tpin11_low = Tstart; // Test Pin13--j2_y Tstart = 0; WRITE_PORT_UCHAR(&PORT,0xff); Tstart++; while ((READ_PORT_UCHAR(&PORT)&0x08)!=0x08) { Tstart++; if (Tstart>=10000) { OutputBufferData.fFail_pin_13 = TRUE; OutputBufferData.fAllResult = FALSE; break; } } OutputBufferData.Tpin13_high = Tstart; while ((READ_PORT_UCHAR(&PORT)&0x08)!=0x00) { Tstart++; if (Tstart>=10000) { OutputBufferData.fFail_pin_13 = TRUE; OutputBufferData.fAllResult = FALSE; break; } } OutputBufferData.Tpin13_low = Tstart; } void ViaGamePortTest() { USHORT Tstart; // Test Button2,7,10,14 Tstart = 0; WRITE_PORT_UCHAR(&PORT,0xff); Tstart++; while ((READ_PORT_UCHAR(&PORT)&0xf0)!=0x00) { Tstart++; if (Tstart>=10000) { OutputBufferData.fFail_pin_button = TRUE; OutputBufferData.fAllResult = FALSE; break; } } OutputBufferData.TpinB_low = Tstart; while ((READ_PORT_UCHAR(&PORT)&0xf0)!=0x00) { Tstart++; if (Tstart>=10000) { OutputBufferData.fFail_pin_button = TRUE; OutputBufferData.fAllResult = FALSE; break; } } OutputBufferData.TpinB_high = Tstart; // Test Pin3--j1_x Tstart = 0; WRITE_PORT_UCHAR(&PORT,0xff); Tstart++; while ((READ_PORT_UCHAR(&PORT)&0x01)!=0x01) { Tstart++; if (Tstart>=10000) { OutputBufferData.fFail_pin_3 = TRUE; OutputBufferData.fAllResult = FALSE; break; } } OutputBufferData.Tpin3_high = Tstart; while ((READ_PORT_UCHAR(&PORT)&0x01)!=0x00) { Tstart++; if (Tstart>=10000) { OutputBufferData.fFail_pin_3 = TRUE; OutputBufferData.fAllResult = FALSE; break; } } OutputBufferData.Tpin3_low = Tstart; // Test Pin6--j1_y Tstart = 0; WRITE_PORT_UCHAR(&PORT,0xff); Tstart++; while ((READ_PORT_UCHAR(&PORT)&0x02)!=0x02) { Tstart++; if (Tstart>=10000) { OutputBufferData.fFail_pin_6 = TRUE; OutputBufferData.fAllResult = FALSE; break; } } OutputBufferData.Tpin6_high = Tstart; while ((READ_PORT_UCHAR(&PORT)&0x02)!=0x00) { Tstart++; if (Tstart>=10000) { OutputBufferData.fFail_pin_6 = TRUE; OutputBufferData.fAllResult = FALSE; break; } } OutputBufferData.Tpin6_low = Tstart; // Test Pin11--j2_x Tstart = 0; WRITE_PORT_UCHAR(&PORT,0xff); Tstart++; while ((READ_PORT_UCHAR(&PORT)&0x04)!=0x04) { Tstart++; if (Tstart>=10000) { OutputBufferData.fFail_pin_11 = TRUE; OutputBufferData.fAllResult = FALSE; break; } } OutputBufferData.Tpin11_high = Tstart; while ((READ_PORT_UCHAR(&PORT)&0x04)!=0x00) { Tstart++; if (Tstart>=10000) { OutputBufferData.fFail_pin_11 = TRUE; OutputBufferData.fAllResult = FALSE; break; } } OutputBufferData.Tpin11_low = Tstart; // Test Pin13--j2_y Tstart = 0; WRITE_PORT_UCHAR(&PORT,0xff); Tstart++; while ((READ_PORT_UCHAR(&PORT)&0x08)!=0x08) { Tstart++; if (Tstart>=10000) { OutputBufferData.fFail_pin_13 = TRUE; OutputBufferData.fAllResult = FALSE; break; } } OutputBufferData.Tpin13_high = Tstart; while ((READ_PORT_UCHAR(&PORT)&0x08)!=0x00) { Tstart++; if (Tstart>=10000) { OutputBufferData.fFail_pin_13 = TRUE; OutputBufferData.fAllResult = FALSE; break; } } OutputBufferData.Tpin13_low = Tstart; } 小弟现在要在Windows下通过读写I/O 201 Port来检测标准游戏控制器的好坏.因为象标准游戏控制器等这些ISA设备在Windows下都应该被分配了固定的地址.所以我想的话我在内核态应该能读写它.可是我现在的程序进入内核driver中来读写201 port好象没有任何的作用.我不知到是什么原因. 开始我猜想可能是PnP没有分配201 port给某一个设备.所以我还想自己向PnP 申请分配201 port资源.见我的程序中的HardwareResources结构及IoReportResourceForDetection.结果我加入了上面的代码后就导致冲突.在动态加载时不能启动driver. 所以我就在我的driver中把它给注解了. 但现在的程序我不知怎么不能读写201 port. 我不知是什么原因.而且我也看到我的主机上201 port的确已经被我的游戏控制器占用了,这也就解答了我为什么不能再向PnP管理器申请分配201 port的原因. 但我还是想不通, 既然我的201 port已经被系统占用, 我却为什么不能读写她呢, 是不是我的driver有什么问题. 请班竹帮忙看看小弟第一次写driver. 小弟还想询问一下班竹的E-mail, 我可以把我的driver寄给班竹还请班竹帮我看看. |
|