|  | 
| 下面是Python做的生成NETID.TXT,系统需要安装Python2.5版本以上。 程序有点缺点,NVIDIA的 %nvnetbus.DeviceDesc%=nvnetBus_Device, PCI\VEN_10DE&DEV_03E6不会生成
 网友jamesdai2002对RIS比较熟悉,以下是他写的程序。在此表示感谢!
 
 #coding:gb2312
 #!/usr/bin/env python
 # -*- Mode: Python; tab-width: 4 -*-
 # 在网卡驱动文件夹内生成.cab文件, 并且生成NETID.TXT
 # Inf Driver parser
 #
 # ======================================================================
 
 from codecs import utf_16_le_decode, BOM_LE, BOM_BE
 from sys import argv, exit as sys_exit
 from os.path import isfile
 from glob import glob
 from cPickle import dump
 from traceback import format_exc
 import os
 
 
 __version__ = '1.0'
 
 ### Compatibility with python 2.1
 if getattr(__builtins__, 'True', None) is None:
 True=1
 False=0
 
 class_guids = ['{4d36e972-e325-11ce-bfc1-08002be10318}']
 classes = ['net']
 
 exclude = ['layout.inf', 'drvindex.inf', 'netclass.inf']
 
 debug = 0
 dumpdev = 0
 
 bustype = { 'USB'   :  1,
 'PCI'   :  5,
 'PCMCIA':  8,
 'ISAPNP': 14
 }
 
 def csv2list(value):
 values = value.strip().split(',')
 for i in range(len(values)):
 values = values.strip()
 return values
 
 def str_lookup(dc, c_key):
 for key in dc.keys():
 if key.lower() == c_key.lower():
 if len(dc[key])>0:
 return dc[key].pop()
 return 'NoDesc'
 
 def item_lookup(dc, c_key):
 for key in dc.keys():
 if key.lower() == c_key.lower():
 return dc[key]
 return None
 
 def fuzzy_lookup(strlist, pattern, ends=None):
 for s in strlist:
 if ends is not None and not s.endswith('services'): continue
 if s.startswith(pattern): return s
 return None
 
 
 def unquote(text):
 return ''.join(text.split('"'))
 
 def skip_inf(line):
 ## Check if driver is requested
 if line.find('=') == -1: return False
 key, value = line.split('=', 1)
 key = key.strip().lower()
 value = value.strip().lower()
 if key == 'class' and value not in classes: return True
 if key == 'classguid' and value not in class_guids: return True
 return False
 
 def parse_line(sections, secname, lineno, line):
 equal = line.find('=')
 comma = line.find(',')
 if equal + comma != -2:
 if equal == -1:
 equal = comma+1
 if comma == -1:
 comma = equal+1
 
 if debug > 2: print '[%d] [%s] equal = %d - comma = %d' % (lineno, secname, equal, comma)
 
 if len(line) + equal + comma == -1:
 if debug: print '[%d] [%s] Invalid line' % (lineno, secname)
 return True
 
 ### Values
 if equal < comma:
 if type(sections[secname]) != type({}):
 sections[secname] = {}
 section = sections[secname]
 key, value = line.split('=', 1)
 key = key.strip()
 
 ### SkipList
 if key == '0':return True
 
 if section.has_key(key):
 values = csv2list(value)
 ### SkipList
 if (len(values) < 2) or (value.find('VEN_') == -1) or (value.find('DEV_') == -1):
 return True
 oldkey = key
 key = key + '_dev_' + values[1]
 
 if debug > 1: print '[%d] [%s] Duplicate key %s will be renamed to %s' % \
 (lineno, secname, oldkey, key)
 
 if secname == 'manufacturer':
 mlist = value.strip().split(',')
 mf = mlist[0].strip().lower()
 if len(mlist) > 1:
 ml = []
 for m in mlist[1:]:
 ml.append('.'.join([mf, m.strip().lower()]))
 mlist = [mf] + ml
 else:
 mlist = [mf]
 
 if debug > 0: print 'Preprocessing Manifacturers:', ', '.join(mlist)
 section[key] = mlist
 if debug > 0: print 'Manifacturer %s=%s' % (key, section[key])
 return True
 
 section[key] = csv2list(value)
 if debug > 1: print '[K] [%d] [%s] %s=%s' % (lineno, secname, key, section[key])
 return True
 
 values = csv2list(line)
 if debug > 1: print '[V] [%d] [%s] Values = %s' % (lineno, secname, ','.join(values))
 sections[secname] = values
 return True
 
 def parse_inf(filename):
 lineno = 0
 name = ''
 sections = {}
 section = None
 data = open(filename).read()
 
 ## Cheap Unicode to ascii
 if data[:2] == BOM_LE or data[:2] == BOM_BE:
 data = utf_16_le_decode(data)[0]
 data = data.encode('ascii', 'ignore')
 
 ## De-inf fixer ;)
 data = 'Copy'.join(data.split(';Cpy'))
 data = '\n'.join(data.split('\r\n'))
 data = ''.join(data.split('\\\n'))
 
 for line in data.split('\n'):
 lineno = lineno + 1
 line = line.strip()
 line = line.split(';', 1)[0]
 line = line.strip()
 
 if len(line) < 1: continue # empty lines
 
 if line[0] == ';': continue # comment
 
 ## We only need network drivers
 if name == 'version' and skip_inf(line):
 if debug > 0: print 'Skipped %s not a network inf' % filename
 return None
 
 ## Section start
 if line.startswith('[') and line.endswith(']'):
 name = line[1:-1].lower()
 sections[name] = {}
 section = sections[name]
 else:
 if section is None: continue
 if not parse_line(sections, name, lineno, line):
 break
 return sections
 
 def scan_inf(filename):
 if debug > 0: print 'Parsing ', filename
 inf = parse_inf(filename)
 if inf is None: return {}
 
 devices = {}
 if inf and inf.has_key('manufacturer'):
 devlist = []
 for sections in inf['manufacturer'].values():
 devlist = devlist + sections
 if debug > 0: print 'Devlist:', ', '.join(devlist)
 for devmap in devlist:
 devmap_k = unquote(devmap.lower())
 if not inf.has_key(devmap_k):
 if debug > 0: print 'Warning: missing [%s] driver section in %s, ignored' % (devmap, filename)
 continue
 devmap = devmap_k
 for dev in inf[devmap].keys():
 if dev.find('%') == -1: continue # bad infs
 
 device = dev.split('%')[1]
 desc = unquote(str_lookup(inf['strings'], device))
 
 sec = inf[devmap][dev][0]
 hid = inf[devmap][dev][1]
 sec = sec.lower()
 
 hid = hid.upper()
 
 if inf.has_key(sec):
 mainsec = sec
 else:
 mainsec = fuzzy_lookup(inf.keys(), sec)
 if mainsec is None: continue
 
 if mainsec.endswith('.services') and inf.has_key(mainsec):
 serv_sec = mainsec
 elif inf.has_key(mainsec + '.services'):
 serv_sec = mainsec + '.services'
 else:
 serv_sec = fuzzy_lookup(inf.keys(), mainsec.split('.')[0], '.services')
 if serv_sec is None:
 if debug > 0: print 'Service section for %s not found, skipping...' % mainsec
 continue
 
 if devices.has_key(hid): continue # Multiple sections define same devices
 
 if dumpdev: print 'Desc:', desc
 if dumpdev: print 'hid:', hid
 
 tmp = item_lookup(inf[serv_sec], 'addservice')
 if tmp is None:
 if debug > 0: print 'Warning: addservice not found %s' % serv_sec
 continue
 service = tmp[0]
 sec_service = tmp[2]
 
 driver = None
 if (type(inf[mainsec]) == type({})
 and inf[mainsec].has_key('copyfiles')):
 sec_files = inf[mainsec]['copyfiles'][0].lower()
 if type(inf[sec_files]) == type([]):
 driver = inf[sec_files][0]
 
 if driver is None:
 if not inf.has_key(sec_service.lower()):
 print 'Warning missing ServiceBinary for %s' % sec_service
 print 'Please report including this file: %s\n' % filename
 continue
 driver = inf[sec_service.lower()]['ServiceBinary'][0].split('\\').pop()
 
 if dumpdev: print 'Driver', driver
 
 try:
 char = eval(inf[mainsec]['Characteristics'][0])
 except:
 char = 132
 
 if dumpdev: print 'Characteristics', char
 try:
 btype = int(inf[mainsec]['BusType'][0])
 except:
 try:
 btype = bustype[hid.split('\\')[0]]
 except:
 btype = 0
 
 if dumpdev: print 'BusType', btype
 if dumpdev: print 'Service', service
 if dumpdev: print '-'*78
 
 
 devices[hid] = { 'desc' : desc,
 'char' : str(char),
 'btype': str(btype),
 'drv'  : driver,
 'svc'  : service,
 'inf'  : filename.split('/').pop() }
 return devices
 
 
 if __name__ == '__main__':                  #主模块
 if len(argv) != 2:
 print 'Usage %s: directory_with_infs' % argv[0]
 sys_exit(-1)
 
 if not os.path.isdir(argv[1]):         #命令行参数必须是一个驱动文件夹
 print 'Usage %s: directory_with_infs' % argv[0]
 sys_exit(-1)
 else:
 rootpath = argv[1]
 
 devlist = {}
 
 for root,dirs,files in os.walk(rootpath):
 if len(glob(root + '/*.inf')) >= 1:                #目录内inf文件个数>=1个则进行处理
 entry =os.path.split(root)                     #分割全路径
 cabfilename=entry[len(entry)-1]                #使用分割后的最后一项作为压缩包名词
 if os.path.isfile(root + '\\' + cabfilename +'.CAB'):
 os.remove(root + '\\' + cabfilename +'.CAB')
 
 cab_arch_cmd = 'cabarc -m lzx:21 n ' + cabfilename.upper() + '.CAB ' + root +'\\*  '
 print cab_arch_cmd
 os.system(cab_arch_cmd)
 os.rename( cabfilename.upper()+ '.CAB', root+'\\'+cabfilename.upper()+ '.CAB')
 for inffile in glob(root + '/*.inf'):  #获取当前路径下面所有的inf文件
 print "Get nic hardware id ---> "+ inffile
 if inffile.split('/').pop() not in exclude:
 try:
 devlist.update(scan_inf(inffile))
 except:
 print '--'
 print 'Error parsing %s' % inffile
 print 'Please report sending the inf file and this message:'
 print '---- CUT HERE ----'
 print '%s Version %s\n' % (argv[0], __version__)
 print format_exc()
 print '---- CUT HERE ----'
 
 print 'Compiled %d drivers' % len(devlist)
 
 #    fd = open('devlist.cache', 'wb')
 #    dump(devlist, fd)
 #    fd.close()
 #    print 'generated devlist.cache'
 
 fd = open('NETID.TXT', 'w')
 drvhash = {}
 for nic in devlist.items():
 entry = nic[0].split('&')
 if len(entry) < 2: continue # just to be sure
 if not entry[0].startswith('PCI'): continue # skip usb
 vid = entry[0].split('VEN_').pop().lower()
 pid = entry[1].split('DEV_').pop().lower()
 key = (vid, pid)
 entry = os.path.split(nic[1]['inf'])      #分割inf文件全路径变成路径和文件名称
 cabpath = entry[0]                        #取分割后的路径
 entry = os.path.split(cabpath)
 cabfilename= entry[1]
 line = 'PCI\\VEN_%4s&DEV_%4s="%s"\n' % (vid, pid, cabpath + '\\' + cabfilename)
 drvhash[key] = line.upper()
 
 drvlist = drvhash.values()
 drvlist.sort()
 fd.writelines(drvlist)
 fd.close()
 
 
 print 'generated NETID.TXT'
 
 [ 本帖最后由 zhaohj 于 2010-4-23 16:25 编辑 ]
 | 
 |