'Downloads several online hosts files and merges them 'into your computer's hosts file. Option Explicit Force32Bit 'Released to Public Domain by Eric Phelps, 2007. May 'be modified and redistributed with no restrictions. 'Define globals Const WindowsFolder = 0 Const SystemFolder = 1 Const TemporaryFolder = 2 Dim gstrHostsUrls 'The default list of URLs where you can find plain-text hosts files Dim gstrDbFolder 'The location of the database folder Dim gstrHostsFile 'The location of the computer's "hosts" file Dim fs 'File System Object Set fs = CreateObject("Scripting.FileSystemObject") 'Set default location of URLs (can be edited by the user in the "database") gstrHostsUrls = "http://www.malware.com.br/cgi/submit?action=list_hosts_win_127001" _ & " http://pgl.yoyo.org/adservers/serverlist.php?showintro=0;hostformat=hosts" _ & " http://someonewhocares.org/hosts/" _ & " http://www.hostsfile.info/classic127.txt" _ & " http://www.mvps.org/winhelp2002/hosts.txt" _ & " http://sysctl.org/cameleon/hosts.win" _ & " http://hostsfile.mine.nu/Hosts" _ & " http://everythingisnt.com/hosts" _ & " http://www.hostsfile.info/online/hpHOSTS.txt" _ & " http://hostsfile.org/Downloads/hosts.txt" 'Make sure the system has the basics If Not HasScripting() Then WScript.Quit 'Find the location of the computer's hosts file If fs.FolderExists(fs.BuildPath(fs.GetSpecialFolder(SystemFolder), "drivers\etc")) Then gstrHostsFile = fs.BuildPath(fs.GetSpecialFolder(SystemFolder), "drivers\etc\hosts")'WinNT, Win2000, WinXP, Vista Else gstrHostsFile = fs.BuildPath(fs.GetSpecialFolder(WindowsFolder), "hosts")'Win98 End If 'Assign the "db" database folder location to the same place as the script gstrDbFolder = fs.BuildPath(fs.GetParentFolderName(Wscript.ScriptFullName), "db") 'Prompt for admin rights if needed If NeedsUAC() Then If MsgBox("This script needs administrative priveleges to disable " _ & "your ""DNS Client"" service and update your ""hosts"" file. " _ & "This script will need to access the Internet, " _ & "change registry settings, run other programs, and modify files. " _ & "If your PC security warns you about these actions, you should allow " _ & "them.", vbOkCancel , "Administrative Rights") <> vbOk Then WScript.Quit End If UAC End If 'All the prerequisites are handled. Now we can run the program! Main Sub Main() Const ForWriting = 2 Const ForAppending = 8 Dim strUrl, strSQL, strText, fs Set fs = CreateObject("Scripting.FileSystemObject") 'Make sure the DNS Cache service is stopped If Not StopDNS() Then Exit Sub 'Create the database folder and all default files If Not fs.FolderExists(gstrDbFolder) Then CreateDatabase If MsgBox("A database folder has been created here:" & vbCrLf & gstrDbFolder & vbCrLf _ & "This folder contains plain-text tab-delimited files you can edit " _ & "to set the source web sites, your desired ""black hole"" address, " _ & "desired web hosts, and other settings. If you click OK now, those settings " _ & "will be used.", vbOkCancel, "One-Time Notice") <> vbOk Then WScript.Quit End If End If 'Back up the existing hosts file If fs.FileExists(gstrHostsFile) Then fs.CopyFile gstrHostsFile, gstrHostsFile & ".bak", True End If 'Get the existing hosts file data If fs.FileExists(gstrHostsFile) Then Status vbCrLf & "Reading existing data from """ & gstrHostsFile & """..." AppendHosts gstrHostsFile, fs.BuildPath(gstrDbFolder, "hosts1.txt"), BlackHole() End If 'Append the user's list of known bad sites from the database Status vbCrLf & "Reading entries from """ & fs.BuildPath(gstrDbFolder, "bad.txt") & """..." BadHosts fs.BuildPath(gstrDbFolder, "bad.txt") , fs.BuildPath(gstrDbFolder, "hosts1.txt"), BlackHole() 'Append all available hosts files from the web For Each strUrl In Split(Urls()) Status vbCrLf & "Merging new entries from " & strUrl & " ..." String2File GetData(strUrl), FileNameInTempDir("hosts") AppendHosts FileNameInTempDir("hosts"), fs.BuildPath(gstrDbFolder, "hosts1.txt"), BlackHole() Next 'Create the "hosts2.txt" file containing unique ordered bad names Status vbCrLf & "Sorting and Removing Duplicates..." strSQL = "" _ & "SELECT DISTINCT [Name], [Domain], [Machine] " _ & "FROM [Hosts1.txt] " _ & "ORDER BY [Domain], [Machine];" RecordsetToFile strSQL, fs.BuildPath(gstrDbFolder, "hosts2.txt"), ForAppending, "Name", vbTab, vbCrLf 'Create the "hosts3.txt" file which doesn't contain trusted hosts Status vbCrLf & "Removing trusted hosts..." strSQL = "" _ & "SELECT H.Name " _ & "FROM [Hosts2.txt] H " _ & "LEFT JOIN [Trusted.txt] T On H.Name = T.Name " _ & "WHERE T.Name Is Null; " RecordsetToFile strSQL, fs.BuildPath(gstrDbFolder, "hosts3.txt"), ForAppending, "Name", vbTab, vbCrLf 'Write the hosts file header Status vbCrLf & "Updating the """ & gstrHostsFile & """ file..." strText = "" _ & "# This file was created by (and can be updated by) running:" & vbCrLf & "# """ & Wscript.ScriptFullName & """" & vbCrLf _ & "# Do not edit this file except to add hosts to be blocked." & vbCrLf _ & "# To prevent hosts from being added to this file, edit:" & vbCrLf & "# """ & fs.BuildPath(gstrDbFolder, "trusted.txt") & """" & vbCrLf _ & "# To change the ""black hole"" IP address used, edit:" & vbCrLf & "# """ & fs.BuildPath(gstrDbFolder, "blackhole.txt") & """" & vbCrLf _ & "# To change the URLs used to get hosts updates, edit:" & vbCrLf & "# """ & fs.BuildPath(gstrDbFolder, "url.txt") & """" & vbCrLf _ & vbCrLf _ & "# The ""localhost"" line below is REQUIRED." & vbCrLf _ & BlackHole() & vbTab & "localhost" & vbCrLf String2File strText, gstrHostsFile 'Write the hosts file legitimate hosts Status vbCrLf & "Adding legitimate hosts entries to the ""hosts"" file..." strText = vbCrLf & "# Lines in this section are aliases for legitimate hosts" _ & vbCrLf & "# To add legitimate hosts with live addresses, see:" _ & vbCrLf & "# """ & fs.BuildPath(gstrDbFolder, "good.txt") & """" fs.OpenTextFile(gstrHostsFile, ForAppending, True).WriteLine strText strSQL = "" _ & "SELECT Address, Name " _ & "FROM [good.txt] " _ & "ORDER BY Name; " RecordsetToFile strSQL, gstrHostsFile, ForAppending, "Address Name", vbTab, vbCrLf 'Write the main part of the hosts file Status vbCrLf & "Adding hosts to be blocked to the ""hosts"" file..." strText = vbCrLf & vbCrLf & "# Lines in this section are hosts to be blocked." _ & vbCrLf & "# To add hosts to always block, see:" _ & vbCrLf & "# """ & fs.BuildPath(gstrDbFolder, "bad.txt") & """" fs.OpenTextFile(gstrHostsFile, ForAppending, True).WriteLine strText strSQL = "" _ & "SELECT B.Address, H.Name " _ & "FROM [blackhole.txt] B, [hosts3.txt] H;" RecordsetToFile strSQL, gstrHostsFile, ForAppending, "Address Name", vbTab, vbCrLf 'Done! Now delete the data in the temporary files strText = "Name" & vbTab & "Machine" & vbTab & "Domain" & vbTab & "(Do not edit this file. It is created and edited by the script.)" fs.OpenTextFile(fs.BuildPath(gstrDbFolder, "hosts1.txt"), ForWriting, True).WriteLine strText strText = "Name" & vbTab & "(Do not edit this file. It is created and edited by the script.)" fs.OpenTextFile(fs.BuildPath(gstrDbFolder, "hosts2.txt"), ForWriting, True).WriteLine strText fs.OpenTextFile(fs.BuildPath(gstrDbFolder, "hosts3.txt"), ForWriting, True).WriteLine strText If fs.FileExists(FileNameInTempDir("hosts")) Then fs.DeleteFile FileNameInTempDir("hosts") End Sub Function StopDNS() 'Returns True if DNS Cache service is (or after it has been) stopped. Const WINDOWS_FOLDER = 0 Const SYSTEM_FOLDER = 1 Dim fs, ws, sc, oTest Dim strData, blnDNS, strMessage, strUser On Error Resume Next 'Create objects Err.Clear Set ws = CreateObject("WScript.Shell") Set fs = CreateObject("Scripting.FileSystemObject") 'Verify the DNS Cache service is stopped blnDNS = False 'True is a bad thing! If ServiceState("DNSCache") <> "Stopped" Then blnDNS = True If ServiceStartMode("DNSCache") = "Auto" Then blnDNS = True If ServiceStartMode("DNSCache") = "" Then blnDNS = True If OsVersion() < 5 Then blnDNS = False 'Win9X has no DNSCache service If blnDNS Then If MsgBox("NOTE: In order for you to use a large HOSTS file, I'll need to disable the ""DNS Client"" service. If this computer is part of a domain (if you use this PC to log in at work), you should check with your IT department first. Proceed?", vbYesNo, "Disable DNS Client Service") = vbYes Then 'Stop the DNS Client service Status "Stopping DNSCache service" StopService "DNSCache" WScript.Sleep 2000 If ServiceState("DNSCache") = "Running" Then 'Assume no news is good news MsgBox "Not good! I was unable to stop the ""DNS Client"" service. You (and by extension, I) may not have permission to muck about with the things we are currently mucking about with. No changes were made. Perhaps you should try again later." StopDNS = False Exit Function End If 'Disable the DNS Client service so it won't start automatically next time If ServiceStartMode("DNSCache") = "Auto" Then Status "Setting DNSCache service to ""disabled""" ws.RegWrite "HKLM\SYSTEM\CurrentControlSet\Services\Dnscache\Start", 4, "REG_DWORD" If ws.RegRead("HKLM\SYSTEM\CurrentControlSet\Services\Dnscache\Start") <> 4 Then 'If we can't disable the DNS Client via the registry, try using the NET command... ws.Run "net.exe config DNSCache start=disabled", 1, False '...and cry about the problem regardless of whether NET worked or not MsgBox "I was unable to reliably disable the ""DNS Client"" service. It really should be disabled or set to manual. I'm afraid you may need to do this manually!", , "Service Error" StopDNS = False Exit Function End If End If Else MsgBox "No changes were made. You may re-run this script again later." StopDNS = False Exit Function End If End If StopDNS = True End Function Sub CreateDatabase() Const ForWriting = 2 Const WindowsFolder = 0 Const SystemFolder = 1 Dim ts, strHostsFile, strURL, strSchema 'First create the DB folder If Not fs.FolderExists(gstrDbFolder) Then fs.CreateFolder gstrDbFolder End If 'Create DB files If Not fs.FileExists(fs.BuildPath(gstrDbFolder, "schema.ini")) Then Set ts = fs.OpenTextFile(fs.BuildPath(gstrDbFolder, "schema.ini"), ForWriting, True) strSchema = vbCrLf & "Format=TabDelimited" & vbCrLf & "ColNameHeader=True" & vbCrLf & "MaxScanRows=0" & vbCrLf & "CharacterSet=ANSI" & vbCrLf ts.WriteLine "[good.txt]" & strSchema ts.WriteLine "[bad.txt]" & strSchema ts.WriteLine "[trusted.txt]" & strSchema ts.WriteLine "[blackhole.txt]" & strSchema ts.WriteLine "[url.txt]" & strSchema ts.WriteLine "[hosts1.txt]" & strSchema ts.WriteLine "[hosts2.txt]" & strSchema ts.WriteLine "[hosts3.txt]" & strSchema ts.Close End If If Not fs.FileExists(fs.BuildPath(gstrDbFolder, "good.txt")) Then Set ts = fs.OpenTextFile(fs.BuildPath(gstrDbFolder, "good.txt"), ForWriting, True) ts.WriteLine "Address" & vbTab & "Name" & vbTab & "(Legitimate tab-delimited address/name pairs that will ALWAYS be part of your hosts file.)" ts.WriteLine "192.168.0.1" & vbTab & "router" ts.Close End If If Not fs.FileExists(fs.BuildPath(gstrDbFolder, "bad.txt")) Then Set ts = fs.OpenTextFile(fs.BuildPath(gstrDbFolder, "bad.txt"), ForWriting, True) ts.WriteLine "Name" & vbTab & "(Personal list of bad host names that will ALWAYS be added to your hosts file.)" ts.WriteLine "btbilgisayarkursu.com" ts.WriteLine "dgdg567.com" ts.Close End If If Not fs.FileExists(fs.BuildPath(gstrDbFolder, "trusted.txt")) Then Set ts = fs.OpenTextFile(fs.BuildPath(gstrDbFolder, "trusted.txt"), ForWriting, True) ts.WriteLine "Name" & vbTab & "(Personal list of good host names that will NEVER be added to your hosts file.)" ts.WriteLine "google.com" ts.WriteLine "www.google.com" ts.WriteLine "orbitz.com" ts.WriteLine "www.orbitz.com" ts.WriteLine "travelocity.com" ts.WriteLine "www.travelocity.com" ts.WriteLine "activex.microsoft.com" ts.WriteLine "codecs.microsoft.com" ts.WriteLine "msdownload.microsoft.com" ts.WriteLine "genuine.microsoft.com" ts.WriteLine "windowsupdate.microsoft.com" ts.WriteLine "www.update.microsoft.com" ts.WriteLine "www.microsoft.com" ts.WriteLine "www.msn.com" ts.WriteLine "www.yahoo.com" ts.WriteLine "wunderground.com" ts.WriteLine "www.netflix.com" ts.WriteLine "netflix.com" ts.Close End If If Not fs.FileExists(fs.BuildPath(gstrDbFolder, "blackhole.txt")) Then Set ts = fs.OpenTextFile(fs.BuildPath(gstrDbFolder, "blackhole.txt"), ForWriting, True) ts.WriteLine "Address" & vbTab & "(Black Hole IP address you want to use in your hosts file.)" ts.WriteLine "127.0.0.1" ts.Close End If 'Create a default list of hosts to use If Not fs.FileExists(fs.BuildPath(gstrDbFolder, "url.txt")) Then Set ts = fs.OpenTextFile(fs.BuildPath(gstrDbFolder, "url.txt"), ForWriting, True) ts.WriteLine "URL" & vbTab & "(List of URLs with plain-text hosts files you can use.)" For Each strUrl In Split(gstrHostsUrls) ts.WriteLine strUrl Next ts.Close End If 'Create temporary files new every time because we need them to start out empty. 'Create "hosts1.txt" temporary table Set ts = fs.OpenTextFile(fs.BuildPath(gstrDbFolder, "hosts1.txt"), ForWriting, True) ts.WriteLine "Name" & vbTab & "Machine" & vbTab & "Domain" & vbTab & "(Do not edit this file. It is created and edited by the script.)" ts.Close 'Create "hosts2.txt" temporary table Set ts = fs.OpenTextFile(fs.BuildPath(gstrDbFolder, "hosts2.txt"), ForWriting, True) ts.WriteLine "Name" & vbTab & "(Do not edit this file. It is created and edited by the script.)" ts.Close 'Create "hosts3.txt" temporary table Set ts = fs.OpenTextFile(fs.BuildPath(gstrDbFolder, "hosts3.txt"), ForWriting, True) ts.WriteLine "Name" & vbTab & "(Do not edit this file. It is created and edited by the script.)" ts.Close 'Create a "readme" file new every time because it documents the location of this script Set ts = fs.OpenTextFile(fs.BuildPath(gstrDbFolder, "Read_Me.txt"), ForWriting, True) ts.WriteLine "****************** This is a description of the files in this directory ******************" ts.WriteLine "Files are the ""database"" for the """ & Wscript.ScriptFullName & """ script." ts.WriteLine "If any file is deleted, it will be regenerated by the script." ts.WriteLine """schema.ini"" - Identifies the data format in each file. Do not modify this file." ts.WriteLine "**** Files described below may be modified as long as the first line is not changed. ****" ts.WriteLine "" ts.WriteLine """bad.txt"" - List of bad host names that will ALWAYS be added to your hosts file." ts.WriteLine """blackhole.txt"" - IP address (like 0.0.0.0 or 127.0.0.1) you want to use in your hosts file." ts.WriteLine """good.txt"" - Legitimate tab-delimited address/name pairs that will ALWAYS be part of your hosts file." ts.WriteLine """hosts1.txt"" - Temporary file used while updating." ts.WriteLine """hosts2.txt"" - Temporary file used while updating." ts.WriteLine """hosts3.txt"" - Temporary file used while updating." ts.WriteLine """trusted.txt"" - List of good host names that will NEVER be added to your hosts file." ts.WriteLine """url.txt"" - URLs of plain-text hosts files you want to merge into your hosts file." If OsVersion() > 5 Then ts.WriteLine vbCrLf ts.WriteLine "************************* WINDOWS VISTA EDITING TIP **********************" ts.WriteLine "Drag a file out of this protected folder to the desktop. You'll be prompted" ts.WriteLine "to confirm the action. Edit and save the file on your desktop. When you are" ts.WriteLine "done, drag the file back to this folder. You'll be prompted again to confirm" ts.WriteLine "the action." End If ts.Close End Sub Sub AppendHosts(strSourceFile, strDestFile, strBlackHole) 'Reads a hosts file in and appends tab-delimited machine and domain 'name data to the "hosts1.txt" file. Const ForReading = 1 Const ForWriting = 2 Const ForAppending = 8 Dim tsSource, tsDest Dim strHostsFile, strLine, strIP, strMachine, strDomain, strHost Dim varHost, intPart, strTLD, strSLD If fs.FileExists(strSourceFile) Then 'Read the source "hosts" file line-at-a-time, writing to the destination Set tsSource = fs.OpenTextFile(strSourceFile, ForReading, False) Set tsDest = fs.OpenTextFile(strDestFile, ForAppending, False) Do While Not tsSource.AtEndOfStream strLine = tsSource.ReadLine strLine = Trim(strLine) If Len(strLine) > 6 Then If ((Left(strLine, 1) <> "#") And (IsNumeric(Left(strLine, 1)))) Then Do While InStr(strLine, vbTab ) <> 0 strLine = Replace(strLine, vbTab, " ") Loop Do While InStr(strLine, "#" ) <> 0 strLine = Replace(strLine, "#", " ") Loop Do While InStr(strLine, " " ) <> 0 strLine = Replace(strLine, " ", " ") Loop 'strIP, strMachine, strDomain, strHost strIP = Split(strLine)(0) If Ubound(Split(strIP, ".")) = 3 Then strHost = Split(strLine)(1) Status strHost 'Verify the IP is blacklisted If ((InStr(strIP, "127.") = 1) _ Or (InStr(strIP, "0.0.0.") = 1) _ Or (InStr(strIP, strBlackHole) = 1)) Then 'Separate out the parts of the host name varHost = Split(strHost, ".") strTLD = "" strSLD = "" strMachine = "" For intPart = UBound(varHost) To 0 Step -1 If strTLD = "" Then strTLD = varHost(intPart) Else If strSLD = "" Then strSLD = varHost(intPart) Else If strMachine <> "" Then strMachine = "." & strMachine End If strMachine = varHost(intPart) & strMachine End If End If Next 'Write the data to the destination If ((strSLD <> "") And (strTLD <> "")) Then tsDest.WriteLine strHost & vbTab & strMachine & vbTab & strSLD & "." & strTLD End If End If End If End If End If Loop tsSource.Close tsDest.Close End If End Sub Sub BadHosts(strSourceFile, strDestFile, strBlackHole) 'Reads the list of hosts in the "bad.txt" file in and appends 'tab-delimited machine and domain name data to the "hosts1.txt" file. 'Virtually identical to the "AppendHosts" subroutine except that 'this doesn't handle IP addresses. Const ForReading = 1 Const ForWriting = 2 Const ForAppending = 8 Dim tsSource, tsDest Dim strHostsFile, strLine, strIP, strMachine, strDomain, strHost Dim varHost, intPart, strTLD, strSLD If fs.FileExists(strSourceFile) Then 'Read the source "hosts" file line-at-a-time, writing to the destination "hosts.txt" Set tsSource = fs.OpenTextFile(strSourceFile, ForReading, False) Set tsDest = fs.OpenTextFile(strDestFile, ForAppending, False) strLine = tsSource.ReadLine 'Read the first line as a throwaway Do While Not tsSource.AtEndOfStream strLine = tsSource.ReadLine strHost = Trim(strLine) If Len(strLine) > 6 Then Status strHost 'Separate out the parts of the host name varHost = Split(strHost, ".") strTLD = "" strSLD = "" strMachine = "" For intPart = UBound(varHost) To 0 Step -1 If strTLD = "" Then strTLD = varHost(intPart) Else If strSLD = "" Then strSLD = varHost(intPart) Else If strMachine <> "" Then strMachine = "." & strMachine End If strMachine = varHost(intPart) & strMachine End If End If Next 'Write the data to the destination If ((strSLD <> "") And (strTLD <> "")) Then tsDest.WriteLine strHost & vbTab & strMachine & vbTab & strSLD & "." & strTLD End If End If Loop tsSource.Close tsDest.Close End If End Sub Sub RecordsetToFile(strSQL, strDestFile, lngFileMode, strOutputFields, strFieldSeparator, strLineSeparator) 'Reads in a recordset and spits out delimited text to a file. Const ForWriting = 2 Const adLockReadOnly = 1 Const adOpenStatic = 3 Dim cn, rs, ts Dim strOutputField, blnFirstLine, blnFirstField 'Create objects Set rs = CreateObject("ADODB.Recordset") Set cn = CreateObject("ADODB.Connection") Set ts = fs.OpenTextFile(strDestFile, lngFileMode, True) 'Create the database connection cn.Provider = "Microsoft.Jet.OLEDB.4.0" cn.Properties("Data Source") = gstrDbFolder cn.Properties("Extended Properties").Value = "text;" cn.Open 'Open the recordset rs.ActiveConnection = cn rs.CursorType = adOpenStatic rs.LockType = adLockReadOnly rs.Source = strSQL rs.Open If Not (rs.BOF And rs.EOF) Then rs.MoveFirst blnFirstLine = True blnFirstField = True Do While Not rs.EOF blnFirstField = True If Not blnFirstLine Then ts.Write strLineSeparator Else blnFirstLine = False End If For Each strOutputField In Split(strOutputFields) If Not blnFirstField Then ts.Write strFieldSeparator Else blnFirstField = False End If If Not IsNull(rs.Fields(strOutputField).Value) Then ts.Write rs.Fields(strOutputField).Value End If Next rs.MoveNext Loop End If ts.Close Set ts = Nothing 'ADO Cleanup rs.Close Set rs = Nothing cn.Close Set cn = Nothing End Sub Function String2File(strData, strFileName) 'Writes a string to a file. Returns True if success. Dim ts 'As Scripting.TextStream Dim lngChar, strBlock, intChar, dtTimeStamp Const ForWriting = 2 On Error Resume Next If fs.FileExists(strFileName) Then dtTimeStamp = fs.GetFile(strFileName).DateLastModified Else dtTimeStamp = CDate(0) End If Err.Clear Set ts = fs.OpenTextFile(strFileName, ForWriting, True) ts.Write strData If Err.Number <> 0 Then 'Must have hit one of the "problem characters" between 128 and 159 For lngChar = 1 To Len(strData) Step 100 Err.Clear ts.Write Mid(strData, lngChar, 100) If Err.Number <> 0 Then 'This block of 100 must have the problem. Write them one-at-a-time strBlock = Mid(strData, lngChar, 100) For intChar = 1 To Len(strBlock) ts.Write Chr(255 And AscW(Mid(strBlock, intChar))) Next End If Next End If ts.Close If fs.FileExists(strFileName) Then If dtTimeStamp = fs.GetFile(strFileName).DateLastModified Then String2File = False Else String2File = True End If Else String2File = False End If End Function Function FileNameInTempDir(strFileName) 'As String 'Returns the full path and file name to a file in the user's temporary directory Const TemporaryFolder = 2 FileNameInTempDir = fs.GetAbsolutePathName(fs.BuildPath(fs.GetSpecialFolder(TemporaryFolder), strFileName)) End Function Function GetData(strUrl) Dim web Const WinHttpRequestOption_EnableRedirects = 6 Set web = Nothing On Error Resume Next Set web = CreateObject("WinHttp.WinHttpRequest.5.1") If web Is Nothing Then Set web = CreateObject("WinHttp.WinHttpRequest") If web Is Nothing Then Set web = CreateObject("MSXML2.ServerXMLHTTP") If web Is Nothing Then Set web = CreateObject("Microsoft.XMLHTTP") If web Is Nothing Then GetData = "" Exit Function End If web.Option(WinHttpRequestOption_EnableRedirects) = True web.Open "GET", strURL, False web.SetRequestHeader "REFERER", strUrl web.SetRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)" web.SetRequestHeader "Accept", "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5" web.SetRequestHeader "Accept-Language", "en-us,en;q=0.5" web.SetRequestHeader "Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7" web.Send If web.Status = "200" Then GetData = web.ResponseText Else GetData = "" End If End Function Sub Status(strMessage) If Lcase(Right(Wscript.FullName, 12)) = "\cscript.exe" Then Wscript.Echo strMessage End If End Sub Function BlackHole() 'Returns the IP address listed in the "black hole" table 'LockTypeEnum Const adLockBatchOptimistic = 4 Const adLockOptimistic = 3 Const adLockPessimistic = 2 Const adLockReadOnly = 1 'CursorTypeEnum Const adOpenDynamic = 2 Const adOpenForwardOnly = 0 Const adOpenStatic = 3 Dim cn, rs 'Create the database connection Set cn = CreateObject("ADODB.Connection") cn.Provider = "Microsoft.Jet.OLEDB.4.0" cn.Properties("Data Source") = gstrDbFolder cn.Properties("Extended Properties").Value = "text;" cn.Open 'Open the recordset Set rs = CreateObject("ADODB.Recordset") rs.ActiveConnection = cn rs.CursorType = adOpenStatic rs.LockType = adLockReadOnly rs.Source = "SELECT * FROM [blackhole.txt]" rs.Open If rs.BOF And rs.EOF Then BlackHole = "127.0.0.1" Else rs.MoveFirst 'Read the data BlackHole = rs.Fields("Address").Value End If 'ADO Cleanup rs.Close Set rs = Nothing cn.Close Set cn = Nothing End Function Function Urls() 'Returns a space-delimited collection of URLs 'LockTypeEnum Const adLockBatchOptimistic = 4 Const adLockOptimistic = 3 Const adLockPessimistic = 2 Const adLockReadOnly = 1 'CursorTypeEnum Const adOpenDynamic = 2 Const adOpenForwardOnly = 0 Const adOpenStatic = 3 Dim cn, rs, strUrls 'Create the database connection Set cn = CreateObject("ADODB.Connection") cn.Provider = "Microsoft.Jet.OLEDB.4.0" cn.Properties("Data Source") = gstrDbFolder cn.Properties("Extended Properties").Value = "text;" cn.Open 'Open the recordset Set rs = CreateObject("ADODB.Recordset") rs.ActiveConnection = cn rs.CursorType = adOpenStatic rs.LockType = adLockReadOnly rs.Source = "SELECT * FROM [url.txt]" rs.Open If rs.BOF And rs.EOF Then strUrls = "" Else rs.MoveFirst strUrls = "" Do Until rs.EOF If strUrls <> "" Then strUrls = strUrls & " " End If strUrls = strUrls & rs.Fields("URL").Value rs.MoveNext Loop End If 'ADO Cleanup rs.Close Set rs = Nothing cn.Close Set cn = Nothing Urls = strUrls End Function Sub StopService(strServiceName) Dim blnDependencies, objWMI, objService, colServices On Error Resume Next Err.Clear Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") Set colServices = objWMI.ExecQuery("Associators of {Win32_Service.Name='" & strServiceName & "'} Where AssocClass=Win32_DependentService " & "Role=Antecedent" ) blnDependencies = False For Each objService in colServices blnDependencies = True objService.StopService Next If blnDependencies = True Then Wscript.Sleep 20000 End If Set colServices = objWMI.ExecQuery("Select * from Win32_Service where Name='" & strServiceName & "'") For Each objService in colServices objService.StopService() Next Set objWMI = Nothing 'If WMI fails, try running NET.EXE to stop service If Err.Number <> 0 Then CreateObject("WScript.Shell").Run "net.exe stop " & strServiceName, 0, False End If End Sub Function ServiceState(strServiceName) 'Returns "Running", "Stopped", "Starting", "Stopping", or "" Dim objWMI, colServices, objService, strState, strStartMode On Error Resume Next Err.Clear Set objWMI = GetObject("winmgmts:\\.\root\CIMV2") Set colServices = objWMI.ExecQuery("SELECT * FROM Win32_Service WHERE NAME='" & strServiceName & "'", "WQL", 48) For Each objService In colServices strState = objService.State Next If Err.Number <> 0 Then ServiceState = "" 'Return empty string on WMI failure Else ServiceState = strState End If Set objWMI = Nothing End Function Function ServiceStartMode(strServiceName) 'Returns "Auto", "Disabled", "Manual", or "" Dim objWMI, colServices, objService, strState, strStartMode On Error Resume Next Err.Clear Set objWMI = GetObject("winmgmts:\\.\root\CIMV2") Set colServices = objWMI.ExecQuery("SELECT * FROM Win32_Service WHERE NAME='" & strServiceName & "'", "WQL", 48) For Each objService In colServices strStartMode = objService.StartMode Next If Err.Number <> 0 Then ServiceStartMode = "" 'Return empty string on WMI failure Else ServiceStartMode = strStartMode End If Set objWMI = Nothing End Function Sub Force32Bit() 'If OS is 64 bit and the script engine is also 64 bit, re-run the script with a 32-bit engine Dim ws, fs, wmi, col, obj, strBits, strCmd, intArg 'Use WMI to see whether OS is 32 or 64 bit strBits = "32" On Error Resume Next Set wmi = GetObject("winmgmts:\\.\root\CIMV2") Set col = wmi.ExecQuery("SELECT * FROM Win32_OperatingSystem", "WQL", 48) For Each obj In col strBits = obj.OSArchitecture Next Set col = Nothing Set wmi = Nothing On Error Goto 0 'Test to see if we're on a 64-bit OS and running a 64-bit script engine If InStr(strBits, "64") <> 0 Then If Instr(WScript.FullName, "SysWOW64") = 0 Then 'Start building the necessary command line to re-launch the script Set ws = CreateObject("Wscript.Shell") Set fs = CreateObject("Scripting.FileSystemObject") strCmd = fs.BuildPath(fs.GetSpecialFolder(0), "SysWOW64\" & fs.GetFileName(WScript.FullName)) 'Add quotes in case engine has spaces in the path If Left(strCmd, 1) <> """" Then strCmd = """" & strCmd & """" End If 'Add the script name (with quotes just in case) strCmd = strCmd & " """ & WScript.ScriptFullName & """" 'Add arguments if there are any If WScript.Arguments.Count > 0 Then For intArg = 0 To WScript.Arguments.Count - 1 'If there is a space in an argument, add quotes around the argument If InStr(WScript.Arguments(intArg), " ") <> 0 Then strCmd = strCmd & " """ & WScript.Arguments(intArg) & """" Else strCmd = strCmd & " " & WScript.Arguments(intArg) End If Next End If 'Run the script again with the 32-bit engine. Kill this 64-bit script. ws.Run strCmd, 1, False WScript.Quit End If End If End Sub '************************************************** '****** Unused routines not worth the bother ****** '************************************************** 'Function DisableAddressBarSearching() 'Dim ws ' Set ws = CreateObject("WScript.Shell") ' 'Talk the user into disabling "Search from the Address bar" ' If ws.RegRead("HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\AutoSearch") <> 0 Then ' If MsgBox("The ""Search from the Address bar"" feature in Internet Explorer can misbehave when used with a restrictive hosts file. This can cause a good web page to be replaced by a search error page. May I disable address bar searching?", vbYesNo, "IE Settings Change") = vbYes Then ' ws.RegWrite "HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\AutoSearch", 0, "REG_DWORD" ' If ws.RegRead("HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\AutoSearch") <> 0 Then ' DisableAddressBarSearching = False ' Status "Unable to disable the ""Search from the Address bar"" feature in IE" ' MsgBox "I was unable to turn off address bar searching. If it ends up causing problems in the future, you can turn the address bar search feature on and off yourself from the ""Advanced"" tab of the ""Internet Properties"" control." ' Else ' DisableAddressBarSearching = True ' Status "Disabled the ""Search from the Address bar"" feature in IE" ' If MsgBox("Okay. I did that for you (" & UserName() & "), but turning off address bar searching is something that needs to be done for every user! Assuming there are other users, should I put a script in the ""Startup"" folder that will turn off address bar searching for all the other users?", vbYesNo, "Other Users") = vbYes Then ' AddressBarSearchScript ws.SpecialFolders("AllUsersStartup") ' End If ' End If ' Else ' DisableAddressBarSearching = False ' MsgBox "No problem. You can turn the address bar search feature on and off yourself from the ""Advanced"" tab of the ""Internet Properties"" control." ' End If ' End If 'End Function ' Function AddressBarSearchScript(strFolder) ' Dim strData ' 'Win9x family may not have a valid folder, so bail out with an error ' If strFolder = "" Then ' AddressBarSearchScript = False ' Exit Function ' End If ' strData = "" ' strData = strData & ":: This file disables the ""Search from the Address bar"" feature " & vbCrLf ' strData = strData & ":: in Internet Explorer. This feature can cause problems when " & vbCrLf ' strData = strData & ":: used with restrictive hosts files. This computer uses such a " & vbCrLf ' strData = strData & ":: hosts file. The person who installed the hosts file elected to " & vbCrLf ' strData = strData & ":: install this file to make sure other users did not experience " & vbCrLf ' strData = strData & ":: problems with Internet Explorer replacing a good web page with " & vbCrLf ' strData = strData & ":: a search web page." & vbCrLf & vbCrLf ' 'Merging a REG file via a batch file fires fewer security alerts than doing it with scripting. ' strData = strData & "@echo off" & vbCrLf ' strData = strData & " >""%temp%\DisableAddressBarSearch.reg"" echo REGEDIT4" & vbCrLf ' strData = strData & ">>""%temp%\DisableAddressBarSearch.reg"" echo." & vbCrLf ' strData = strData & ">>""%temp%\DisableAddressBarSearch.reg"" echo [HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\]" & vbCrLf ' strData = strData & ">>""%temp%\DisableAddressBarSearch.reg"" echo ""AutoSearch""=dword:00000000" & vbCrLf ' strData = strData & ">>""%temp%\DisableAddressBarSearch.reg"" echo." & vbCrLf ' strData = strData & "start /w regedit.exe /s ""%temp%\DisableAddressBarSearch.reg""" & vbCrLf ' strData = strData & "del ""%temp%\DisableAddressBarSearch.reg"" > nul" & vbCrLf ' strData = strData & "cls" & vbCrLf ' strData = strData & "exit" ' AddressBarSearchScript = String2File(strData, CreateObject("Scripting.FileSystemObject").BuildPath(strFolder, "Disable Address Bar Searching.bat")) ' End Function ' Function HasWMI() ' 'Returns True is able to get CIMV2 ' Dim oTest ' Set oTest = Nothing ' On Error Resume Next ' Err.Clear ' Set oTest = GetObject("winmgmts:\\.\root\CIMV2") ' If oTest Is Nothing Then ' If OsVersion() = 4 Then ' If MsgBox ("You don't seem to have WMI (Windows Management Infrastructure). May I take you to a Microsoft web page where you can download WMI?", vbYesNo, "WMI") = vbYes Then ' ws.Run "http://www.microsoft.com/downloads/details.aspx?FamilyID=afe41f46-e213-4cbf-9c5b-fbf236e0e875&DisplayLang=en", 1, False ' End If ' End If ' HasWMI = False ' Else ' Set oTest = Nothing ' HasWMI = True ' End If ' End Function '********************************************************* '**** UAC (User Access Control) code below this point **** '********************************************************* Function NeedsUAC() 'Returns False if UAC not needed (Win9x or Win2K/XP with logged on admin) 'Returns True if UAC needed (Win2K/XP with no admin or every instance of Vista) If IsAdmin(UserName()) Then If OsVersion() < 6 Then NeedsUAC = False Else NeedsUAC = True End If Else NeedsUAC = True End If End Function Sub UAC() 'Run this subroutine FIRST THING on any script that may require admin 'priveleges. It will generate a "User Access Control" prompt on Vista 'or generate a "Run As" prompt for admin priveleges on 2K/XP (if the '2K/XP user isn't an admin). It will do nothing on Win9x systems or 'on Win2K/XP systems with a logged-in admin. Const FOR_WRITING = 2 Const TEMP_FOLDER = 2 Dim ws, fs, ts, wmi, col, obj Dim strData, strUacFile, strArg, strArgs, strOsVersion, strUserName, strGroup, strMember Dim lngArg, lngOsVersion Dim blnIsAdmin, blnHasAdmins 'See if we can create needed objects On Error Resume Next Err.Clear Set fs = CreateObject("Scripting.FileSystemObject") Set ws = CreateObject("WScript.Shell") Set wmi = GetObject("winmgmts:\\.\root\CIMV2") If Err.Number <> 0 Then Exit Sub 'Reasonable assumption it's Win9x? On Error Goto 0 'Define the name of the special script that will re-launch this one for UAC if needed. 'Can't use %TEMP% or other per-user folder, can't use script folder because it might be 'in protected area. strUacFile = "" If strUacFile = "" Then 'First try to use "shared docs" because everyone can get to it. strUacFile = ws.RegRead("HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Common Documents") If strUacFile <> "" Then If fs.FolderExists(strUacFile) Then strUacFile = fs.BuildPath(strUacFile, "~" & fs.GetBaseName(WScript.ScriptName) & ".vbs") Else strUacFile = "" End If End If End If If strUacFile = "" Then 'Next choice is all users desktop. strUacFile = ws.SpecialFolders("AllUsersDesktop") If strUacFile <> "" Then If fs.FolderExists(strUacFile) Then strUacFile = fs.BuildPath(strUacFile, "~" & fs.GetBaseName(WScript.ScriptName) & ".vbs") Else strUacFile = "" End If End If End If If strUacFile = "" Then 'Last choice is the drive root. At least we know it exists! strUacFile = fs.BuildPath(fs.GetDriveName(WScript.Path) & "\", "~" & WScript.ScriptName) End If 'If the UAC script exists, we can assume it launched this one! It should be deleted. If fs.FileExists(strUacFile) Then fs.DeleteFile strUacFile Exit Sub End If 'Find the Operating System major version Set col = wmi.ExecQuery("SELECT * FROM Win32_OperatingSystem", "WQL", 48) strOsVersion = "0.0" For Each obj In col : strOsVersion = obj.Version : Next If Instr(strOsVersion, ".") Then strOsVersion = Left(strOsVersion, Instr(strOsVersion, ".") - 1) lngOsVersion = CLng(strOsVersion) 'If the OS is less than W2K, everybody is an admin and no UAC prompt is needed If lngOsVersion < 5 Then Exit Sub 'Find the user name (needed to see if the user is an admin) Set col = wmi.ExecQuery("SELECT * FROM Win32_ComputerSystem", "WQL", 48) strUserName = "" For Each obj In col : strUserName = obj.UserName : Next If Instr(strUserName, "\") Then strUserName = Mid(strUserName, Instr(strUserName, "\") + 1) 'See if the user is an admin blnIsAdmin = False blnHasAdmins = False Set col = wmi.ExecQuery("SELECT * FROM Win32_GroupUser", "WQL", 48) For Each obj In col strGroup = obj.GroupComponent strGroup = Split(strGroup, "=") If strGroup(UBound(strGroup)) = """Administrators""" Then blnHasAdmins = True strMember = obj.PartComponent strMember = Split(strMember, "=") If strMember(UBound(strMember)) = """" & strUserName & """" Then blnIsAdmin = True End If End If Next If blnHasAdmins = False Then blnIsAdmin = True 'If no admin group then everybody is an admin? 'Final test. No UAC prompt is needed if user is admin on something less than Vista If ((lngOsVersion < 6) And (blnIsAdmin)) Then Exit Sub 'This is definitely a directly-run script. We need to re-launch it to get a UAC. 'First collect any arguments the script has so we can re-launch it exactly the same. For lngArg = 0 To WScript.Arguments.Count - 1 If strArgs <> "" Then strArgs = strArgs & " " strArg = WScript.Arguments(lngArg) If ((InStr(strArg, " ") <> 0) Or (InStr(strArg, vbTab) <> 0)) Then strArg = """" & """" & strArg & """" & """" End If strArgs = strArgs & strArg Next 'Now build the actual command that will re-launch the script with a UAC prompt strData = "CreateObject(""Shell.Application"").ShellExecute " strData = strData & """" & """" & """" & Wscript.FullName & """" & """" & """" strData = strData & ", " strData = strData & """" & """" & """" & WScript.ScriptFullName & """" & """" If strArgs = "" Then strData = strData & """, " Else strData = strData & " " & strArgs & """, " End If strData = strData & """" & """" & """" & fs.GetParentFolderName(WScript.ScriptFullName) & """" & """" & """" strData = strData & ", " strData = strData & """runas""" strData = strData & ", 1" 'Save the UAC command in a separate script Set ts = fs.OpenTextFile(strUacFile, FOR_WRITING, True) ts.Write strData ts.Close 'Show a message Wscript.Echo "This script will need administrative priveleges." 'Launch the UAC script ws.Run "wscript.exe" & " """ & strUacFile & """", 1, False 'We MUST exit at this point and let the UAC script re-launch us. WScript.Quit End Sub Function HasScripting() 'Returns True if able to create common scripting objects (some WinXP can fail!) Dim fs, ws, sa, lngErrNum Err.Clear lngErrNum = 0 Set ws = CreateObject("WScript.Shell") lngErrNum = lngErrNum + Err.Number Set fs = CreateObject("Scripting.FileSystemObject") lngErrNum = lngErrNum + Err.Number Set sa = CreateObject("Shell.Application") lngErrNum = lngErrNum + Err.Number If lngErrNum <> 0 Then If MsgBox ("You seem to have a bad (or old) installation of Microsoft Windows Scripting. I'd like to take you to a Microsoft web page where you can download Scripting Version 5.6. May I launch your default browser to show you the download page?", vbYesNo, "Update Needed") = vbYes Then ws.Run "http://www.microsoft.com/downloads/details.aspx?FamilyId=C717D943-7E4B-4622-86EB-95A22B832CAA&displaylang=en", 1, False End If HasScripting = False Else HasScripting = True End If End Function Function OsVersion() 'Returns the base + minor version for the OS. Returns 0 on error. '3.5=NT, 4.0=95, 4.1=98, 4.9=ME, 5.0=2K, 5.1=XP, 5.2=2003, 6.0=Vista Dim strVersion, objWMI, colSystems, objOS Dim ver, strVer, strVerMajor, strVerMinor, strMajor strVersion = "0" 'Set a default of zero in case of error On Error Resume Next Set objWMI = GetObject("winmgmts:\\.\root\CIMV2") Set colSystems = objWMI.ExecQuery("SELECT * FROM Win32_OperatingSystem", "WQL", 48) For Each objOS In colSystems strVersion = objOS.Version Next Set objWMI = Nothing If InStr(strVersion, ".") > 0 Then strVersion = Left(strVersion, InStr(strVersion, ".") + 1) End If 'If WMI fails, try parsing output from the old "ver" command If strVersion = "0" Then Set ws = CreateObject("Wscript.Shell") Set ver = ws.Exec("%comspec% /c ver") Do While ver.Status = 0 WScript.Sleep 100 Loop strVer = ver.StdOut.ReadAll strVer = Split(strVer, ".") 'Get major version strMajor = strVer(0) strMajor = Split(strMajor, " ") strVerMajor = strMajor(UBound(strMajor)) 'Get minor version strVerMinor = strVer(1) strVerMinor = Left(strVerMinor, 1) 'Check results If IsNumeric(strVerMajor) And IsNumeric(strVerMinor) Then strVersion = strVerMajor & "." & strVerMinor End If End If OsVersion = strVersion End Function Function UserName() Dim objWMI, colComputers, objComputer, strUser, ws, env On Error Resume Next strUser = "" Err.Clear Set objWMI = GetObject("winmgmts:\\.\root\CIMV2") Set colComputers = objWMI.ExecQuery("SELECT * FROM Win32_ComputerSystem", "WQL", 48) If Err.Number <> 0 Then 'WMI Failure. Try environment Set ws = CreateObject("Wscript.Shell") Set env = ws.Environment("Process") strUser = env.Item("USERNAME") Else For Each objComputer In colComputers strUser = objComputer.UserName Next If Instr(strUser, "\") Then strUser = Mid(strUser, Instr(strUser, "\") + 1) End If End If Set objWMI = Nothing UserName = strUser End Function Function IsAdmin(strUserName) Dim objWMI, colUsers, objUser, strGroup, strUser, blnIsAdmin, blnHasAdmins On Error Resume Next Err.Clear Set objWMI = GetObject("winmgmts:\\.\root\CIMV2") Set colUsers = objWMI.ExecQuery("SELECT * FROM Win32_GroupUser", "WQL", 48) If Err.Number <> 0 Then 'Assume WMI failure means Win9X, implying user is an Administrator IsAdmin = True Else blnIsAdmin = False blnHasAdmins = False For Each objUser In colUsers strGroup = objUser.GroupComponent strGroup = Split(strGroup, "=") If strGroup(UBound(strGroup)) = """Administrators""" Then blnHasAdmins = True strUser = objUser.PartComponent strUser = Split(strUser, "=") If strUser(UBound(strUser)) = """" & strUserName & """" Then blnIsAdmin = True End If End If Next End If If blnHasAdmins = False Then 'If there are no members of the Administrators group, assume everybody is an admin IsAdmin = True Else IsAdmin = blnIsAdmin End If End Function