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

请问如何在内核态driver中读写201 I/O port

楼主#
更多 发布于:2003-06-10 18:55
请问各位高手一个问题:
   现在我要在内核态访问一个I/O port: 0x201 port. 我写了一个driver在内核driver中去读写0x201 port.原以为很容易.但我发现我在driver中无法从201 port中读到数据.我想可能是PnP没有给201 port分配资源.所以我的driver就无法访问这个端口设备(201 port). 以前我在应用程序中通过挂上一些Direct Io 之类的driver,可以很容易的在AP下访问任意的I/O .可是现在我在Dreiver中指定访问一个I/O port就这么难,我不知道该如何做,请问有没有人,做过在driver中访问读写一个以前遗留下来的I/O 的程序.为什么在AP下挂driver可以达到访问I/O port,而在内核态driver中直接读写一个I/O port却不行呢?
   如果PnP没有枚举到这个端口设备,请问有什么方法,可以自己向PnP申请访问这个I/O port. 有源程序的话做好可以让我参考一下,谢谢!
如果大家不嫌弃的话我也可以把我的driver给大家看看,希望能得到大家的帮助.

Lingfeng
驱动牛犊
驱动牛犊
  • 注册日期2002-11-30
  • 最后登录2008-07-20
  • 粉丝0
  • 关注0
  • 积分11分
  • 威望5点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-06-10 20:40
请问班竹遇到过这样的问题没有?帮小弟一吧吧.
我想的话可以人为的向PnP管理器请求分配资源吧.
libin2309
驱动大牛
驱动大牛
  • 注册日期2002-11-20
  • 最后登录2005-12-29
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-06-10 21:50
能不能说的详细点,你是怎么做的?具体怎么做的!
我想最基本的I/O读写,应该不难!
用READFILE或DEVICEIOCTL来实现,在应用层开辟缓冲区,然后映射到驱动层,利用最基本的读函数就能实现了,我用DS实现过,没什么难度!
我是一只小小鸟,永远也飞也飞不高,但我永远在飞!
zydcat
驱动老牛
驱动老牛
  • 注册日期2001-12-06
  • 最后登录2006-04-12
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-06-10 21:58
不用分配资源
直接读写就可以的 :D
[color=red]肥虫虫[/color] [img]http://www.driverdevelop.com/forum/upload/bradley/2002-11-15_ig01.gif[/img]
Lingfeng
驱动牛犊
驱动牛犊
  • 注册日期2002-11-30
  • 最后登录2008-07-20
  • 粉丝0
  • 关注0
  • 积分11分
  • 威望5点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-06-10 22:46
我的driver是这样做的:

#include <ntddk.h>

#define IOPM_SIZE 0x2000
typedef char IOPM[IOPM_SIZE];
IOPM *pIOPM = NULL;
// Define the various device type values.  Note that values used by Microsoft
// Corporation are in the range 0-32767, and 32768-65535 are reserved for use
// by customers.
#define FILE_DEVICE_JOYSTICK 0x00008020

// Macro definition for defining IOCTL and FSCTL function control codes.
// Note that function codes 0-2047 are reserved for Microsoft Corporation,
// and 2048-4095 are reserved for customers.
#define JOYSTICK_IOCTL_INDEX 0x820

// Define our own private IOCTL
#define IOCTL_JOYSTICK_TEST   CTL_CODE(FILE_DEVICE_JOYSTICK, \\
JOYSTICK_IOCTL_INDEX + 1, \\
METHOD_BUFFERED, \\
FILE_ANY_ACCESS)
KSPIN_LOCK BufferLock;
KIRQL irql;

struct OutputData {

BOOLEAN fAllResult;
BOOLEAN fFail_pin_button;
BOOLEAN fFail_pin_3;
BOOLEAN fFail_pin_6;
BOOLEAN fFail_pin_11;
BOOLEAN fFail_pin_13;

USHORT TpinB_low;
USHORT TpinB_high;
USHORT Tpin3_high;
USHORT Tpin3_low;
     USHORT Tpin6_high;
USHORT Tpin6_low;
USHORT Tpin11_high;
USHORT Tpin11_low;
USHORT Tpin13_high;
USHORT Tpin13_low;

} OutputBufferData = {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

UCHAR PORT = (UCHAR)0x201;

// -----------------------------------------------------------------
NTSTATUS JoyStickDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
void JoyStickUnload(IN PDRIVER_OBJECT DriverObject);

void Ke386SetIoAccessMap(int, IOPM *);
void Ke386IoSetAccessProcess(PEPROCESS, int);

void WinbondGamePortTest();
void ViaGamePortTest();


// -----------------------------------------------------------------
// Installable driver initialization entry point.
// This entry point is called directly by the I/O system.
NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject,
                      IN PUNICODE_STRING RegistryPath)
{
UNICODE_STRING  DeviceNameUnicodeString;
UNICODE_STRING  DeviceLinkUnicodeString;
NTSTATUS        ntStatus;
PDEVICE_OBJECT  DeviceObject = NULL;
//
//BOOLEAN ConflictDetected = FALSE;
//CM_RESOURCE_LIST HardwareResources;

RtlInitUnicodeString (&DeviceNameUnicodeString, L\"\\\\Device\\\\JoyStick\");

// Create an EXCLUSIVE device object (only 1 thread at a time
// can make requests to this device).
ntStatus = IoCreateDevice (DriverObject,
                             0,
                             &DeviceNameUnicodeString,
                             FILE_DEVICE_JOYSTICK,
                             0,
                             TRUE,
                             &DeviceObject);

if (NT_SUCCESS(ntStatus))
{
// Create dispatch points for device control, create, close.
DriverObject->MajorFunction[IRP_MJ_CREATE]         =
DriverObject->MajorFunction[IRP_MJ_CLOSE]          =
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = JoyStickDispatch;
DriverObject->DriverUnload                         = JoyStickUnload;

// Create a symbolic link, e.g. a name that a Win32 app can specify
// to open the device.
RtlInitUnicodeString (&DeviceLinkUnicodeString, L\"\\\\DosDevices\\\\JoyStick\");

ntStatus = IoCreateSymbolicLink (&DeviceLinkUnicodeString,
                            &DeviceNameUnicodeString);
if (!NT_SUCCESS(ntStatus))
// Symbolic link creation failed- note this & then delete the
// device object (it\'s useless if a Win32 app can\'t get at it).
IoDeleteDevice (DeviceObject);

}

/*
HardwareResources.Count = 1;
HardwareResources.List[0].InterfaceType = -1;
HardwareResources.List[0].BusNumber = -1;
HardwareResources.List[0].PartialResourceList.Version = 1;
HardwareResources.List[0].PartialResourceList.Revision = 1;
HardwareResources.List[0].PartialResourceList.Count = 1;
HardwareResources.List[0].PartialResourceList.PartialDescriptors[0].Type = CmResourceTypePort;
HardwareResources.List[0].PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareDeviceExclusive;
HardwareResources.List[0].PartialResourceList.PartialDescriptors[0].Flags = CM_RESOURCE_PORT_IO;
HardwareResources.List[0].PartialResourceList.PartialDescriptors[0].u.Port.Start.QuadPart = (LONGLONG)PORT;
HardwareResources.List[0].PartialResourceList.PartialDescriptors[0].u.Port.Length = 1;

ntStatus = IoReportResourceForDetection (DriverObject,
&HardwareResources,
sizeof(HardwareResources),
NULL,
NULL,
0,
&ConflictDetected);
//Debug
KdPrint((\"ConflictDetected = %d\\n\", ConflictDetected));

if (!NT_SUCCESS(ntStatus))
{
KdPrint((\" IoReportResourceForDetection Error \"));
return ntStatus;
}
*/

return ntStatus;
}


// Process the IRPs sent to this device
NTSTATUS JoyStickDispatch(IN PDEVICE_OBJECT DeviceObject,
                       IN PIRP Irp)
{
PIO_STACK_LOCATION IrpStack;
ULONG              dwInputBufferLength;
   ULONG              dwOutputBufferLength;
ULONG              dwIoControlCode;
PVOID              pvIOBuffer;
NTSTATUS           ntStatus;


// Init to default settings
Irp->IoStatus.Status      = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;


IrpStack = IoGetCurrentIrpStackLocation(Irp);

// Get the pointer to the input/output buffer and it\'s length
   pvIOBuffer           = Irp->AssociatedIrp.SystemBuffer;
   //struct OutputData * pvio =(struct OutputData) pvIOBuffer;
   dwInputBufferLength  = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
   dwOutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
 
switch (IrpStack->MajorFunction)
{
case IRP_MJ_CREATE:

break;

case IRP_MJ_CLOSE:

break;

case IRP_MJ_DEVICE_CONTROL:
dwIoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
   
switch (dwIoControlCode)
{
         case IOCTL_JOYSTICK_TEST:
         //Add
         pIOPM = MmAllocateNonCachedMemory(sizeof(IOPM));
        
         KdPrint((\"pIOPM = %d\\n\", pIOPM));

           if (pIOPM)
           {
             RtlZeroMemory(pIOPM, sizeof(IOPM));
             Ke386IoSetAccessProcess(PsGetCurrentProcess(), 1);
             Ke386SetIoAccessMap(1, pIOPM);
            
             KdPrint((\"1\"));
           }
           else
             {Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}

//Debug
         KdPrint((\"2\"));

         KeInitializeSpinLock(&BufferLock);
         KeAcquireSpinLock(&BufferLock,&irql);
        
         //Debug
         KdPrint((\"ChipName = %d\\n\", *((PLONG)pvIOBuffer)));
        
         if (*((PLONG)pvIOBuffer)==0)
         WinbondGamePortTest();
         if (*((PLONG)pvIOBuffer)==1)
         ViaGamePortTest();

KeReleaseSpinLock(&BufferLock,irql);

//Add
if (pIOPM)
           {
             Ke386IoSetAccessProcess(PsGetCurrentProcess(), 0);
             Ke386SetIoAccessMap(1, pIOPM);
             MmFreeNonCachedMemory(pIOPM, sizeof(IOPM));
             pIOPM = NULL;
           }

//Debug Information

KdPrint((\"OutputBufferData.fAllResult = %d\\n\", OutputBufferData.fAllResult));
KdPrint((\"OutputBufferData.fFail_pin_button = %d\\n\", OutputBufferData.fFail_pin_button));
KdPrint((\"OutputBufferData.fFail_pin_3 = %d\\n\", OutputBufferData.fFail_pin_3));
KdPrint((\"OutputBufferData.fFail_pin_6 = %d\\n\", OutputBufferData.fFail_pin_6));
KdPrint((\"OutputBufferData.fFail_pin_11 = %d\\n\", OutputBufferData.fFail_pin_11));
KdPrint((\"OutputBufferData.fFail_pin_13 = %d\\n\", OutputBufferData.fFail_pin_13));

KdPrint((\"OutputBufferData.TpinB_low = %d\\n\", OutputBufferData.TpinB_low));
KdPrint((\"OutputBufferData.TpinB_high = %d\\n\", OutputBufferData.TpinB_high));

KdPrint((\"OutputBufferData.Tpin3_high = %d\\n\", OutputBufferData.Tpin3_high));
KdPrint((\"OutputBufferData.Tpin3_low = %d\\n\", OutputBufferData.Tpin3_low));

KdPrint((\"OutputBufferData.Tpin6_high = %d\\n\", OutputBufferData.Tpin6_high));
KdPrint((\"OutputBufferData.Tpin6_low = %d\\n\", OutputBufferData.Tpin6_low));

KdPrint((\"OutputBufferData.Tpin11_high = %d\\n\", OutputBufferData.Tpin11_high));
KdPrint((\"OutputBufferData.Tpin11_low = %d\\n\", OutputBufferData.Tpin11_low));

KdPrint((\"OutputBufferData.Tpin13_high = %d\\n\", OutputBufferData.Tpin13_high));
KdPrint((\"OutputBufferData.Tpin13_low = %d\\n\", OutputBufferData.Tpin13_low));

//pIrp->IoStatus.Information = DataBufferSize;


RtlCopyMemory(pvIOBuffer, &OutputBufferData, sizeof(OutputBufferData));

Irp->IoStatus.Information = sizeof(OutputBufferData);

break;

         default:
      
           Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;

         break;
}
break;
}

// DON\'T get cute and try to use the status field of the irp in the
// return status.  That IRP IS GONE as soon as you call IoCompleteRequest.
ntStatus = Irp->IoStatus.Status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
  
return ntStatus;
}


// Delete the associated device and return
void JoyStickUnload(IN PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING DeviceLinkUnicodeString;
NTSTATUS ntStatus;

RtlInitUnicodeString (&DeviceLinkUnicodeString, L\"\\\\DosDevices\\\\JoyStick\");
ntStatus = IoDeleteSymbolicLink (&DeviceLinkUnicodeString);
if (NT_SUCCESS(ntStatus))
IoDeleteDevice (DriverObject->DeviceObject);
}
Lingfeng
驱动牛犊
驱动牛犊
  • 注册日期2002-11-30
  • 最后登录2008-07-20
  • 粉丝0
  • 关注0
  • 积分11分
  • 威望5点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-06-10 23:07
上接:我的两个测试函数的实现
(这两个函数是我的测试内容.其实大家不要搞清为什么要这样做,这是我们自己的代码,仅在driver中来调用,然后我的driver就把我要的结果返回给我的应用程序.)
void WinbondGamePortTest();
void ViaGamePortTest();




void WinbondGamePortTest()
{
USHORT Tstart;

// Test Button2,7,10,14
Tstart = 0;
WRITE_PORT_UCHAR(&PORT,(UCHAR)0xff);  
        
Tstart++;
while ((READ_PORT_UCHAR(&PORT)& 0xf0)!=0x00) {
Tstart++;
if (Tstart>=10000) {
OutputBufferData.fFail_pin_button = TRUE;
    OutputBufferData.fAllResult = FALSE;
    break;
}
}
OutputBufferData.TpinB_low = Tstart;
while ((READ_PORT_UCHAR(&PORT)& (UCHAR)0xf0)!=0xf0) {
Tstart++;
if (Tstart>=10000) {
OutputBufferData.fFail_pin_button = TRUE;
OutputBufferData.fAllResult = FALSE;
break;
}
}
OutputBufferData.TpinB_high = Tstart;

// Test Pin3--j1_x
Tstart = 0;
WRITE_PORT_UCHAR(&PORT,(UCHAR)0xff);                
Tstart++;
while ((READ_PORT_UCHAR(&PORT)&0x01)!=0x01) {
Tstart++;
if (Tstart>=10000) {
OutputBufferData.fFail_pin_3 = TRUE;
OutputBufferData.fAllResult = FALSE;
break;
}
}
OutputBufferData.Tpin3_high = Tstart;
while ((READ_PORT_UCHAR(&PORT)&0x01)!=0x00) {
Tstart++;
if (Tstart>=10000) {
OutputBufferData.fFail_pin_3 = TRUE;
                        OutputBufferData.fAllResult = FALSE;
                        break;
}
}
OutputBufferData.Tpin3_low = Tstart;

// Test Pin6--j1_y  
Tstart = 0;
WRITE_PORT_UCHAR(&PORT,0xff);                
Tstart++;
while ((READ_PORT_UCHAR(&PORT)&0x02)!=0x02) {
Tstart++;
if (Tstart>=10000) {
OutputBufferData.fFail_pin_6 = TRUE;
                        OutputBufferData.fAllResult = FALSE;
                        break;
}
}
OutputBufferData.Tpin6_high = Tstart;
while ((READ_PORT_UCHAR(&PORT)&0x02)!=0x00) {
Tstart++;
if (Tstart>=10000) {
OutputBufferData.fFail_pin_6 = TRUE;
                        OutputBufferData.fAllResult = FALSE;
                        break;
}
}
OutputBufferData.Tpin6_low = Tstart;

 // Test Pin11--j2_x
  Tstart = 0;
WRITE_PORT_UCHAR(&PORT,0xff);                // Test Pin11--j2_x
Tstart++;
while ((READ_PORT_UCHAR(&PORT)&0x04)!=0x04) {
Tstart++;
if (Tstart>=10000) {
OutputBufferData.fFail_pin_11 = TRUE;
                        OutputBufferData.fAllResult = FALSE;
                        break;
}
}
OutputBufferData.Tpin11_high = Tstart;
while ((READ_PORT_UCHAR(&PORT)&0x04)!=0x00) {
Tstart++;
if (Tstart>=10000) {
OutputBufferData.fFail_pin_11 = TRUE;
                        OutputBufferData.fAllResult = FALSE;
                        break;
}
}
OutputBufferData.Tpin11_low = Tstart;

// Test Pin13--j2_y
Tstart = 0;
WRITE_PORT_UCHAR(&PORT,0xff);                
Tstart++;
while ((READ_PORT_UCHAR(&PORT)&0x08)!=0x08) {
Tstart++;
if (Tstart>=10000) {
OutputBufferData.fFail_pin_13 = TRUE;
                        OutputBufferData.fAllResult = FALSE;
                        break;
}
}
OutputBufferData.Tpin13_high = Tstart;
while ((READ_PORT_UCHAR(&PORT)&0x08)!=0x00) {
Tstart++;
if (Tstart>=10000) {
OutputBufferData.fFail_pin_13 = TRUE;
OutputBufferData.fAllResult = FALSE;
break;
}
}
OutputBufferData.Tpin13_low = Tstart;
}

void ViaGamePortTest()
{
USHORT Tstart;

// Test Button2,7,10,14
Tstart = 0;
WRITE_PORT_UCHAR(&PORT,0xff);                
Tstart++;
while ((READ_PORT_UCHAR(&PORT)&0xf0)!=0x00) {
Tstart++;
if (Tstart>=10000) {
OutputBufferData.fFail_pin_button = TRUE;
    OutputBufferData.fAllResult = FALSE;
    break;
}
}
OutputBufferData.TpinB_low = Tstart;
while ((READ_PORT_UCHAR(&PORT)&0xf0)!=0x00) {
Tstart++;
if (Tstart>=10000) {
OutputBufferData.fFail_pin_button = TRUE;
OutputBufferData.fAllResult = FALSE;
break;
}
}
OutputBufferData.TpinB_high = Tstart;

// Test Pin3--j1_x
Tstart = 0;
WRITE_PORT_UCHAR(&PORT,0xff);              
Tstart++;
while ((READ_PORT_UCHAR(&PORT)&0x01)!=0x01) {
Tstart++;
if (Tstart>=10000) {
OutputBufferData.fFail_pin_3 = TRUE;
OutputBufferData.fAllResult = FALSE;
break;
}
}
OutputBufferData.Tpin3_high = Tstart;
while ((READ_PORT_UCHAR(&PORT)&0x01)!=0x00) {
Tstart++;
if (Tstart>=10000) {
OutputBufferData.fFail_pin_3 = TRUE;
                        OutputBufferData.fAllResult = FALSE;
                        break;
}
}
OutputBufferData.Tpin3_low = Tstart;

// Test Pin6--j1_y
Tstart = 0;
WRITE_PORT_UCHAR(&PORT,0xff);              
Tstart++;
while ((READ_PORT_UCHAR(&PORT)&0x02)!=0x02) {
Tstart++;
if (Tstart>=10000) {
OutputBufferData.fFail_pin_6 = TRUE;
                        OutputBufferData.fAllResult = FALSE;
                        break;
}
}
OutputBufferData.Tpin6_high = Tstart;
while ((READ_PORT_UCHAR(&PORT)&0x02)!=0x00) {
Tstart++;
if (Tstart>=10000) {
OutputBufferData.fFail_pin_6 = TRUE;
                        OutputBufferData.fAllResult = FALSE;
                        break;
}
}
OutputBufferData.Tpin6_low = Tstart;

// Test Pin11--j2_x
Tstart = 0;
WRITE_PORT_UCHAR(&PORT,0xff);                
Tstart++;
while ((READ_PORT_UCHAR(&PORT)&0x04)!=0x04) {
Tstart++;
if (Tstart>=10000) {
OutputBufferData.fFail_pin_11 = TRUE;
                        OutputBufferData.fAllResult = FALSE;
                        break;
}
}
OutputBufferData.Tpin11_high = Tstart;
while ((READ_PORT_UCHAR(&PORT)&0x04)!=0x00) {
Tstart++;
if (Tstart>=10000) {
OutputBufferData.fFail_pin_11 = TRUE;
                        OutputBufferData.fAllResult = FALSE;
                        break;
}
}
OutputBufferData.Tpin11_low = Tstart;

// Test Pin13--j2_y
Tstart = 0;  
WRITE_PORT_UCHAR(&PORT,0xff);                
Tstart++;
while ((READ_PORT_UCHAR(&PORT)&0x08)!=0x08) {
Tstart++;
if (Tstart>=10000) {
OutputBufferData.fFail_pin_13 = TRUE;
                        OutputBufferData.fAllResult = FALSE;
                        break;
}
}
OutputBufferData.Tpin13_high = Tstart;
while ((READ_PORT_UCHAR(&PORT)&0x08)!=0x00) {
Tstart++;
if (Tstart>=10000) {
OutputBufferData.fFail_pin_13 = TRUE;
OutputBufferData.fAllResult = FALSE;
break;
}
}
OutputBufferData.Tpin13_low = Tstart;
}



    小弟现在要在Windows下通过读写I/O 201 Port来检测标准游戏控制器的好坏.因为象标准游戏控制器等这些ISA设备在Windows下都应该被分配了固定的地址.所以我想的话我在内核态应该能读写它.可是我现在的程序进入内核driver中来读写201 port好象没有任何的作用.我不知到是什么原因.
    开始我猜想可能是PnP没有分配201 port给某一个设备.所以我还想自己向PnP 申请分配201 port资源.见我的程序中的HardwareResources结构及IoReportResourceForDetection.结果我加入了上面的代码后就导致冲突.在动态加载时不能启动driver. 所以我就在我的driver中把它给注解了. 但现在的程序我不知怎么不能读写201 port.
     我不知是什么原因.而且我也看到我的主机上201 port的确已经被我的游戏控制器占用了,这也就解答了我为什么不能再向PnP管理器申请分配201 port的原因. 但我还是想不通, 既然我的201 port已经被系统占用, 我却为什么不能读写她呢, 是不是我的driver有什么问题.
 
     请班竹帮忙看看小弟第一次写driver.

小弟还想询问一下班竹的E-mail, 我可以把我的driver寄给班竹还请班竹帮我看看.
游客

返回顶部