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


    今天移植以前用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也是过时的、不推荐使用的函数,将来有时间还是按照微软的建议将程序彻底改写。

  • 相关阅读:
    maven私服
    docker
    mysql ip
    jenkins安装
    centeros7防火墙操作
    centeros7 gitlap安装
    nexus安装及使用(maven私服掌握)
    idea永久激活使用
    redis密码验证
    Nginx服务优化配置
  • 原文地址:https://www.cnblogs.com/zealsoft/p/446510.html
Copyright © 2020-2023  润新知