阅读:1625回复:10
谁能提供一个win2k下访问PCI配置空间的驱动?
rt,访问PCI配置空间需要访问0xCF8和0xCFC端口,这两个端口都需要按4字节访问。我写了一个在win2k下访问端口的驱动,但是按字节访问是可以的(通过读CMOS验证),但是按4字节访问总是出错,推测原因一是Win2k把这种访问PCI配置空间的方式给禁了,再就是我的驱动写的有问题。有哪位达人可指教,在此先谢过了(最好能提供源码)
我的驱动的源码如下: #include <ntddk.h> #include "portaccess.h" #define IOPM_SIZE 0x2000 typedef UCHAR IOPM[IOPM_SIZE]; IOPM *IOPM_local = 0; void Ke386SetIoAccessMap(int, IOPM *); void Ke386QueryIoAccessMap(int, IOPM *); void Ke386IoSetAccessProcess(PEPROCESS, int); NTSTATUS PortAccessDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); VOID PortAccessUnload(IN PDRIVER_OBJECT DriverObject); NTSTATUS PortAccessCreateDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } NTSTATUS PortAccessDeviceControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP pIrp ) { PIO_STACK_LOCATION irpSp; NTSTATUS ntStatus = STATUS_SUCCESS; ULONG inBufLength; /* Input buffer length */ ULONG outBufLength; /* Output buffer length */ ULONG inBuf; /* Pointer to Input and output buffer */ PUCHAR CharBuffer; PUSHORT ShortBuffer; PULONG LongBuffer; PVOID ioBuffer; USHORT Offset; ULONG Value; ULONG ProcessID; struct _EPROCESS *Process; irpSp = IoGetCurrentIrpStackLocation( pIrp ); inBufLength = irpSp->Parameters.DeviceIoControl.InputBufferLength; outBufLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength; ioBuffer = pIrp->AssociatedIrp.SystemBuffer; CharBuffer = (PUCHAR) ioBuffer; ShortBuffer = (PUSHORT) ioBuffer; LongBuffer = (PULONG) ioBuffer; switch ( irpSp->Parameters.DeviceIoControl.IoControlCode ) { case IOCTL_READ_PORT_BYTE: if ((inBufLength >= 2) && (outBufLength >= 1)) { // KdPrint( ("PORTACCESS: IOCTL_READ_PORT_UCHAR 0x%X",ShortBuffer[0]) ); (UCHAR)Value = READ_PORT_UCHAR((PUCHAR)ShortBuffer[0]); /* __asm { mov dx,word ptr CharBuffer[0] ; in al,dx mov byte ptr Value,al } */ // KdPrint( ("PORTACCESS: Value Read %X",Value) ); CharBuffer[0] = Value; } else ntStatus = STATUS_BUFFER_TOO_SMALL; pIrp->IoStatus.Information = 1; /* Output Buffer Size */ ntStatus = STATUS_SUCCESS; break; case IOCTL_WRITE_PORT_BYTE: if (inBufLength >= 3) { // KdPrint( ("PORTACCESS: IOCTL_WRITE_PORT_UCHAR(0x%X,0x%X)",ShortBuffer[0], CharBuffer[2]) ); WRITE_PORT_UCHAR((PUCHAR)ShortBuffer[0], CharBuffer[2]); /* __asm { mov dx,word ptr CharBuffer[0]; mov al,byte ptr Value; out dx,al } */ } else ntStatus = STATUS_BUFFER_TOO_SMALL; pIrp->IoStatus.Information = 0; /* Output Buffer Size */ ntStatus = STATUS_SUCCESS; break; case IOCTL_READ_PORT_WORD: if ((inBufLength >= 1) && (outBufLength >= 1)) { // KdPrint( ("PORTACCESS: IOCTL_READ_PORT_UCHAR 0x%X",ShortBuffer[0]) ); (USHORT)Value = READ_PORT_USHORT((PUSHORT)ShortBuffer[0]); // KdPrint( ("PORTACCESS: Value Read %X",Value) ); ShortBuffer[0] = Value; } else ntStatus = STATUS_BUFFER_TOO_SMALL; pIrp->IoStatus.Information = 1; /* Output Buffer Size */ ntStatus = STATUS_SUCCESS; break; case IOCTL_WRITE_PORT_WORD: if (inBufLength >= 3) { // KdPrint( ("PORTACCESS: IOCTL_WRITE_PORT_UCHAR(0x%X,0x%X)",ShortBuffer[0], CharBuffer[2]) ); WRITE_PORT_USHORT((PUSHORT)ShortBuffer[0], ShortBuffer[2]); } else ntStatus = STATUS_BUFFER_TOO_SMALL; pIrp->IoStatus.Information = 0; /* Output Buffer Size */ ntStatus = STATUS_SUCCESS; break; case IOCTL_READ_PORT_DWORD: if ((inBufLength >= 2) && (outBufLength >= 1)) { // KdPrint( ("PORTACCESS: IOCTL_READ_PORT_UCHAR 0x%X",ShortBuffer[0]) ); (ULONG)Value = READ_PORT_ULONG((PULONG)ShortBuffer[0]); // KdPrint( ("PORTACCESS: Value Read %X",Value) ); LongBuffer[0] = Value; } else ntStatus = STATUS_BUFFER_TOO_SMALL; pIrp->IoStatus.Information = 1; /* Output Buffer Size */ ntStatus = STATUS_SUCCESS; break; case IOCTL_WRITE_PORT_DWORD: if (inBufLength >= 3) { // KdPrint( ("PORTACCESS: IOCTL_WRITE_PORT_UCHAR(0x%X,0x%X)",ShortBuffer[0], CharBuffer[2]) ); WRITE_PORT_ULONG((PULONG)ShortBuffer[0], LongBuffer[2]); } else ntStatus = STATUS_BUFFER_TOO_SMALL; pIrp->IoStatus.Information = 0; /* Output Buffer Size */ ntStatus = STATUS_SUCCESS; break; default: KdPrint( ("PORTACCESS: Unsupported IOCTL Call\n") ); ntStatus = STATUS_UNSUCCESSFUL; pIrp->IoStatus.Information = 0; break; } pIrp->IoStatus.Status = ntStatus; IoCompleteRequest( pIrp, IO_NO_INCREMENT ); return ntStatus; } VOID PortAccessUnload(IN PDRIVER_OBJECT DriverObject) { WCHAR DOSNameBuffer[] = L"\\DosDevices\\PortAccess"; UNICODE_STRING uniDOSString; KdPrint( ("PORTAccess: PortAccess is Unloading . .\n") ); if(IOPM_local) MmFreeNonCachedMemory(IOPM_local, sizeof(IOPM)); RtlInitUnicodeString(&uniDOSString, DOSNameBuffer); IoDeleteSymbolicLink (&uniDOSString); IoDeleteDevice(DriverObject->DeviceObject); } NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { PDEVICE_OBJECT deviceObject; NTSTATUS status; WCHAR NameBuffer[] = L"\\Device\\PortAccess"; WCHAR DOSNameBuffer[] = L"\\DosDevices\\PortAccess"; UNICODE_STRING uniNameString, uniDOSString; KdPrint( ("PORTACCESS: PortAccess has Loaded") ); IOPM_local = MmAllocateNonCachedMemory(sizeof(IOPM)); if(IOPM_local == 0) return STATUS_INSUFFICIENT_RESOURCES; RtlFillMemory(IOPM_local, sizeof(IOPM), 0xFF); RtlInitUnicodeString(&uniNameString, NameBuffer); RtlInitUnicodeString(&uniDOSString, DOSNameBuffer); status = IoCreateDevice(DriverObject, 0, &uniNameString, FILE_DEVICE_UNKNOWN, 0, FALSE, &deviceObject); if(!NT_SUCCESS(status)) return status; status = IoCreateSymbolicLink (&uniDOSString, &uniNameString); if (!NT_SUCCESS(status)) return status; DriverObject->MajorFunction[IRP_MJ_CREATE] = PortAccessCreateDispatch; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PortAccessDeviceControl; DriverObject->DriverUnload = PortAccessUnload; return STATUS_SUCCESS; } [编辑 - 12/16/04 by ichabod] |
|
沙发#
发布于:2004-12-16 13:37
rt,访问PCI配置空间需要访问0xCF8和0xCFC端口,这两个端口都需要按4字节访问。我写了一个在win2k下访问端口的驱动,但是按字节访问是可以的(通过读CMOS验证),但是按4字节访问总是出错,推测原因一是Win2k把这种访问PCI配置空间的方式给禁了,再就是我的驱动写的有问题。有哪位达人可指教,在此先谢过了(最好能提供源码) 留下Mail地址,我发给你修改后的代码 |
|
|
板凳#
发布于:2004-12-16 18:23
mhx011052@yahoo.com.cn
多谢多谢 |
|
地板#
发布于:2004-12-16 20:57
mhx011052@yahoo.com.cn mail已经发送,请查收 |
|
|
地下室#
发布于:2004-12-16 22:14
信已收到,按你所说的做了修改,但结果仍然不对,还请再看一下
|
|
5楼#
发布于:2004-12-17 09:19
信已收到,按你所说的做了修改,但结果仍然不对,还请再看一下 果然还有个低级错误 WRITE_PORT_ULONG((PULONG)ShortBuffer[0], LongBuffer[2]); 修改为 WRITE_PORT_ULONG((PULONG)(&ShortBuffer[0]), LongBuffer[2]); 或 WRITE_PORT_ULONG((PULONG)ShortBuffer, LongBuffer[2]); 其它的同样这样修改一下(第一个参数是指针,你将Value强制转为指针不可以) |
|
|
6楼#
发布于:2004-12-18 18:38
仍然不对,两种方式都试过了,不行
|
|
7楼#
发布于:2004-12-18 18:46
仍然不对,两种方式都试过了,不行 READ_PORT_USHORT和READ_PORT_ULONG等函数修改了吗? |
|
|
8楼#
发布于:2004-12-19 13:21
当然都改过了,可还是不行啊
|
|
9楼#
发布于:2004-12-20 05:28
我想问题出在你的exe文件中
不在这个驱动中....... 你怎么读pci config space的? 代码发上来.... 或者你看看另外的那个也是读pci config space的帖子.. 以上 |
|
10楼#
发布于:2004-12-22 16:52
多谢两位,问题已解决。用SoftICE调试发现除了达人指出的错误外,我的.exe也存在问题(ioBuffer传入的长度不对)。多谢指教。
|
|