关于_outp 请问在win2000下象_outp这样的函数调用是不是不兼容啊 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 _outp and _inp是直接和端口打交道的程序,它可在win9x下运行但win2000是保护模式的,用户不能对硬件直接读写,需写驱动程序才可以访问硬件。 在csdn上搜一下我记得有一个驱动是可以的 Win2000下应用程序不能直接用I/O函数读写端口,搜一下WinIO吧,调用它的接口就可以了。 NT下对I/O操作进行了保护的,不允许直接访问i/o端口,一般的解决方法是 编写驱动程序,这样可以在Kernel层访问I/O.在NT/2000DDK\src\general目录下有个 portio的例子,拿来就可以用了.还有更好的方法,利用DDK中几个未公开的API也可以 达到同样的目的. //portio.c #include /* * The name of our device driver. */ #define DEVICE_NAME_STRING L"portio" #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); /********************************************************************* Release any allocated objects. *********************************************************************/ VOID GiveioUnload(IN PDRIVER_OBJECT DriverObject) { WCHAR DOSNameBuffer[] = L"\\DosDevices\\" DEVICE_NAME_STRING; UNICODE_STRING uniDOSString; if(IOPM_local) MmFreeNonCachedMemory(IOPM_local, sizeof(IOPM)); RtlInitUnicodeString(&uniDOSString, DOSNameBuffer); IoDeleteSymbolicLink (&uniDOSString); IoDeleteDevice(DriverObject->DeviceObject); } VOID SetIOPermissionMap(int OnFlag) { Ke386IoSetAccessProcess(PsGetCurrentProcess(), OnFlag); Ke386SetIoAccessMap(1, IOPM_local); } void GiveIO(void) { SetIOPermissionMap(1); } NTSTATUS GiveioCreateDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { GiveIO(); // give the calling process I/O access Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { { PDEVICE_OBJECT deviceObject; NTSTATUS status; WCHAR NameBuffer[] = L"\\Device\\" DEVICE_NAME_STRING; WCHAR DOSNameBuffer[] = L"\\DosDevices\\" DEVICE_NAME_STRING; UNICODE_STRING uniNameString, uniDOSString; // // Allocate a buffer for the local IOPM and zero it. // IOPM_local = MmAllocateNonCachedMemory(sizeof(IOPM)); if(IOPM_local == 0) return STATUS_INSUFFICIENT_RESOURCES; RtlZeroMemory(IOPM_local, sizeof(IOPM)); // // Set up device driver name and device object. // 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; // // Initialize the Driver Object with driver's entry points. // All we require are the Create and Unload operations. // DriverObject->MajorFunction[IRP_MJ_CREATE] = GiveioCreateDispatch; DriverObject->DriverUnload = GiveioUnload; return STATUS_SUCCESS; } //在同一个目录下建造sources文件,内容: TARGETNAME=portio TARGETPATH=. TARGETTYPE=DRIVER INCLUDES=e:\ntddk\inc ;//这儿填写DDK下inc目录的路径 SOURCES=portio.c //在同一个目录下建造makefile文件,内容: !INCLUDE $(NTMAKEENV)\makefile.def 利用命令行:SetEnv e:\ntddk //设置DDK环境 在该目录下 build,然后会在该目录的I386中产生portio.sys文件,将文件 copy到WINNT\system32\drivers里面,在注册表中手工安装驱动程序(别告诉我你不会 ,到驱动程序版查查,最好设置为驱动程序自动启动,service的key为portio),重起机子。 编写用户态程序: HANDLE h; h = CreateFile("\\\\.\\portio", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NUULL); if(h == INVALID_HANDLE_VALUE) { printf("Couldn't access giveio device\n"); return -1; } CloseHandle(h); //然后以后用嵌入汇编或者_inp,_oup写端口即可. 关于进程与模块 如何通过界面输入变量,然后自动生成代码? 请教下为何MSDN里查不到GetAdaptersInfo这个API, -------关于ATL 控件的问题! 一个对话框的工具栏问题-->>怎样禁用对话框中的工具栏按钮<<--问题解决就结贴 对即时语音通讯以及网络会议.语音聊天室感兴趣的朋友请加入 急救!!! 简单的问题: vc6.0下使用richtextbox如何一直显示最后输出的数据? tree control控件 展开与缩进 简单问题,怎么把一个字符串中的"字符替换成^" 如何让文字或图片控件能在对话框居中显示?
编写驱动程序,这样可以在Kernel层访问I/O.在NT/2000DDK\src\general目录下有个
portio的例子,拿来就可以用了.还有更好的方法,利用DDK中几个未公开的API也可以
达到同样的目的.
//portio.c
#include
/*
* The name of our device driver.
*/
#define DEVICE_NAME_STRING L"portio"
#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); /*********************************************************************
Release any allocated objects.
*********************************************************************/
VOID GiveioUnload(IN PDRIVER_OBJECT DriverObject)
{
WCHAR DOSNameBuffer[] = L"\\DosDevices\\" DEVICE_NAME_STRING;
UNICODE_STRING uniDOSString; if(IOPM_local)
MmFreeNonCachedMemory(IOPM_local, sizeof(IOPM)); RtlInitUnicodeString(&uniDOSString, DOSNameBuffer);
IoDeleteSymbolicLink (&uniDOSString);
IoDeleteDevice(DriverObject->DeviceObject);
} VOID SetIOPermissionMap(int OnFlag)
{
Ke386IoSetAccessProcess(PsGetCurrentProcess(), OnFlag);
Ke386SetIoAccessMap(1, IOPM_local);
} void GiveIO(void)
{
SetIOPermissionMap(1);
} NTSTATUS GiveioCreateDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
GiveIO(); // give the calling process I/O access Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
} NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
{
PDEVICE_OBJECT deviceObject;
NTSTATUS status;
WCHAR NameBuffer[] = L"\\Device\\" DEVICE_NAME_STRING;
WCHAR DOSNameBuffer[] = L"\\DosDevices\\" DEVICE_NAME_STRING;
UNICODE_STRING uniNameString, uniDOSString; //
// Allocate a buffer for the local IOPM and zero it.
//
IOPM_local = MmAllocateNonCachedMemory(sizeof(IOPM));
if(IOPM_local == 0)
return STATUS_INSUFFICIENT_RESOURCES;
RtlZeroMemory(IOPM_local, sizeof(IOPM)); //
// Set up device driver name and device object.
//
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; //
// Initialize the Driver Object with driver's entry points.
// All we require are the Create and Unload operations.
//
DriverObject->MajorFunction[IRP_MJ_CREATE] = GiveioCreateDispatch;
DriverObject->DriverUnload = GiveioUnload;
return STATUS_SUCCESS;
} //在同一个目录下建造sources文件,内容:
TARGETNAME=portio
TARGETPATH=.
TARGETTYPE=DRIVER
INCLUDES=e:\ntddk\inc ;//这儿填写DDK下inc目录的路径
SOURCES=portio.c //在同一个目录下建造makefile文件,内容:
!INCLUDE $(NTMAKEENV)\makefile.def 利用命令行:SetEnv e:\ntddk //设置DDK环境
在该目录下 build,然后会在该目录的I386中产生portio.sys文件,将文件
copy到WINNT\system32\drivers里面,在注册表中手工安装驱动程序(别告诉我你不会
,到驱动程序版查查,最好设置为驱动程序自动启动,service的key为portio),重起机子。 编写用户态程序:
HANDLE h;
h = CreateFile("\\\\.\\portio", GENERIC_READ, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NUULL);
if(h == INVALID_HANDLE_VALUE) {
printf("Couldn't access giveio device\n");
return -1;
}
CloseHandle(h);
//然后以后用嵌入汇编或者_inp,_oup写端口即可.