⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcicfg.cpp

📁 windwos环境下查看PCI驱动信息的源代码。
💻 CPP
📖 第 1 页 / 共 3 页
字号:
   for (int i = 0 ; i < sizeof(cfg)/sizeof(DWORD) ; i++)
      {
      WORD hi, lo ;
      if (!read_DWORD_register(bus,device,func,i*sizeof(DWORD),&lo,&hi))
	 return 0 ;
      ((WORD*)&cfg)[2*i] = lo ;
      ((WORD*)&cfg)[2*i+1] = hi ;
      }
   return &cfg ;
}

//----------------------------------------------------------------------

static const char *get_subclass_name(int classcode, int subclass)
{
   if (classcode < 0 || classcode >= lengthof(subclass_data) ||
       subclass_data[classcode] == 0)
      return "???" ;
   const subclass_info *subinfo = subclass_data[classcode] ;
   while (subinfo->subclass_code != -1)
      {
      if (subinfo->subclass_code == subclass)
	 return subinfo->subclass_name ;
      subinfo++ ;
      }
   return "???" ;
}

//----------------------------------------------------------------------

static const char *get_vendor_name(WORD vendorID)
{
   if (vendorID == 0x0000 || vendorID == 0xFFFF)
      return "Not Present" ;
   char *next ;
   for (char *data = device_ID_data ; data ; data = next)
      {
      next = *((char**)data) ;
      data += sizeof(char*) ;
      data += sizeof(WORD) ;		// skip the length field
      WORD ID = *((WORD*)data) ;
      data += sizeof(WORD) ;
      if (ID == vendorID)
	 return data ;
      }
   // if we get here, there was no matching ID in the file,
   return "???" ;
}

//----------------------------------------------------------------------

static const char *get_device_name(WORD vendorID, WORD deviceID)
{
   if (vendorID == 0x0000 || vendorID == 0xFFFF || deviceID == 0xFFFF)
      return "Not Present" ;
   char *data = device_ID_data ;
   while (data)
      {
      char *next = *((char**)data) ;
      data += sizeof(char*) ;
      WORD length = *((WORD*)data) ;
      data += sizeof(WORD) ;
      char *end = data + length ;
      WORD ID = *((WORD*)data) ;
      data += sizeof(WORD) ;
      if (ID == vendorID)
	 {
	 // OK, we've found the vendor, now scan for the device
	 // 1. skip the vendor name
	 while (*data)
	    data++ ;
	 if (data < end)		// skip the NUL
	    data++ ;
	 // 2. check each device ID in turn
	 while (data < end)
	    {
	    ID = *((WORD*)data) ;
	    data += sizeof(WORD) ;
	    if (ID == deviceID)
	       return data ;
	    while (*data)
	       data++ ;
	    data++ ;			// skip the NUL
	    }
	 // if we get here, there was no match for the device ID
	 break ;
	 }
      data = next ;
      }
   // if we get here, there was no matching ID in the file,
   return "???" ;
}

//----------------------------------------------------------------------

static int load_device_info(FILE *fp, char * &format_string,
			    char const * &enum_list)
{
   if (!fp)
      return FALSE ;
   long int filesize = lseek(fileno(fp),0L,SEEK_END) ;
   fseek(fp,0L,SEEK_SET) ;		// back to beginning of file
   char line[MAX_LINE] ;
   // read until we find the actual beginning of the device definition
   do {
      line[0] = '\0' ;			// catch EOF or read error
      fgets(line,sizeof(line),fp) ;
      } while (!feof(fp) && strncmp(line,"!begin",6) != 0) ;
   int datasize = (int)(filesize - ftell(fp)) ;
   char *buffer = (char*)malloc(datasize+3) ;
   int readsize ;
   char *newline ;
   if (buffer && (readsize = fread(buffer,sizeof(char),datasize,fp)) > 0)
      {
      buffer[readsize] = '\0' ;		// ensure proper string termination
      format_string = buffer ;
      enum_list = format_string ;
      if (*enum_list == '\n')
	 enum_list++ ;
      // look forward to end of format string, then chop into two strings
      do {
	 newline = strchr(enum_list,'\n') ;
	 if (newline && strncmp(newline+1,"!end",4) == 0)
	    {
	    newline[1] = '\0' ;
	    newline = strchr(newline+2,'\n') ;
	    if (newline)
	       enum_list = newline ;
	    else
	       enum_list = newline+2 ;
	    break ;
	    }
	 if (newline)
	    enum_list = newline+1 ;
	 } while (newline) ;
      }
   else
      return FALSE ;
   // scan until we find the actual beginning of the 'enum' definition
   char *result = (char*)enum_list ;
   newline = (char*)enum_list ;
   do {
      newline = strchr(newline,'\n') ;
      if (newline)
	 {
	 newline++ ;
	 if (strncmp(newline,"!enum",5) == 0)
	    break ;
	 }
      } while (newline) ;
   if (newline)
      {
      newline++ ;
      // format of the enum:
      //    !enum enum_name
      //     enumvalue0
      //     enumvalue1
      //     ...
      //     enumvalueN
      //    !end
      do {
	 // extract the enum's name
	 //assert(strcmp(newline,"!enum",5) == 0) ;
	 newline = skip_whitespace(newline+5) ;
	 const char *end = strchr(newline,'\n') ;
	 if (!end)
	    break ;
	 memcpy(result,newline,end-newline+1) ;
	 result += (end-newline+1) ;
	 newline = (char*)end+1 ;
	 while (*newline && strncmp(newline,"!end",4) != 0)
	    {
	    newline = skip_whitespace(newline) ;
	    char *end = strchr(newline,'\n') ;
	    if (!end)
	       end = strchr(newline,'\0') ;
	    char *next = *end ? end+1 : end ;
	    while (end > newline && isspace(end[-1]))
	       end-- ;
	    memcpy(result,newline,end-newline) ;
	    result[end-newline] = '\n' ;
	    result += (end-newline+1) ;
	    newline = next ;
	    }
	 *result++ = '\0' ;
	 // one enum is done, so scan for the next (if any)
	 while ((newline = strchr(newline,'\n')) != 0)
	    {
	    newline++ ;
	    if (strncmp(newline,"!enum",5) == 0)
	       break ;
	    }
	 } while (newline && *newline) ;
      }
   *result++ = '\0' ;
   return TRUE ;
}

//----------------------------------------------------------------------

static int know_device(WORD vendor, WORD device,
		       char * &format_string, char const * &enum_list)
{
   if (vendor == 0x0000 || vendor == 0xFFFF || device == 0xFFFF)
      return FALSE ;
   // see if there's a data file for this device
   int dir_len = strlen(exe_directory) ;
   char *device_file = (char*)malloc(dir_len+14) ;
   if (device_file)
      {
      sprintf(device_file,"%s/%4.04X%4.04X.PCI",exe_directory,vendor,device) ;
      device_file[dir_len+13] = '\0' ;
      FILE *fp = fopen(device_file,"r") ;
      free(device_file) ;
      if (fp)
	 {
	 int success = load_device_info(fp,format_string,enum_list) ;
	 fclose(fp) ;
	 return success ;
	 }
      }
   return FALSE ;
}

//----------------------------------------------------------------------

static void write_bits(WORD bitflags, const char *const *flagnames, int numbits)
{
   for (int i = 0 ; i < numbits ; i++)
      {
      if ((bitflags & (1 << i)) != 0 && flagnames[i])
	 printf(" %s",flagnames[i]) ;
      }
}

#define WRITE_CMD_BITS(x) write_bits((x),command_bits,lengthof(command_bits))
#define WRITE_STAT_BITS(x) write_bits((x),status_bits,lengthof(status_bits))
#define WRITE_BCTRL_BITS(x) write_bits((x),bctrl_bits,lengthof(bctrl_bits))

//----------------------------------------------------------------------

static DWORD extract_field(const char *&s, const char *cfg)
{
   DWORD value = 0 ;
   int addr = 0 ;
   while (*s == '[' || *s == '|')
      {
      s++ ;
      int lowbit = 0 ;
      int highbit = 7 ;
      while (*s && isxdigit(*s))
	 {
	 int digit = *s - '0' ;
	 if (digit > 9)
	    digit -= ('A'-10-'0') ;
	 addr = 16*addr + digit ;
	 s++ ;
	 }
      addr &= 0x00FF ;
      if (*s == ':')
	 {
	 s++ ;
	 while (*s && isdigit(*s))
	    {
	    lowbit = 10*lowbit + (*s-'0') ;
	    s++ ;
	    }
	 if (*s == '-')
	    {
	    highbit = 0 ;
	    s++ ;
	    while (*s && isdigit(*s))
	       {
	       highbit = 10*highbit + (*s-'0') ;
	       s++ ;
	       }
	    }
	 else
	    highbit = lowbit ;
	 if (highbit < lowbit)
	    {
	    int tmp = lowbit ;
	    lowbit = highbit ;
	    highbit = tmp ;
	    }
	 if (highbit > 31)
	    {
	    if (highbit - lowbit >= 32)
	       highbit = 31 ;
	    }
	 if (lowbit/8)
	    {
	    int adj = lowbit/8 ;
	    addr += adj ;
	    adj *= 8 ;
	    lowbit -= adj ;
	    highbit -= adj ;
	    }
	 }
      DWORD prev_value = value << (highbit-lowbit+1) ;
      if (highbit > 16)
	 {
	 value = cfg[addr] + (cfg[addr+1] << 8) + ((DWORD)cfg[addr+2] << 16) +
		 ((DWORD)cfg[addr+3] << 24) ;
	 }
      else if (highbit > 8)
	 value = cfg[addr] + (cfg[addr+1] << 8) ;
      else
	 value = cfg[addr] ;
      DWORD mask = 0 ;
      for (int i = lowbit ; i <= highbit ; i++)
	 mask |= (1L << i-lowbit) ;
      while (lowbit-- > 0)
         value >>= 1 ;
      value &= mask ;
      if (*s == '<')
	 {
	 s++ ;
	 int shift = 0 ;
	 while (*s && isdigit(*s))
	    {
	    shift = 10*shift + (*s-'0') ;
	    s++ ;
	    }
	 while (shift-- > 0)
	    {
	    value <<= 1 ;
	    prev_value <<= 1 ;
	    }
	 }
      if (*s == '*')
	 {
	 s++ ;
	 unsigned mult = 0 ;
	 while (*s && isdigit(*s))
	    {
	    mult = 10*mult + (*s-'0') ;
	    s++ ;
	    }
	 if (mult == 0)
	    mult =1 ;
	 value *= mult ;
	 prev_value *= mult ;
	 }
      value |= prev_value ;
      if (*s == '+')
	 {
	 *s++ ;
	 int negative = 0 ;
	 if (*s == '-')
	    negative = 1 ;
	 long offset = 0 ;
	 while (*s && isdigit(*s))
	    {
	    offset = 10*offset + (*s-'0') ;
	    s++ ;
	    }
	 if (negative)
	    offset = -offset ;
	 value += offset ;
	 }
      if (*s == ']')
	 {
	 s++ ;
	 break ;
	 }
      }
   return value ;
}

//----------------------------------------------------------------------

static void format_number(FILE *out, DWORD val, int width, int base)
{
   char buf[38] ;			// enough for DWORD, plus fudge factor
   static char digits[] = "0123456789ABCDEF" ;
   int count = 0 ;
   do {
      int digit = (int)(val % base) ;
      val /= base ;
      buf[count++] = digits[digit] ;
      } while (val) ;
   buf[count] = '\0' ;
   for (int i = 0 ; i < count/2 ; i++)
      {
      char tmp = buf[count-i-1] ;
      buf[count-i-1] = buf[i] ;
      buf[i] = tmp ;
      }
   if (count < width)
      {
      for (int i = count ; i < width ; i++)
	 fputc(base == 10 ? ' ' : '0',out) ;
      }
   fputs(buf,out) ;
   return ;
}

//----------------------------------------------------------------------

static void format_enabled(FILE *out, DWORD value, int width)
{
   int w = value ? 6 : 7 ;
   for (int i = w ; i < width ; i++)
      fputc(' ',out) ;
   fputs(value ? "enable" : "disable",out) ;
}

//----------------------------------------------------------------------

static void format_flag(FILE *out, DWORD value, int width)
{
   for (int i = 1 ; i < width ; i++)
      fputc(' ',out) ;
   fputc(value ? '

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -