请问在win2000下象_outp这样的函数调用是不是不兼容啊

解决方案 »

  1.   

    _outp and _inp是直接和端口打交道的程序,它可在win9x下运行但win2000是保护模式的,用户不能对硬件直接读写,需写驱动程序才可以访问硬件。
      

  2.   

    在csdn上搜一下我记得有一个驱动是可以的
      

  3.   

    Win2000下应用程序不能直接用I/O函数读写端口,搜一下WinIO吧,调用它的接口就可以了。
      

  4.   

    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写端口即可.