自动识别网卡型号

来源:互联网 发布:四维星手机展示软件 编辑:程序博客网 时间:2024/06/02 07:27

DOS下,用TC编译

       网卡在PCI DEVICE上的BUS#,DEVICE#,FUCTION#,会随着网卡厂家不同而不同,需要先通过枚举PCI DEVICE来获得正确的vendorID和deviceID。

      因为需要操作32位PCI配置端口,需要内嵌汇编和机器码访问

/* 读32位端口 */

#define PDI_BUS_SHIFT   8
#define PDI_BUS_SIZE    8
#define PDI_BUS_MAX     0xFF
#define PDI_BUS_MASK    0xFF00

#define PDI_DEVICE_SHIFT   3
#define PDI_DEVICE_SIZE    5
#define PDI_DEVICE_MAX     0x1F
#define PDI_DEVICE_MASK    0x00F8

#define PDI_FUNCTION_SHIFT   0
#define PDI_FUNCTION_SIZE    3
#define PDI_FUNCTION_MAX     0x7
#define PDI_FUNCTION_MASK    0x0007

#define MK_PDI(bus,dev,func) (WORD)((bus&PDI_BUS_MAX)<<PDI_BUS_SHIFT | (dev&PDI_DEVICE_MAX)<<PDI_DEVICE_SHIFT | (func&PDI_FUNCTION_MAX) )


/* PCI配置空间寄存器 */
#define PCI_CONFIG_ADDRESS      0xCF8
#define PCI_CONFIG_DATA         0xCFC


/* 填充PCI_CONFIG_ADDRESS */
#define MK_PCICFGADDR(bus,dev,func) (DWORD)(0x80000000L | (DWORD)MK_PDI(bus,dev,func)<<8)


DWORD inpd(int portid)   
{
 DWORD dwRet;
 asm mov dx, portid;
 asm lea bx, dwRet;
 __emit__(
  0x66,0x50, // push EAX
  0x66,0xED, // in EAX,DX
  0x66,0x89,0x07, // mov [BX],EAX
  0x66,0x58); // pop EAX
 return dwRet;
}

/* 写32位端口 */
void outpd(int portid, DWORD dwVal)
{
 asm mov dx, portid;
 asm lea bx, dwVal;
 __emit__(
  0x66,0x50, // push EAX
  0x66,0x8B,0x07, // mov EAX,[BX]
  0x66,0xEF, // out DX,EAX
  0x66,0x58); // pop EAX
 return;
}

在枚举过程中寻找对应的网卡的vendorID和deviceID,如RTL的vendorID 是10EC,INTEL的是8086。通过vendorID和deviceID就可以识别对应的网卡了,如我的位 10EC,8139   就是RTL8139的网卡。

int main(void)
{
 int bus, dev, func;
 int i;
 DWORD dwAddr;
 DWORD dwData;
 FILE* hF;
 char szFile[0x10];

 printf("/n");
 printf("Bus#/tDevice#/tFunc#/tVendor/tDevice/tClass/tIRQ/tIntPin/n");

 /* 枚举PCI设备 */
 for(bus = 0; bus <= PDI_BUS_MAX; ++bus) {
  for(dev = 0; dev <= PDI_DEVICE_MAX; ++dev) {
   for(func = 0; func <= PDI_FUNCTION_MAX; ++func) {
    /* 计算地址 */
    dwAddr = MK_PCICFGADDR(bus, dev, func);
    
    /* 获取厂商ID */
    outpd(PCI_CONFIG_ADDRESS, dwAddr);
    dwData = inpd(PCI_CONFIG_DATA);

    /* 判断设备是否存在。FFFFh是非法厂商ID */
    if ((WORD)dwData != 0xFFFF) {
     /* bus/dev/func */
     printf("%2.2X/t%2.2X/t%1X/t", bus, dev, func);

     /* Vendor/Device */
     printf("%4.4X/t%4.4X/t", (WORD)dwData, dwData>>16);

     /* Class Code */
     outpd(PCI_CONFIG_ADDRESS, dwAddr | 0x8);
     dwData = inpd(PCI_CONFIG_DATA);
     printf("%6.6lX/t", dwData>>8);

     /* IRQ/intPin */
     outpd(PCI_CONFIG_ADDRESS, dwAddr | 0x3C);
     dwData = inpd(PCI_CONFIG_DATA);
     printf("%d/t", (BYTE)dwData);
     printf("%d", (BYTE)(dwData>>8));

     printf("/n");

MSN: twinliwu@hotmail.com

 

原创粉丝点击