Lingfeng
驱动牛犊
驱动牛犊
  • 注册日期2002-11-30
  • 最后登录2008-07-20
  • 粉丝0
  • 关注0
  • 积分11分
  • 威望5点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
阅读:1237回复:5

一个有关访问IO的driver,在访问Com口时总是不能得到值

楼主#
更多 发布于:2003-09-23 22:09
Hi ,各位驱动开发网的朋友:
    小弟现在有一个问题想请教大家。我写了一个driver是专门用来访问IO端口的。我全部用的是DDK中提供的函数,没有用Undocument的API。这个driver可以正常的访问打印口,扬声器的端口。但是在读取COM口数据时得到的数据总是0xff.一般系统提供给Com的IO端口为0x3f8~0x3ff, 或0x2f8~0x2ff等。但当我去读这些端口时,得到的数据总为0xff,写也写不进去。我不知道是什么原因,难道是体统屏蔽了这个端口,还是怎么的。而且我用那三个没有公开的API直接打开IO掩码,得到的结果是一样的,这就使我感到很奇怪了,如果我的driver有问题的话,那他应该连其他端口也不能访问,但是我试了其他端口可以读出正确的值,就是Com口如果直接的去读写的话,好像不能得到正确的值,独到的值总为0xff,写也写不进去。请各位帮忙,看看是什么原因,谢谢!
else
驱动小牛
驱动小牛
  • 注册日期2002-10-21
  • 最后登录2004-06-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-09-23 22:17
这种驱动还用自己去写吗?

http://www.internals.com/
Lingfeng
驱动牛犊
驱动牛犊
  • 注册日期2002-11-30
  • 最后登录2008-07-20
  • 粉丝0
  • 关注0
  • 积分11分
  • 威望5点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-09-24 08:17
这位老兄:
    谢谢你的回复,这个WinIO2.0我这里也有,而且我看到他是用微软没有公开的几个API来做的。这种方法虽然简单,但是还是有不好之处。我现在是自己全部用系统提供的API来写的,已经可以了。不过就是不能正常的读写COM口的值,而且我也用WinIO2.0也试了一下,好像他读到道的值也全为0xff.不知老兄试过没有。我不知是什么原因。
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
地板#
发布于:2003-09-24 08:58
修改IO位图看看.
驱动:WssIo.c
#include \"ntddk.h\"
#include \"string.h\"

#ifndef DWORD
#define DWORD unsigned int
#endif

#ifndef WORD
#define WORD unsigned short
#endif

#define NOT_BUSY            9
#define DEFAULT_TSS_LIMIT   0x20ab  //缺省的 TSS 段界限
#define NEW_TSS_LIMIT       0x2fab

static NTSTATUS  MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject);

#pragma pack(push,1)


typedef struct tagGDTR{
    WORD    wLimit;
    DWORD   *dwBase;
}GDTR, *PGDTR;

typedef struct tagGDTENTRY{
    DWORD dwLimit : 16;
    DWORD dwBaselo : 16;
    DWORD dwBasemid : 8;
    DWORD dwType : 4;
    DWORD dwSystem : 1;
    DWORD dwDpl : 2;
    DWORD dwPresent : 1;
    DWORD dwLimithi : 4;
    DWORD dwAvailable : 1;
    DWORD dwZero : 1;
    DWORD dwSize : 1;
    DWORD dwGranularity : 1;
    DWORD dwBasehi : 8;
} GDTENTRY, *PGDTENTRY;

#pragma pack(pop)

VOID SetAllPorcIO( int iTrue )
{
    GDTR        gdtr;
    PGDTENTRY   TssInGdt;

    WORD        TSSseg;


    __asm {
        cli                            // 屏蔽中断
        sgdt  gdtr                    // 得到 GDT 基地址与段界限
        str   TSSseg                // 得到 TSS 选择子
        movzx esi,TSSseg            // 扩展到 ESI 中以便计算
        add   esi,gdtr.dwBase       // 得到 TSS 在 GDT 中描述符
        mov   TssInGdt,esi
    }

    if ( iTrue == 1 )
    {
        TssInGdt->dwLimit = NEW_TSS_LIMIT;    // 设置新的 TSS 段界限
    }

    else {
        TssInGdt->dwLimit = DEFAULT_TSS_LIMIT;
    }

    TssInGdt->dwType = NOT_BUSY;            //必须设置为NOTBUSY状态(9),BUSY is 0Bh

    __asm {
        ltr TSSseg                // 将设置好的 TSS 重新装入
        sti                        // 开中断
    }


}


// 驱动入口
NTSTATUS  DriverEntry( IN PDRIVER_OBJECT DriverObject,  IN PUNICODE_STRING RegistryPath )
{
    
    UNICODE_STRING  nameString, linkString;
    PDEVICE_OBJECT  deviceObject;
    NTSTATUS        status;
    HANDLE          hHandle;
    int                i;
    

    //卸载驱动
    DriverObject->DriverUnload = DriverUnload;

    //建立设备
    RtlInitUnicodeString( &nameString, L\"\\\\Device\\\\WssIo\" );
    
    status = IoCreateDevice( DriverObject,
                             0,
                             &nameString,
                             FILE_DEVICE_UNKNOWN,
                             0,
                             TRUE,
                             &deviceObject
                           );
                          

    if (!NT_SUCCESS( status ))
        return status;
    

    RtlInitUnicodeString( &linkString, L\"\\\\DosDevices\\\\WssIo\" );

    status = IoCreateSymbolicLink (&linkString, &nameString);

    if (!NT_SUCCESS( status ))
    {
        IoDeleteDevice (DriverObject->DeviceObject);
        return status;
    }    
    
    SetAllPorcIO(1);

    for ( i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)    {

          DriverObject->MajorFunction = MydrvDispatch;
    }

      DriverObject->DriverUnload = DriverUnload;
    
  return STATUS_SUCCESS;
}


//处理设备对象操作

static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0L;
    IoCompleteRequest( Irp, 0 );
    return Irp->IoStatus.Status;
    
}


VOID DriverUnload (IN PDRIVER_OBJECT    pDriverObject)
{
    UNICODE_STRING  nameString;

    SetAllPorcIO(0);

    RtlInitUnicodeString( &nameString, L\"\\\\DosDevices\\\\WssIo\" );    
    IoDeleteSymbolicLink(&nameString);
    IoDeleteDevice(pDriverObject->DeviceObject);

    return;
}

//应用层测试程序
#include\"stdio.h\"
#include <windows.h>


SERVICE_STATUS_HANDLE ssh;
SERVICE_STATUS ss;

void WINAPI StartupService();

void WINAPI InstallService()
{
 SC_HANDLE scm;
 SC_HANDLE svc;

 scm=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
 svc=CreateService( scm,
    \"WinIo\",
    \"WinIo\",
    SERVICE_ALL_ACCESS,
    SERVICE_KERNEL_DRIVER,
    SERVICE_DEMAND_START,
    SERVICE_ERROR_NORMAL,
    \"C:\\\\WINDOWS\\\\SYSTEM32\\\\DRIVERS\\\\WinIo.sys\",
    NULL,
    NULL,
    NULL,
    NULL,
    NULL
    );
 if(svc!=NULL)
 {
  CloseServiceHandle(svc);
  CloseServiceHandle(scm);
 }
}


void WINAPI DelService()
{
 SC_HANDLE scm;
 SC_HANDLE svc;
 BOOL ret;
 SERVICE_STATUS ServiceStatus;

 scm=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
 if(scm!=NULL)
 {
  svc=OpenService(scm,\"WinIo\",SERVICE_ALL_ACCESS);
  if (svc == NULL)
  {
   MessageBox(NULL,\"svcERROR!\",NULL,MB_OK);
   return ;
  }
  ret = ControlService(svc,SERVICE_CONTROL_STOP,&ServiceStatus);
  if (ret == FALSE)
  {
   MessageBox(NULL,\"error\",NULL,MB_OK);
  }
  svc=OpenService(scm,\"WinIo\",SERVICE_ALL_ACCESS);
  DeleteService(svc);
  CloseServiceHandle(svc);
  MessageBox(NULL,\"驱动已卸载 \",\"删除\",MB_OK);
  CloseServiceHandle(scm);
 }
 else
  MessageBox(NULL,\"cuo\",NULL,MB_OK);

}


void WINAPI StartupService()
{
 SC_HANDLE scm;
 SC_HANDLE svc;

 scm=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
 if(scm!=NULL)
 {
  svc=OpenService(scm,\"WinIo\",SERVICE_ALL_ACCESS);
  if(svc!=NULL)
  {
   StartService(svc,0,NULL);
   CloseServiceHandle(svc);
   MessageBox(NULL,\"驱动已安装\",\"启动\",MB_OK);
  }
  else CloseServiceHandle(scm);
 }

 else MessageBox(NULL,\"安装驱动失败\",NULL,MB_OK);

}

  

void WINAPI InitService()
{
 InstallService();
 StartupService();  
}

 void main()
{
     TCHAR szDir[MAX_PATH];
     TCHAR szsysDir[MAX_PATH];
     int i = 0;

GetCurrentDirectory(sizeof(szDir),szDir);
     lstrcat(szDir,\"\\\\winio.sys\");
     GetSystemDirectory(szsysDir,sizeof(szsysDir));
     lstrcat(szsysDir,\"\\\\drivers\\\\winio.sys\");
     CopyFile(szDir,szsysDir,FALSE);

InitService();
    __asm {
      mov al,0a0h
      mov dx,03f8h
      out dx,al
      mov dx,03f8h
      in  al,dx
      mov byte ptr i,al
    }  
    printf(\"%d\\n\",i);

    DelService();
}

花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
Lingfeng
驱动牛犊
驱动牛犊
  • 注册日期2002-11-30
  • 最后登录2008-07-20
  • 粉丝0
  • 关注0
  • 积分11分
  • 威望5点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-09-24 09:28
Hi, wowocock:
    我刚才在ddk环境下build你的WssIo.c怎么出现了102个错误呀。请问你是如何build的呀。谢谢你了,你能帮小弟实试试吗?谢了!

wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
5楼#
发布于:2003-09-24 11:37
不会吧,我用XPDDK编译没问题的啊
附件名称/大小 下载次数 最后更新
2003-09-24_winio.sys (2KB)  0
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
游客

返回顶部