|
下面是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 编辑 ] |
|