#!/usr/bin/ruby
# encoding: utf-8

class VirusScreen	
	def initialize(extlayers, button, nwscreen)
		lang = ENV['LANGUAGE'][0..1]
		lang = ENV['LANG'][0..1] if lang.nil?
		lang = "en" if lang.nil?
		@tl = MfsTranslator.new(lang, "VirusScreen.xml")
		@layers = Array.new
		@extlayers = extlayers 
		@nwscreen = nwscreen
		#### Partitions etc.
		#### Table for deletion of single partitions
		@parttable = nil
		# list of drives
		@partdrives = Array.new
		# shown partitions
		@partparts = Array.new
		# headers
		@partheaders = Array.new
		# checkboxes
		@partchecks = Array.new
		# labels
		@partlabels = Array.new
		#### progress bar for virus search
		@progressbar = nil
		#### VTE for signature update
		@sigs_vte = Vte::Terminal.new
		@sigs_update_running = false
		@sigs_vte.signal_connect("child-exited") { @sigs_update_running = false } 
		#### VTE for scancl check
		@check_vte = Vte::Terminal.new
		@check_running = false
		@check_vte.signal_connect("child-exited") { @check_running = false } 
		#### VTE for scancl virus scan
		@scan_vte = Vte::Terminal.new
		@scan_running = false
		@scan_vte.signal_connect("child-exited") { @scan_running = false } 
		@scan_log_button = Gtk::Button.new(@tl.get_translation("details"))
		#### Label with scan results at the end
		@resultlabel = nil
		#### Was the scan killed?
		@scan_killed = false
		#### Was a BKA trojan found?
		@bka_found = false
		#### Which virus scanner is available
		@scanner = "clamscan"
		@scanner = "scancl" if File.exists?("/AntiVir/scancl") 
		$stderr.puts "virus scanner found: #{@scanner}"
		
		### Radiobuttons for methods 
		@archive_yes_radio = Gtk::RadioButton.new
		@archive_no_radio = Gtk::RadioButton.new(@archive_yes_radio)
		@archive_no_radio.active = true
		@action_delete_radio = Gtk::RadioButton.new
		@action_ignore_radio = Gtk::RadioButton.new(@action_delete_radio)
		@action_ignore_radio.active = true
		@action_show_radio = Gtk::RadioButton.new(@action_delete_radio)
		
		fixed = Gtk::Fixed.new
		throbber = Gtk::EventBox.new.add Gtk::Image.new("throbber.gif")
		throbtext = Gtk::Label.new
		throbtext.width_request = 250
		throbtext.wrap = true
		throbtext.set_markup('<span foreground="white">' + @tl.get_translation("sigupdate") + '</span>')
		text5 = Gtk::Label.new
		text5.width_request = 250
		text5.wrap = true
		text5.set_markup("<span color='white'>" + @tl.get_translation("gotonext") + "</span>")
		forw  = Gtk::EventBox.new.add Gtk::Image.new("forward.png")
		archtext = TileHelpers.create_label("<b>" + @tl.get_translation("settingshead") + "</b>\n\n" + @tl.get_translation("settingsbody") , 510)
		actiontext =  TileHelpers.create_label(@tl.get_translation("actionquest"), 510)
		
		yestext = TileHelpers.create_label("<b>" + @tl.get_translation("yes") + "</b>, " + @tl.get_translation("archiveyes"), 380)
		notext = TileHelpers.create_label("<b>" + @tl.get_translation("no") + "</b>, " + @tl.get_translation("archiveno"), 380)
		actdeltext = TileHelpers.create_label(@tl.get_translation("repairdelete"), 380)
		actigntext = TileHelpers.create_label(@tl.get_translation("repairrename"), 380)
		actshowtext = TileHelpers.create_label(@tl.get_translation("justshow"), 380)
	
		button1 = Gtk::Image.new("virusgreen.png")
		button2 = Gtk::Image.new("virusgreen.png")
		aviralogo = Gtk::Image.new("aviralogo.png")
		fixed.put(button1, 0, 0)
		fixed.put(aviralogo, 660, 0)
		# fixed.put(button2, 0, 130)
		fixed.put(archtext, 130, 0)
		fixed.put(actiontext, 130, 160)
		fixed.put(@archive_yes_radio, 140, 80)
		fixed.put(@archive_no_radio, 140, 110)
		fixed.put(yestext, 165, 83)
		fixed.put(notext, 165, 113)
		fixed.put(@action_delete_radio, 140, 190)
		fixed.put(@action_ignore_radio, 140, 215)
		fixed.put(@action_show_radio, 140, 240)
		fixed.put(actdeltext, 165, 193)
		fixed.put(actigntext, 165, 218)
		fixed.put(actshowtext, 165, 243)
	
		fixed.put(forw, 853, 282)
		fixed.put(text5, 605, 288)
		TileHelpers.place_back(fixed, extlayers)
		# fixed.put(throbber, 0, 332)
		# fixed.put(throbtext, 52, 338)
		
		extlayers["virusstart"] = fixed
		@layers[0] = fixed
		button.signal_connect('button-release-event') { |x, y|
			if y.button == 1 
				extlayers.each { |k,v|v.hide_all }
				if nwscreen.test_connection == false
					nwscreen.nextscreen = "virusstart"
					nwscreen.fill_wlan_combo 
					# Check for networks first...
					extlayers["networks"].show_all
				else
					system("/etc/rc.d/0611-scancl-blob.sh start") 
					extlayers["virusstart"].show_all
				end
			end
		}
		forw.signal_connect('button-release-event') { |x, y|
			if y.button == 1 
				@partdrives, @partparts, @partheaders, @partchecks, @partlabels = fill_part_tab(@parttable, @partheaders, @partchecks, @partlabels)
				extlayers.each { |k,v|v.hide_all }
				system("/etc/rc.d/0611-scancl-blob.sh start") 
				extlayers["virusdrives"].show_all
			end
		}
		extlayers["virusdrives"] = create_drive_screen(extlayers)
		@layers[1] = extlayers["virusdrives"]
		extlayers["virusprogress"] = create_progress_screen(extlayers)
		@layers[2] = extlayers["virusprogress"]
		extlayers["virusresult"] = create_result_screen(extlayers)
		@layers[3] = extlayers["virusresult"]
	end
	attr_reader :layers, :scanner
	
	def create_drive_screen(extlayers)
		### Layer for deletion of single partitions
		fixed = Gtk::Fixed.new
		tile = Gtk::Image.new("virusgreen.png")
		TileHelpers.place_back(fixed, extlayers)
		delscroll = Gtk::ScrolledWindow.new
		delscroll.height_request = 195
		delscroll.width_request = 760
		delscroll.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ) 
		drivetext = TileHelpers.create_label("<b>" + @tl.get_translation("drivehead") + "</b>\n\n" + @tl.get_translation("drivebody"), 510)
		# Table for drives
		@parttable = Gtk::Table.new(2, 11, false)
		align = Gtk::Alignment.new(0, 0, 0.1, 0.1)
		align.add @parttable
		delscroll.add_with_viewport align
		anc = @parttable.get_ancestor(Gtk::Viewport)
		anc.modify_bg(Gtk::STATE_NORMAL, Gdk::Color.parse('#00419c') )
		# puts anc.to_s
		# Forward button:
		text5 = TileHelpers.create_label(@tl.get_translation("gotoscan"), 250)
		forw  = Gtk::EventBox.new.add Gtk::Image.new("forward.png")
		forw.signal_connect('button-release-event') { |x, y|
			if y.button == 1 
				extlayers.each { |k,v|v.hide_all }
				system("/etc/rc.d/0611-scancl-blob.sh start") 
				extlayers["virusprogress"].show_all
				run_virus_check
			end
		}
		fixed.put(tile, 0, 0)
		fixed.put(delscroll, 130, 65)
		fixed.put(drivetext, 130, 0)
		fixed.put(forw, 853, 282)
		fixed.put(text5, 605, 288)
		return fixed
	end
	
	def create_progress_screen(extlayers)
		fixed = Gtk::Fixed.new
		tile = Gtk::Image.new("virusgreen.png")
		drivetext = TileHelpers.create_label("<b>" + @tl.get_translation("scanhead") +"</b>\n\n" + @tl.get_translation("scanbody"), 510)
		@progressbar = Gtk::ProgressBar.new
		@progressbar.width_request = 415
		@progressbar.height_request = 32
		@scan_log_button.width_request = 90
		@scan_log_button.height_request = 32
		cancelbutton = TileHelpers.place_back(fixed, extlayers, false)
		fixed.put(tile, 0, 0)
		fixed.put(@progressbar, 130, 88)
		fixed.put(@scan_log_button, 550, 88)
		@scan_log_button.signal_connect('clicked') {
			system("/usr/bin/Terminal --hide-menubar -e 'tail -f /var/log/virusscan.log' &") 
		}
		cancelbutton.signal_connect('button-release-event') { |x, y|
			if y.button == 1 
				@scan_killed = true
				system("killall scancl")
				sleep 1.0
				system("killall -9 scancl") 
				extlayers.each { |k,v|v.hide_all }
				extlayers["start"].show_all
			end
		}
		fixed.put(drivetext, 130, 0)
		return fixed
	end
	
	def create_result_screen(extlayers)
		fixed = Gtk::Fixed.new
		tile = Gtk::Image.new("virusgreen.png")
		@resultlabel = TileHelpers.create_label("<b>" + @tl.get_translation("resulthead") +  "</b>\n\n" + @tl.get_translation("resultbody"), 510)
		log_button = Gtk::Button.new(@tl.get_translation("showprotocol") )
		log_button.width_request = 150
		log_button.height_request = 32
		fixed.put(tile, 0, 0)
		fixed.put(@resultlabel, 130, 0)		
		fixed.put(log_button, 490, 240)
		log_button.signal_connect('clicked') {
			system("gedit /var/log/virusscan.log &") 
		}
		TileHelpers.place_back(fixed, extlayers)
		return fixed
	end
	
	def fill_part_tab(table, oldheaders, oldchecks, oldlabels)
		TileHelpers.umount_all
		table.row_spacings = 4
		parts = Array.new
		headers = Array.new
		drives = Array.new
		checks = Array.new
		labels = Array.new
		Dir.entries("/sys/block").each { |l|
			drives.push(MfsDiskDrive.new(l, false)) if l =~ /[a-z]$/ 
		}
		oldheaders.each { |h| table.remove h }
		oldlabels.each{ |l| table.remove l } 
		oldchecks.each{ |c| table.remove c } 
		
		table.resize(drives.size * 100, 2)
		rowcount = 0
		drives.each { |d|
			label = "<b>#{d.vendor} #{d.model} - #{d.human_size} - #{d.device}"
			if d.usb == true
				label = label + " (USB)</b>\n"
			else
				label = label + " (SATA/eSATA/IDE)</b>\n"
			end
			l = TileHelpers.create_label(label, 670)
			l.height_request = 17
			headers.push l
			table.attach(l, 0, 2, rowcount, rowcount+1)
			rowcount += 1
			d.partitions.each { |p|
				unless p.fs.to_s.strip == ""
					pt = "#{p.device} - #{p.human_size} - #{p.fs}"
					mnt, opt = p.mount_point
					iswin, winvers = p.is_windows
					pt = pt + " - " + winvers if iswin
					if p.system_partition? == true
						pt = @tl.get_translation("notesystem").gsub("PARTITIONNAME", pt) 
					elsif mnt.nil? == false
						pt = @tl.get_translation("noteinuse").gsub("PARTITIONNAME", pt) 
					end
					pl = TileHelpers.create_label(pt, 650)
					cb = Gtk::CheckButton.new
					cb.active = true if p.fs =~ /ntfs/ || p.fs =~ /vfat/  
					cb.active = false unless mnt.nil?
					cb.sensitive = false unless mnt.nil? 
					labels.push pl
					checks.push cb
					parts.push p
					table.attach(pl, 1, 2, rowcount, rowcount+1)
					table.attach(cb, 0, 1, rowcount, rowcount+1)
					rowcount += 1
				end
			}
			
		}
		table.resize(rowcount, 2)
		return drives, parts, headers, checks, labels
	end
	
	def run_virus_check
		if @scanner == "scancl"
			run_virus_check_scancl 
		else
			run_virus_check_clamav
		end
	end
	
	def run_virus_check_clamav
		@bka_found = false
		@scan_killed == false
		@scan_log_button.sensitive = false
		update_signatures
		while @sigs_update_running == true
			sleep 0.2
			@progressbar.text = @tl.get_translation("progresssigs")
			@progressbar.pulse 
			while (Gtk.events_pending?)
				Gtk.main_iteration
			end
		end
		# Now run the real check for malicious software
		scanparams = Array.new
		scanparams.push("/opt/bin/clamscan")
		scanparams.push("--recursive=yes")
		scanparams.push("--scan-archive=no") unless @archive_yes_radio.active?
		scanparams.push("--scan-mail=no")
		scanparams.push("--scan-html=no")
		scanparams.push("--follow-dir-symlinks=0")
		scanparams.push("--follow-file-symlinks=0")
		scanparams.push("--remove=yes") if @action_delete_radio.active?
		scanparams.push("--log=/var/log/virusscan.log")
		
		# scanparams.push("--defaultaction=clean,delete,delete-archive") if @action_delete_radio.active?
		# scanparams.push("--defaultaction=clean,rename") if @action_ignore_radio.active?
		# scanparams.push("--defaultaction=ignore") if @action_show_radio.active?
		
		scanparams.push("/media")
		puts scanparams.join(" ")
		if @scan_killed == true
			@extlayers.each { |k,v|v.hide_all }
			@extlayers["start"].show_all 
			return false
		end
		0.upto(@partchecks.size - 1) { |n|
			if @partchecks[n].active? 
				system("mkdir -p /media/" + @partparts[n].device)
				@partparts[n].mount("rw", "/media/" + @partparts[n].device)
			end
		}
		scan_clamscan(scanparams)
		@scan_log_button.sensitive = true
		while @scan_running == true
			sleep 0.2
			@progressbar.text = @tl.get_translation("progressscan")
			@progressbar.pulse 
			while (Gtk.events_pending?)
				Gtk.main_iteration
			end
		end
		@scan_log_button.sensitive = false
		0.upto(@partchecks.size - 1) { |n|
			if @partchecks[n].active? 
				repair_shell = false
				repair_shell = true if @action_delete_radio.active? || @action_ignore_radio.active?
				@bka_found = true if bka_check(@partparts[n], repair_shell)  == true
				# @partparts[n].umount
			end
		}
		if @scan_killed == true
			TileHelpers.umount_all 
			@extlayers.each { |k,v|v.hide_all }
			@extlayers["start"].show_all 
			return false
		end
		
		# Now analyze the log file and jump to the result screen
		analyze_log(@action_ignore_radio.active?)
		TileHelpers.umount_all 
		@extlayers.each { |k,v|v.hide_all }
		@extlayers["virusresult"].show_all 
		 
	end
	
	def run_virus_check_scancl
		@bka_found = false
		@scan_killed == false
		@scan_log_button.sensitive = false
		# count files
		# filecount = 0
		# 0.upto(@partchecks.size - 1) { |n|
		#	filecount += @partparts[n].filecount(@progressbar) if @partchecks[n].active? 
		# }
		# update signatures - if not already done in background
		update_signatures
		while @sigs_update_running == true
			sleep 0.2
			@progressbar.text = @tl.get_translation("progresssigs") 
			@progressbar.pulse 
			while (Gtk.events_pending?)
				Gtk.main_iteration
			end
		end
		# check usability of scancl
		check_scancl
		while @check_running == true
			sleep 0.2
			@progressbar.text = @tl.get_translation("progresscheck")
			@progressbar.pulse 
			while (Gtk.events_pending?)
				Gtk.main_iteration
			end
		end
		check_success = File.read("/var/log/scancl-check.ret").strip.to_i
		if check_success > 0 && @scan_killed == false
			TileHelpers.error_dialog(@tl.get_translation("scannerdefectbody"), @tl.get_translation("scannerdefecthead"))
			@extlayers.each { |k,v|v.hide_all }
			@extlayers["start"].show_all 
		end
		# Now run the real check for malicious software
		scanparams = Array.new
		scanparams.push("/AntiVir/scancl")
		scanparams.push("--recursion")
		scanparams.push("-z") if @archive_yes_radio.active? 
		scanparams.push("--defaultaction=clean,delete,delete-archive") if @action_delete_radio.active?
		scanparams.push("--defaultaction=clean,rename") if @action_ignore_radio.active?
		scanparams.push("--defaultaction=ignore") if @action_show_radio.active?
		scanparams.push("--heurlevel=2")
		scanparams.push("--nolinks")
		scanparams.push("--log=/var/log/virusscan.log")
		scanparams.push("--logformat=singleline")
		scanparams.push("/media")
		puts scanparams.join(" ")
		if @scan_killed == true
			@extlayers.each { |k,v|v.hide_all }
			@extlayers["start"].show_all 
			return false
		end
		0.upto(@partchecks.size - 1) { |n|
			if @partchecks[n].active? 
				system("mkdir -p /media/disk/" + @partparts[n].device)
				@partparts[n].mount("rw", "/media/disk/" + @partparts[n].device)
				#repair_shell = false
				#repair_shell = true if @action_delete_radio.active? || @action_ignore_radio.active?
				#bka_check(@partparts[n], repair_shell) 
			end
		}
		scan_scancl(scanparams)
		@scan_log_button.sensitive = true
		while @scan_running == true
			sleep 0.2
			@progressbar.text = @tl.get_translation("progressscan")
			@progressbar.pulse 
			while (Gtk.events_pending?)
				Gtk.main_iteration
			end
		end
		@scan_log_button.sensitive = false
		0.upto(@partchecks.size - 1) { |n|
			if @partchecks[n].active? 
				repair_shell = false
				repair_shell = true if @action_delete_radio.active? || @action_ignore_radio.active?
				@bka_found = true if bka_check(@partparts[n], repair_shell)  == true
				@partparts[n].umount
			end
		}
		if @scan_killed == true
			@extlayers.each { |k,v|v.hide_all }
			@extlayers["start"].show_all 
			return false
		end
		
		TileHelpers.umount_all 
		# Now analyze the log file and jump to the result screen
		analyze_log
		@extlayers.each { |k,v|v.hide_all }
		@extlayers["virusresult"].show_all 
		 
	end
	
	def update_signatures
		if @scanner == "scancl"
			update_signatures_scancl 
		else
			update_signatures_clamav
		end
	end
	
	def update_signatures_clamav
		return false if @sigs_update_running == true
		return false if @nwscreen.test_connection == false
		@sigs_update_running = true
		@sigs_vte.fork_command("/bin/bash", [ "/bin/bash", "freshclam_wrapper.sh" ] )
	end
	
	def update_signatures_scancl
		return false if @sigs_update_running == true
		return false if @nwscreen.test_connection == false
		@sigs_update_running = true
		@sigs_vte.fork_command("/bin/bash", [ "/bin/bash", "avupdate_wrapper.sh" ] )
	end
	
	def check_scancl
		return false if @check_running == true
		system("install -m 0644 /etc/avira/hbedv.key /AntiVir/hbedv.key") if File.exists?("/AntiVir/rescue_cd.key") 
		@check_running = true
		@check_vte.fork_command("/bin/bash", [ "/bin/bash", "check_wrapper.sh" ]  )
	end
	
	def scan_scancl(scanparams)
		return false if @scan_running == true
		@scan_running = true
		@scan_vte.fork_command("/AntiVir/scancl", scanparams )
	end
	
	def scan_clamscan(scanparams)
		return false if @scan_running == true
		system("rm /var/log/virusscan.log") 
		@scan_running = true
		@scan_vte.fork_command("/opt/bin/clamscan", scanparams )
	end
	
	def analyze_log(move=false)
		if @scanner == "scancl"
			analyze_log_scancl 
		else
			analyze_log_clamav(move)
		end
	end
	
	def analyze_log_clamav(move)
		inside = false
		infected = 0
		total = 0
		text = ""
		File.open("/var/log/virusscan.log").each { |line|
			ltoks = line.strip.split(': ')
			inside = true if line =~ /SCAN SUMMARY/ 
			if inside == true && line =~ /Scanned files/
				total = line.split(': ')[1].to_i 
			end
			if ltoks[1] =~ /FOUND$/ 
				infected += 1
				unless ( move == false || ltoks[0] =~ /\.vir$/ ) 
					begin
						File.rename(ltoks[0], ltoks[0] + ".vir")
					rescue
					end
				end
			end
		}
		if inside == false 
			text = "<b>" + @tl.get_translation("scancancelledhead") + "</b>\n\n" + @tl.get_translation("scancancelledbody")  
		elsif infected < 1
			text = "<b>" + @tl.get_translation("nomalwarehead") + "</b>\n\n" + @tl.get_translation("nomalwarebody").gsub("FILECOUNT", total.to_s) 
		elsif @action_show_radio.active? == true
			text = "<b>" + @tl.get_translation("malwarehead") + "</b>\n\n" + @tl.get_translation("malwareshow") .gsub("FILECOUNT", total.to_s).gsub("INFECTEDCOUNT", infected.to_s) 
		else
			text = "<b>" + @tl.get_translation("malwarehead") + "</b>\n\n" + @tl.get_translation("malwareremoved") .gsub("FILECOUNT", total.to_s).gsub("INFECTEDCOUNT", infected.to_s) 
		end
		#### BKA-Trojaner-Text
		if @bka_found == true && @action_show_radio.active? == true
			text = text + "\n\n<b>" + @tl.get_translation("ransomhead") + "</b>\n\n" + @tl.get_translation("ransomshow")
		elsif @bka_found == true
			text = text + "\n\n<b>" + @tl.get_translation("ransomhead") + "</b>\n\n" + @tl.get_translation("ransomremove")
		end
		@resultlabel.set_markup("<span color='white'>#{text}</span>") 
	end
	
	def analyze_log_scancl 
		inside = false
		infected = 0
		total = 0
		text = ""
		File.open("/var/log/virusscan.log").each { |line|
			begin 
				inside = true if line.strip =~ /^Statistics/ 
			rescue
			end
			if inside == true
				ltoks = line.strip.split
				if line.strip =~ /^Infected/
					infected = ltoks[-1].to_i 
				elsif line.strip =~ /^Files/
					total = ltoks[-1].to_i 
				end
			end
		}
		if inside == false 
			text = "<b>" + @tl.get_translation("scancancelledhead") + "</b>\n\n" + @tl.get_translation("scancancelledbody")  
		elsif infected < 1
			text = "<b>" + @tl.get_translation("nomalwarehead") + "</b>\n\n" + @tl.get_translation("nomalwarebody").gsub("FILECOUNT", total.to_s) 
		elsif @action_show_radio.active? == true
			text = "<b>" + @tl.get_translation("malwarehead") + "</b>\n\n" + @tl.get_translation("malwareshow") .gsub("FILECOUNT", total.to_s).gsub("INFECTEDCOUNT", infected.to_s) 
		else
			text = "<b>" + @tl.get_translation("malwarehead") + "</b>\n\n" + @tl.get_translation("malwareremoved") .gsub("FILECOUNT", total.to_s).gsub("INFECTEDCOUNT", infected.to_s) 
		end
		#### BKA-Trojaner-Text
		if @bka_found == true && @action_show_radio.active? == true
			text = text + "\n\n<b>" + @tl.get_translation("ransomhead") + "</b>\n\n" + @tl.get_translation("ransomshow")
		elsif @bka_found == true
			text = text + "\n\n<b>" + @tl.get_translation("ransomhead") + "</b>\n\n" + @tl.get_translation("ransomremove")
		end
		
		@resultlabel.set_markup("<span color='white'>#{text}</span>") 
	end
	
	# Check for BKA Ukash trojan, those modify the SHELL
	
	def bka_check(partition, purge)
		return false unless partition.fs =~ /ntfs/ || partition.fs =~ /vfat/
		# assume partition is mounted
		return false if partition.mount_point.nil?
		reg_file = nil 
		path = partition.mount_point[0]
		Dir.entries(path).each { |w|
			if w =~ /^windows$/i
				path = path + "/" + w 
				Dir.entries(path).each { |s|
					if s =~ /^system32$/i 
						path = path + "/" + s 
						Dir.entries(path).each { |c|
							if c =~ /^config$/i
								path = path + "/" + c
								Dir.entries(path).each { |r|
									reg_file = path + "/" + r if r =~/^software$/i 
								}
							end
						}
					end
				}
			end
		}
		puts "No registry file found!"
		return false if reg_file.nil?
		valid_reg = system('echo -e "q\n" | chntpw -e ' + reg_file ) 
		if valid_reg == false
			TileHelpers.error_dialog(@tl.get_translation("damagedregbody").gsub("REGFILE", reg_file) , @tl.get_translation("damagedreghead") )
			return false
		end
		shell = get_shell(reg_file)
		return false if shell =~ /^explorer\.exe$/i 
		if purge == true
			puts "Repair shell! " + shell 
			reset_shell(reg_file)
			shell = get_shell(reg_file)
		end
		return true 
	end
	
	def get_shell(reg_file)
		valid_reg = system('echo -e "q\n" | chntpw -e ' + reg_file) 
		return nil if valid_reg == false
		lcount = 0
		nline = -1
		shell = nil
		IO.popen("printf \"cat Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Shell\\nq\\n\" | chntpw -e " + reg_file ) { |l| 
			while l.gets
				nline = lcount if $_ =~ /currentversion.winlogon.shell/i 
				shell = $_.strip if lcount == nline + 1  
				lcount += 1
			end
		}
		puts "Shell found! #{shell.to_s}"
		return shell
	end
	
	def reset_shell(reg_file)
		success = system("printf \"cd Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\ncat Shell\\ned Shell\\nexplorer.exe\\ncat Shell\\nq\\ny\\n\" | chntpw -e " + reg_file) 
		return success 
	end
	
end