function cmp_hash(a, b) if (a.hash < b.hash) then cmp_hash = CMP_LESS elseif (a.hash > b.hash) then cmp_hash = CMP_GREATER else cmp_hash = CMP_EQUAL end if end function function PadDigits(n, totaldigits) PadDigits = right(string(totaldigits,"0") & hex(n), totaldigits) end function public const CMP_LESS = -1 public const CMP_EQU = 0 public const CMP_GREATER = 1 function array_swap0(values, i,j) dim temp : set temp = values(i) set values(i) = values (j) set values(j) = temp end function function QSort(byref values, loBound,hiBound) dim pivot,loSwap,hiSwap if hiBound - loBound = 1 then if cmp_hash(values(loBound), values(hiBound)) = CMP_GREATER then array_swap0 values,loBound,hiBound end if exit function end If dim pivotIndex : pivotIndex = int((loBound + hiBound) / 2) set pivot = values(pivotIndex) array_swap0 values, pivotIndex, loBound loSwap = loBound + 1 hiSwap = hiBound do while (loSwap < hiSwap) and (cmp_hash(values(loSwap), pivot) <> CMP_GREATER) loSwap = loSwap + 1 wend while (cmp_hash(values(hiSwap), pivot) = CMP_GREATER) hiSwap = hiSwap - 1 wend if loSwap < hiSwap then array_swap0 values, loSwap, hiSwap end If loop while loSwap < hiSwap set values(loBound) = values(hiSwap) set values(hiSwap) = pivot if loBound < hiSwap-1 then QSort values, loBound, hiSwap-1 if hiSwap+1 < hibound then QSort values, hiSwap+1, hiBound end function function StartSort(byref values, size) if UBound(values) < 1 then exit function QSort values, LBound(values), size end function class lineobj public hash public line end class function binary32(val) while val > 4294967295 val = val - 4294967296 wend binary32 = val end function function binary24(val) while val > 16777215 val = val - 16777216 wend binary24 = val end function 'option explicit dim dev_id,inf_path,dev_name,inf_name,drv_date,drv_version dim strings dim file_dir dim dir dim tab,output dim catpresent dim starttime,point1 dim r_beg,r_date,r_version dim r_identS,r_str,r_strORind,r_subs dim regex_mansect,regex_strsect,regex_version,regex_devs_l,regex_devs_r dim regex_devid,regex_mandef,regex_devdef,regex_strings,regex_sectnames dim lines(1000000) dim hash(1000000) dim numlines 'dim HashOutput,Hashtest dim indexFile dim hashFile numlines = 0 file_dir = WScript.Arguments.Item(0) dir = WScript.Arguments.Item(1) & "\" temp_drp = WScript.Arguments.Item(2) & "\" tab = chr(9) output = "" WScript.Echo "dir: " & dir starttime = timer point1 = starttime r_beg = "^[ \t]*" r_date = "(%[^%]*%|(?:[\w/ ])+)" r_version = "(%[^%]*%|(?:[\w/ .])+)" r_identS = "([^; \t\r\n][^;\t\r\n]*[^; \t\r\n])" r_str = "(?:""([^\r\n""]*)""|([^\r\n;]*))" ' %var% "str" text r_strORind = "(?:%([^%\r\n]+)%|""([^\r\n]+)""|([^;=\r\n]+))" 'r_subs = "(?:&(?:VEN_....|DEV_....|PID_....|SUBCLASS_..|FW[\w]+|Ozonic|TYP_.|ID_.|FN_..|PCI_........|SUBSYS_\w{8}|FireDTV_[\w/]+))*" r_subs = "(?:&(?:[\w/]+))*" ' sections regex_mansect = r_beg & "\[Manufacturer\](?:([\s\S]*?)" & r_beg & "(?=\[)|([\s\S]*))" regex_strsect = r_beg & "\[strings\](?:([\s\S]*?)" & r_beg & "(?=\[)|([\s\S]*))" regex_version = r_beg & "\[Version\][\s\S]*?^[ \t]*DriverVer[ \t]*=[ \t]*" & r_date & "(?:[ \t]*,[ \t]*" & r_version & ")?" regex_devs_l = "^[ \t]*" & "\[(" regex_devs_r = ")\](?:([\s\S]*?)" & r_beg & "(?=\[)|([\s\S]*))" ' ,ID,ID, ... regex_devid = ",[ \t]*""?([^ \t\r\n,][^ \t\r\n&,]+" & r_subs & ")" ' name = sectname,suffix,suffix,... regex_mandef = r_beg & "[^;\r\n=]*=[ \t]*([^;\r\n]*)" ' name = driver,ID,ID,... regex_devdef = r_beg & r_strORind & "[^=\r\n]*=[^\r\n,]*" & "([^;\r\n]*)" ' variable = "str" regex_strings = r_beg & r_identS & "[ \t]*=[ \t]*" & r_str regex_sectnames = "(?:,?[ \t]*""([^""\r\n]+)""|,?[ \t]*([^,\t\r\n;]+[^,\t\r\n ;]))" WScript.Echo "regex_version " & regex_version WScript.Echo "regex_mansect " & regex_mansect WScript.Echo "regex_strsect " & regex_strsect WScript.Echo "regex_strings " & regex_strings WScript.Echo "regex_devid " & regex_devid WScript.Echo "regex_devdef " & regex_devdef set HashOutput = CreateObject ("Scripting.Dictionary") set Hashtest = CreateObject ("Scripting.Dictionary") HashOutput.CompareMode = 1 set indexFile = CreateObject("Scripting.FileSystemObject").CreateTextFile(temp_drp & "result" & file_dir & ".txt", true) indexFile.Write("Version5;" & VbCrLf) On Error resume next set listFile = CreateObject("Scripting.FileSystemObject").OpenTextFile(temp_drp & "list" & file_dir & ".txt",1,false,-2) set list7z = CreateObject("Scripting.FileSystemObject").OpenTextFile(temp_drp & "list7z.txt",1,false,-2) list7zcontent = UCase(list7z.ReadAll) if Err.Number<>0 then WScript.Echo "Cannot read the driver list." & VbCrLf & "Disk may be writeprotected or file is corrupted." else ' Init regexps set RegExpStrSect = CreateObject("VBScript.RegExp") RegExpStrSect.Pattern = regex_strsect RegExpStrSect.Multiline = true RegExpStrSect.IgnoreCase = true RegExpStrSect.Global = false ' Note: "XP Alternative (by Greg)\D\3\M\A\12\prime.inf" has two [strings] sections set RegExpStrDefs = CreateObject("VBScript.RegExp") RegExpStrDefs.Pattern = regex_strings RegExpStrDefs.Multiline = true RegExpStrDefs.IgnoreCase = true RegExpStrDefs.Global = true set RegExpVerSect = CreateObject("VBScript.RegExp") RegExpVerSect.Pattern = regex_version RegExpVerSect.Multiline = true RegExpVerSect.IgnoreCase = true RegExpVerSect.Global = false set RegExpManSect = CreateObject("VBScript.RegExp") RegExpManSect.Pattern = regex_mansect RegExpManSect.Multiline = true RegExpManSect.IgnoreCase = true RegExpManSect.Global = false set RegExpManDef = CreateObject("VBScript.RegExp") RegExpManDef.Pattern = regex_mandef RegExpManDef.Multiline = true RegExpManDef.IgnoreCase = true RegExpManDef.Global = true set RegManID = CreateObject("VBScript.RegExp") RegManID.Pattern = regex_sectnames RegManID.Multiline = true RegManID.IgnoreCase = true RegManID.Global = true set RegExpDevDef = CreateObject("VBScript.RegExp") RegExpDevDef.Pattern = regex_devdef RegExpDevDef.Multiline = true RegExpDevDef.IgnoreCase = true RegExpDevDef.Global = true set RegExpDevID = CreateObject("VBScript.RegExp") RegExpDevID.Pattern = regex_devid RegExpDevID.IgnoreCase = true RegExpDevID.Global = true set RegExpDevSect = CreateObject("VBScript.RegExp") 'RegExpDevSect.Pattern = regex_devs_l & sectlist & regex_devs_r RegExpDevSect.Multiline = true RegExpDevSect.IgnoreCase = true RegExpDevSect.Global = true ' Read the list of paths of INF files do until listFile.AtEndOfStream inf_fullname = listFile.Readline inf_name = inf_fullname inf_path = Left(inf_fullname, InStrRev(inf_fullname,"\")) inf_path = Replace(inf_path,dir,"",1,-1,1) inf_name = Replace(inf_fullname,dir,"",1,-1,1) inf_filename_l = inf_name inf_filename_l = Replace(inf_filename_l,"inf","cat",1,-1,1) inf_filename_l = Ucase(inf_filename_l) inf_name = Replace(inf_name,inf_path,"",1,-1,1) WScript.Echo "inf_fullname:" & inf_fullname 'WScript.Echo "inf_path:" & inf_path WScript.Echo "inf_name:" & inf_filename_l ' WScript.Echo list7zcontent if inStr(list7zcontent,inf_filename_l) then catpresent = 1 WScript.Echo "+++" else catpresent = 0 WScript.Echo "---" end if 'WScript.Echo "1 " & timer-point1 point1 = timer point2 = point1 ' Read INF file filecontent = "" set objInfFile = CreateObject("Scripting.FileSystemObject").OpenTextFile(inf_fullname,1,false,-2) filecontent = objInfFile.ReadAll() objInfFile.Close 'WScript.Echo "2 " & timer-point1 point1 = timer ' Find [strings] section strings = "" set stringhash = CreateObject("Scripting.Dictionary") stringhash.CompareMode = 1 set MatchesStrSect = RegExpStrSect.Execute(filecontent) if MatchesStrSect.Count>=1 then set objMatch = MatchesStrSect.Item(0) strings = objMatch.SubMatches(0) & objMatch.SubMatches(1) set MatchesStrDefs = RegExpStrDefs.Execute(strings) for i=0 To MatchesStrDefs.Count-1 set objMatch = MatchesStrDefs.Item(i) key = objMatch.SubMatches(0) value = objMatch.SubMatches(1) if value = "" then value = objMatch.SubMatches(2) stringhash.add key, value stringhash.add "%"&key&"%", value next end if 'WScript.Echo "3 " & timer-point1 point1 = timer ' Find [version] section unkver = 0 set MatchesVerSect = RegExpVerSect.Execute(filecontent) if MatchesVerSect.Count>=1 then set objMatch = MatchesVerSect.Item(0) drv_date = objMatch.SubMatches(0) if InStr(drv_date,"%") then varname = Left(drv_date, InStrRev(drv_date,"%")) val = stringhash.item(varname) if val = "" then WScript.Echo "Cannot find '" & varname & "'" else drv_date = replace(drv_date,varname,val) end if end if drv_version = objMatch.SubMatches(1) if InStr(drv_version,"%") then varname = Left(drv_version, InStrRev(drv_version,"%")) val = stringhash.item(varname) if val = "" then WScript.Echo "Cannot find '" & varname & "'" else drv_version = replace(drv_version,varname,val) end if end if ' WScript.Echo drv_version else 'WScript.Echo "Section [version] not found" drv_date = "" drv_version = "" end if 'WScript.Echo "4 " & timer-point1 point1 = timer ' Find [manufacturer] section set MatchesManSect = RegExpManSect.Execute(filecontent) if MatchesManSect.Count>=1 then set objMatch = MatchesManSect.Item(0) sections = objMatch.SubMatches(0) & objMatch.SubMatches(1) sectlist = "" set MatchesManDef = RegExpManDef.Execute(sections) for i=0 To MatchesManDef.Count-1 set objMatch = MatchesManDef.Item(i) ss= objMatch.SubMatches(0) set MatchesManID = RegManID.Execute(ss) basename="" 'found =0 for j=0 To MatchesManID.Count-1 set objMatch1 = MatchesManID.Item(j) sb= objMatch1.SubMatches(0) & objMatch1.SubMatches(1) sb = rtrim(sb) 'WScript.Echo sb if i<>0 or j<>0 then sectlist = sectlist & "|" end if sectname="" if j=0 then basename = sb sectlist = sectlist&sb sectname = sb else sectlist = sectlist& basename&"."&sb ' WScript.Echo "*"§list 'found = 1 end if 'set RegManTest = CreateObject("VBScript.RegExp") 'RegManTest.Pattern = r_beg & "\[(?:"§name &")\](?:([\s\S]*?)" & r_beg & "(?=\[)|([\s\S]*))" 'RegManTest.Multiline = true 'RegManTest.IgnoreCase = true 'RegManTest.Global = false 'set MatchesManTest = RegManTest.Execute(filecontent) 'if MatchesManTest.Count=0 and sectname<>"" and MatchesManID.Count=1 then ' WScript.Echo "$$"§name 'end if 'WScript.Echo "|" & sb next ' man_ids next ' man_defs ' set RegExpDevSect = CreateObject("VBScript.RegExp") RegExpDevSect.Pattern = regex_devs_l & sectlist & regex_devs_r ' RegExpDevSect.Multiline = true ' RegExpDevSect.IgnoreCase = true ' RegExpDevSect.Global = true set MatchesDevSect = RegExpDevSect.Execute(filecontent) for k=0 To MatchesDevSect.Count-1 set objMatch = MatchesDevSect.Item(k) thissection = objMatch.SubMatches(1) & objMatch.SubMatches(2) arch = objMatch.SubMatches(0) ' Find device definitions defenitionlist = "" set MatchesDevDef = RegExpDevDef.Execute(thissection) ' Handle definition for i=0 To MatchesDevDef.Count-1 set objMatch = MatchesDevDef.Item(i) dev_ids = objMatch.SubMatches(3) ' Find name if objMatch.SubMatches(0)<>"" then ' %var% dev_name = stringhash.item(objMatch.SubMatches(0)) if dev_name = "" then dev_name = "Variable: " & objMatch.SubMatches(0) end if ' dev_name = objMatch.SubMatches(0) ' pos = InStr(dev_name,"%") ' if pos>0 then ' varname = mid(dev_name, pos, InStrRev(dev_name,"%")) ' 'replace(dev_name,varname,val) ' 'WScript.Echo "##"&varname&"##" ' val = stringhash.item(varname) ' if val = "" then ' WScript.Echo "Cannot find '" & varname & "'" ' else ' dev_name = replace(dev_name,varname,val) ' end if ' end if else if objMatch.SubMatches(1)<>"" then ' "str" dev_name = objMatch.SubMatches(1) if asc(mid(dev_name,1,1) = "%") then pos = InStr(dev_name,"%") if pos>0 then varname = mid(dev_name, pos, InStrRev(dev_name,"%")) 'replace(dev_name,varname,val) 'WScript.Echo "##"&varname&"##" val = stringhash.item(varname) if val = "" then WScript.Echo "Cannot find '" & varname & "'" else dev_name = replace(dev_name,varname,val) end if end if end if else if objMatch.SubMatches(2)<>"" then ' text dev_name = objMatch.SubMatches(2) pos = InStr(dev_name,"%") if pos>0 then varname = mid(dev_name, pos, InStrRev(dev_name,"%")) 'replace(dev_name,varname,val) 'WScript.Echo "##"&varname&"##" val = stringhash.item(varname) if val = "" then WScript.Echo "Cannot find '" & varname & "'" else dev_name = replace(dev_name,varname,val) end if end if else WScript.Echo "Something messed up really bad in " & inf_fullname end if end if end if ' add IDs set MatchesDevID = RegExpDevID.Execute(dev_ids) for j=0 To MatchesDevID.Count-1 set objMatch = MatchesDevID.Item(j) dev_id = objMatch.SubMatches(0) if dev_id <> "" then ss = dev_id & inf_path & inf_name & dev_name & arch r=HashOutput.Exists(ss) if r=false then HashOutput.item(ss)= "+" end if if r=false then unkver = unkver + 1 if drv_version="" and drv_date="" then ver = "Unknown" else if drv_version<>"" then ver = drv_date & "," & drv_version else ver = drv_date end if end if ' h = ((h << 5) + h) ^ ch; hashval = 0 str = ucase(dev_id) ' WScript.Echo str for k1 = 1 to len(str) t = asc(mid(str,k1,1)) ' hashval = binary24(hashval*2 + t) hashval = (binary24(hashval*32+hashval) xor t) ' WScript.Echo hashval&"("&t&")" next a = "" for k1 = 1 to len(dev_name) t = asc(mid(dev_name,k1,1)) a = a + chr(t) next set lines(numlines) = new lineobj lines(numlines).hash = hashval lines(numlines).line = dev_id & tab & inf_path & tab & inf_name & tab & arch & tab & catpresent & tab & ver & tab & a & VbCrLf numlines = numlines + 1 ' indexFile.Write(dev_id & tab & inf_path & tab & inf_name & tab & arch & tab & ver & tab & dev_name & VbCrLf) end if ' dev_entry end if next ' dev_ids next ' dev_defs next ' dev_sects end if ' sect_list 'WScript.Echo "5 " & timer-point1 point1 = timer HashOutput.removeall() stringhash.removeall() c=point1 'WScript.Echo "L: " & (c-point2) 'WScript.Echo "S: " & (c-starttime) loop ' inf list file end if ' file read point1 = timer numbuckets = round(numlines) if numbuckets<400 then numbuckets = 400 end if set hashFile = CreateObject("Scripting.FileSystemObject").CreateTextFile(temp_drp & "result" & file_dir & ".hash", true) VbCrLf_ ="" sp = "" hashFile.Write(PadDigits((numbuckets),8)&sp) WScript.Echo "Items:"&numlines&" Buckets:"&numbuckets dim buckets(100000) dim blocks(100000) for i = 0 to numlines-1 lines(i).hash = lines(i).hash mod numbuckets ' lines(i).line = lines(i).hash & " " & lines(i).line ' WScript.Echo lines(i).line buckets(lines(i).hash) = buckets(lines(i).hash) + 1 blocks(lines(i).hash) = blocks(lines(i).hash) + len(lines(i).line) next StartSort lines, numlines-1 lasthash = -1 lastlines = -1 curhs = -1 pos = 11 WScript.Echo "Beg" for i = 0 to numlines-1 while lasthash<>lines(i).hash lasthash = lasthash + 1 if lasthash<>lines(i).hash then hashFile.Write("00000000"&sp&"00000000"&sp) end if wend if curhs<>lines(i).hash then hashFile.Write(PadDigits((pos),8)&sp&PadDigits((blocks(lasthash)),8)&sp&VbCrLf_) curhs=lines(i).hash end if pos = pos + len(lines(i).line) indexFile.Write(lines(i).line) next for i = lasthash+1 to numbuckets-1 hashFile.Write("00000000"&sp&"00000000"&sp) next WScript.Echo "Done" listFile.Close indexFile.Close hashFile.Close list7z.Close WScript.Echo "Sum: " & timer-starttime