posts - 27,  comments - 68,  trackbacks - 0
今天移植以前用DriverWorks编写的一个驱动到x64平台上,编译时没有什么问题,但链接的时候发现无法找到KPciConfiguration::Enumerate,经过一段时间的探索,找到了一种临时解决方案。

由于
KPciConfiguration 的构造函数中也使用了这个函数,而且程序中大量使用了KPciConfiguration类,这意味着要大量修改代码,真是头痛

检查DriverWorks的源程序 Kpcicfg.cpp 后发现,在 AMD64 模式下,KPciConfiguration::Enumerate函数是不被编译的:
#if ! _WDM_
#if !(defined(_IA64_) || defined(_AMD64_))

BOOLEAN KPciConfiguration::Enumerate(
    KPciSlot
& slot,
    PUSHORT VendorId,
    PUSHORT DeviceId)
{
    ULONG status;
    UCHAR headtype;

    
struct {
        USHORT VendorID;
        USHORT DeviceID;
    }
 slotdata;


    
if ( (slot.Slot() != 0xffffffff|| (slot.Bus() != 0) )
    
{
        
// determine if the current slot is single function device
        status = HalGetBusDataByOffset(
            PCIConfiguration,
            slot.Bus(),
            slot.Slot(),
            
&headtype,
            HeaderOffset(HeaderType),
            
1);

        
if ( (slot.Function() == 0&&
             (status 
!= 0&&
             (status 
!= 2&&
             ((headtype 
& 0x80)==0) ) // bit 7 of header type is 1 for multi
        {
            slot.IncrementDevice();
        }

        
else
        
{
            slot.Increment();
        }

    }

    
else
    
{
        slot.Increment();
    }


    
while (TRUE)
    
{
        status 
= HalGetBusData(PCIConfiguration, slot.Bus(), slot.Slot(), &slotdata, 4);
        
        
if (status == 0)
        
{
            
if ( slot.Bus() == 255 )
            
{
                
return FALSE;
            }

            
else
            
{
                slot.IncrementBus();
            }

            
continue;
        }

        
else if (status == 2)
        
{
            slot.Increment();
            
continue;
        }

        
else
        
{
            
*VendorId = slotdata.VendorID;
            
*DeviceId = slotdata.DeviceID;
            
return TRUE;
        }

    }

}


#endif

如果去掉#if语句强行编译,发现原来是因为HalGetBusData函数不被x64支持,所以不能编译成功。在MSDN的文档中的确提到这个函数是过时的,建议使用即插即用 (PnP) 管理器的 IRP_MN_START_DEVICE 请求来获取这些资源,在中文知识库中还可以找到一个例子:http://support.microsoft.com/?scid=kb;zh-cn;253232。在网上还找到另一个英文的例子http://www.hollistech.com/Resources/Misc%20articles/getbusdata.doc

不过要全部改写代码,担心时间不够,所以想到另外一个临时解决方案,在x64下
HalGetBusDataByOffset仍然是支持的,所以利用HalGetBusDataByOffset代替HalGetBusData,暂时修改函数如下:

#if ! _WDM_
//#if !(defined(_IA64_) || defined(_AMD64_))

BOOLEAN KPciConfiguration::Enumerate(
    KPciSlot
& slot,
    PUSHORT VendorId,
    PUSHORT DeviceId)
{
    ULONG status;
    UCHAR headtype;

    
struct {
        USHORT VendorID;
        USHORT DeviceID;
    }
 slotdata;


    
if ( (slot.Slot() != 0xffffffff|| (slot.Bus() != 0) )
    
{
        
// determine if the current slot is single function device
        status = HalGetBusDataByOffset(
            PCIConfiguration,
            slot.Bus(),
            slot.Slot(),
            
&headtype,
            HeaderOffset(HeaderType),
            
1);

        
if ( (slot.Function() == 0&&
             (status 
!= 0&&
             (status 
!= 2&&
             ((headtype 
& 0x80)==0) ) // bit 7 of header type is 1 for multi
        {
            slot.IncrementDevice();
        }

        
else
        
{
            slot.Increment();
        }

    }

    
else
    
{
        slot.Increment();
    }


    
while (TRUE)
    
{
//        status = HalGetBusData(PCIConfiguration, slot.Bus(), slot.Slot(), &slotdata, 4);
        status = HalGetBusDataByOffset(PCIConfiguration, slot.Bus(), slot.Slot(), &slotdata, 04);
        
        
if (status == 0)
        
{
            
if ( slot.Bus() == 255 )
            
{
                
return FALSE;
            }

            
else
            
{
                slot.IncrementBus();
            }

            
continue;
        }

        
else if (status == 2)
        
{
            slot.Increment();
            
continue;
        }

        
else
        
{
            
*VendorId = slotdata.VendorID;
            
*DeviceId = slotdata.DeviceID;
            
return TRUE;
        }

    }

}


//#endif
 

目前从测试的结果来看,这样做是可以运行的。但是 HalGetBusDataByOffset 也是过时的,不推荐使用的函数,将来有时间还是按照微软的建议将程序彻底改写。

posted on 2006-07-09 16:32 zealsoft 阅读(814) 评论(0)  编辑 收藏 引用 所属分类: 驱动开发

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


欢迎访问我的学术博客

<2006年7月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

常用链接

留言簿(13)

随笔分类(28)

随笔档案(27)

搜索

  •  

积分与排名

  • 积分 - 55567
  • 排名 - 382

最新评论

阅读排行榜

评论排行榜