DriverWorks的KPciConfiguration不支持x64平台的解决方法

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

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

检查DriverWorks的源程序 Kpcicfg.cpp 后发现,在 AMD64 模式下,KPciConfiguration::Enumerate函数是不被编译的:
None.gif #if  ! _WDM_
None.gif
#if  !(defined(_IA64_) || defined(_AMD64_))
None.gif
None.gifBOOLEAN KPciConfiguration::Enumerate(
None.gif    KPciSlot
&  slot,
None.gif    PUSHORT VendorId,
None.gif    PUSHORT DeviceId)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    ULONG status;
InBlock.gif    UCHAR headtype;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
struct dot.gif{
InBlock.gif        USHORT VendorID;
InBlock.gif        USHORT DeviceID;
ExpandedSubBlockEnd.gif    }
 slotdata;
InBlock.gif
InBlock.gif
InBlock.gif    
if ( (slot.Slot() != 0xffffffff|| (slot.Bus() != 0) )
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
// determine if the current slot is single function device
InBlock.gif
        status = HalGetBusDataByOffset(
InBlock.gif            PCIConfiguration,
InBlock.gif            slot.Bus(),
InBlock.gif            slot.Slot(),
InBlock.gif            
&headtype,
InBlock.gif            HeaderOffset(HeaderType),
InBlock.gif            
1);
InBlock.gif
InBlock.gif        
if ( (slot.Function() == 0&&
InBlock.gif             (status 
!= 0&&
InBlock.gif             (status 
!= 2&&
InBlock.gif             ((headtype 
& 0x80)==0) ) // bit 7 of header type is 1 for multi
ExpandedSubBlockStart.gifContractedSubBlock.gif
        dot.gif{
InBlock.gif            slot.IncrementDevice();
ExpandedSubBlockEnd.gif        }

InBlock.gif        
else
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            slot.Increment();
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif    
else
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        slot.Increment();
ExpandedSubBlockEnd.gif    }

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

InBlock.gif            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                slot.IncrementBus();
ExpandedSubBlockEnd.gif            }

InBlock.gif            
continue;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
else if (status == 2)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            slot.Increment();
InBlock.gif            
continue;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
else
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
*VendorId = slotdata.VendorID;
InBlock.gif            
*DeviceId = slotdata.DeviceID;
InBlock.gif            
return TRUE;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif
#endif
None.gif

如果去掉#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,暂时修改函数如下:

None.gif #if  ! _WDM_
None.gif
// #if !(defined(_IA64_) || defined(_AMD64_))
None.gif

None.gifBOOLEAN KPciConfiguration::Enumerate(
None.gif    KPciSlot
&  slot,
None.gif    PUSHORT VendorId,
None.gif    PUSHORT DeviceId)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    ULONG status;
InBlock.gif    UCHAR headtype;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
struct dot.gif{
InBlock.gif        USHORT VendorID;
InBlock.gif        USHORT DeviceID;
ExpandedSubBlockEnd.gif    }
 slotdata;
InBlock.gif
InBlock.gif
InBlock.gif    
if ( (slot.Slot() != 0xffffffff|| (slot.Bus() != 0) )
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
// determine if the current slot is single function device
InBlock.gif
        status = HalGetBusDataByOffset(
InBlock.gif            PCIConfiguration,
InBlock.gif            slot.Bus(),
InBlock.gif            slot.Slot(),
InBlock.gif            
&headtype,
InBlock.gif            HeaderOffset(HeaderType),
InBlock.gif            
1);
InBlock.gif
InBlock.gif        
if ( (slot.Function() == 0&&
InBlock.gif             (status 
!= 0&&
InBlock.gif             (status 
!= 2&&
InBlock.gif             ((headtype 
& 0x80)==0) ) // bit 7 of header type is 1 for multi
ExpandedSubBlockStart.gifContractedSubBlock.gif
        dot.gif{
InBlock.gif            slot.IncrementDevice();
ExpandedSubBlockEnd.gif        }

InBlock.gif        
else
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            slot.Increment();
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif    
else
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        slot.Increment();
ExpandedSubBlockEnd.gif    }

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

InBlock.gif            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                slot.IncrementBus();
ExpandedSubBlockEnd.gif            }

InBlock.gif            
continue;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
else if (status == 2)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            slot.Increment();
InBlock.gif            
continue;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
else
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
*VendorId = slotdata.VendorID;
InBlock.gif            
*DeviceId = slotdata.DeviceID;
InBlock.gif            
return TRUE;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif
// #endif
 

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

转载于:https://www.cnblogs.com/zealsoft/archive/2006/07/09/446510.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值