关于_outp

couch1974 2004-03-15 05:23:03
请问在win2000下象_outp这样的函数调用是不是不兼容啊
...全文
332 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
swbreath 2004-04-25
  • 打赏
  • 举报
回复
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写端口即可.

狂放之歌 2004-04-24
  • 打赏
  • 举报
回复
以前有老大贴过代码..搜一搜..
simouse 2004-04-23
  • 打赏
  • 举报
回复
关注ing...
seaquester 2004-04-23
  • 打赏
  • 举报
回复
Win2000下应用程序不能直接用I/O函数读写端口,搜一下WinIO吧,调用它的接口就可以了。
nuaawenlin 2004-04-23
  • 打赏
  • 举报
回复
在csdn上搜一下

我记得有一个驱动是可以的
lgchina97 2004-04-19
  • 打赏
  • 举报
回复
_outp and _inp是直接和端口打交道的程序,它可在win9x下运行

但win2000是保护模式的,用户不能对硬件直接读写,需写驱动程序才可以访问硬件。

2,640

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧