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

class ChntpwScreen	
	def initialize(extlayers, button)
		@layers = Array.new
		#### Global variables
		# Combobox for selection of partition
		@drivecombo = nil
		@partlist = Array.new
		#### Combobox for selection of Users
		@usercombo = nil
		@userlist = Array.new
		@humanusers = Array.new
		
		###### First layer for selection of windows installation
		
		fixed = Gtk::Fixed.new
		text5 = Gtk::Label.new
		text5.width_request = 230
		text5.wrap = true
		text5.set_markup("<span color='white'>Klicken Sie hier, um zum nächsten Schritt zu gelangen.</span>")
		forw  = Gtk::EventBox.new.add Gtk::Image.new("forward.png")
		
		orangetile = Gtk::Image.new("chntpwgreen.png")
		# reread = Gtk::EventBox.new.add Gtk::Image.new("buttongreen.png")
		# reread = Gtk::Button.new("Neu einlesen")
		# reread.width_request = 120
		# reread.height_request = 32
		@drivecombo = Gtk::ComboBox.new
		# @drivecombo.append_text("Yoyodyne Frobolator SATA Partition 2 500GB (sda2)") 
		# @drivecombo.active = 0
		@drivecombo.height_request = 32
		@drivecombo.width_request = 510
		deltext = TileHelpers.create_label("<b>Auswahl der Windows-Installation</b>\n\nVon welcher Windows-Installation soll die Passwort-Datenbank bearbeitet werden? Bitte beachten Sie, dass nur lokal gespeicherte Passwörter zurückgesetzt werden können.", 510)
		
		fixed.put(forw, 853, 282)
		fixed.put(text5, 605, 288)
		fixed.put(orangetile, 0, 0)
		fixed.put(deltext, 130, 0)
		# fixed.put(reread, 520, 88)
		fixed.put(@drivecombo, 130, 108)
		TileHelpers.place_back(fixed, extlayers)
		extlayers["chntpwstart"] = fixed
		@layers[0] = fixed
		button.signal_connect('button-release-event') { |x, y|
			if y.button == 1 
				# reread drives here!
				@partlist = find_win_sysparts(@drivecombo)
				extlayers.each { |k,v|v.hide_all }
				extlayers["chntpwstart"].show_all
			end
		}
		forw.signal_connect('button-release-event') { |x, y|
			if y.button == 1 
				if @partlist.size < 1 
					TileHelpers.error_dialog("Es wurde keine Windows-Installation gefunden, deren Passwort zurückgesetzt werden kann.", "Windows nicht gefunden")
				else
					# reread users here!
					@userlist, @humanusers = get_nt_users(@partlist[@drivecombo.active], @usercombo) 
					if @userlist.size < 1
						TileHelpers.error_dialog("Es wurden keine Nutzerkonten gefunden. Dies deutet auf eine defekte 	Passwort-Datenbank hin", "Keine Nutzer gefunden")
					else
						extlayers.each { |k,v|v.hide_all }
						extlayers["chntpwuser"].show_all
					end
				end
			end
		}
		
		###### Second layer for selection of user
		fixeduser = Gtk::Fixed.new
		text6 = Gtk::Label.new
		text6.width_request = 230
		text6.wrap = true
		text6.set_markup("<span color='white'>Klicken Sie hier, um das Passwort zurückzusetzen.</span>")
		forw2  = Gtk::EventBox.new.add Gtk::Image.new("forward.png")
		orange2tile = Gtk::EventBox.new.add Gtk::Image.new("chntpwgreen.png")
		usertext = TileHelpers.create_label("<b>Auswahl des Benutzerkontos</b>\n\nWessen Windows-Passwort soll zurückgesetzt werden? Nicht angezeigte Nutzer deuten auf die Verwendung von Microsoft-Benutzerkonten (Windows Live-IDs) oder eine defekte Passwort-Datenbank hin.", 510)
		TileHelpers.place_back(fixeduser, extlayers)
		@usercombo = Gtk::ComboBox.new
		@usercombo.append_text("Heinz Mustermann") 
		@usercombo.active = 0
		@usercombo.height_request = 32
		@usercombo.width_request = 510
		fixeduser.put(forw2, 853, 282)
		fixeduser.put(text6, 605, 288)
		fixeduser.put(usertext, 130, 0)
		fixeduser.put(orange2tile, 0, 0)
		fixeduser.put(@usercombo, 130, 108)
		
		extlayers["chntpwuser"] = fixeduser
		@layers[1] = fixeduser
		
		forw2.signal_connect('button-release-event') { |x, y|
			if y.button == 1 
				run_chntpw(@partlist[@drivecombo.active], @userlist[@usercombo.active])
				TileHelpers.success_dialog("Das Passwort des Benutzers " + @humanusers[@usercombo.active] + " auf " + @partlist[@drivecombo.active].device + " wurde erfolgreich zurückgesetzt! Klicken Sie auf \"OK\" um zum Startbildschirm zurückzukehren.", "Passwort zurückgesetzt")
				extlayers.each { |k,v|v.hide_all }
				extlayers["start"].show_all
			end
		}
	end
	
	attr_reader :layers
	
	def find_win_sysparts(combobox)
		drives = Array.new
		auxdrives = Array.new
		ntparts = Array.new 
		100.downto(0) { |i| 
			begin
				combobox.remove_text(i) 
			rescue
			end
		}
		Dir.entries("/sys/block").each { |l|
			if l =~ /[a-z]$/ 
				d = MfsDiskDrive.new(l, false)
				auxdrives.push(d) 
			end
		}
		mountpoint = "/var/run/lesslinux/" + $$.to_s + "/testmount"
		system("mkdir -p #{mountpoint}") unless  File.exist?(mountpoint)
		auxdrives.each { |d|
			d.partitions.each { |p|
				p.mount("ro", mountpoint)
				if File.exist?("#{mountpoint}/Windows/System32/config/SAM") ||
						File.exist?("#{mountpoint}/WINDOWS/system32/config/SAM")
					ntparts.push p
					label = label = "#{d.vendor} #{d.model}"
					if d.usb == true
						label = label + " (USB) "
					else
						label = label + " (SATA/eSATA/IDE) "
					end
					label = label + "#{p.device} #{p.human_size}"
					combobox.append_text label
				end
				p.umount 
			}
		}
		combobox.active = 0 
		return ntparts
	end

	def get_nt_users(p, combobox)
		100.downto(0) { |i| 
			begin
				combobox.remove_text(i) 
			rescue
			end
		}
		mountpoint = "/var/run/lesslinux/" + $$.to_s + "/testmount"
		# Hex!
		p.mount("ro", mountpoint) 
		samusers = Array.new
		clearusers = Array.new
		samfile = ""
		[ "#{mountpoint}/Windows/System32/config/SAM", 
			"#{mountpoint}/WINDOWS/system32/config/SAM" ].each { |s|
			samfile = s if File.exist?(s)
		}
		IO.popen("chntpw -l " + samfile + " | iconv -c -f ISO-8859-15 -t UTF-8 ") { |io|
			accstart = false
			while io.gets
				toks = $_.split("|")
				if accstart == true
					$stderr.puts "Hex ID:" + toks[1].to_s.strip
					$stderr.puts "Username: " + toks[2].to_s.strip.gsub(/[^[:print:]]/, '_')
					# samusers.push( [ toks[1].to_s.strip, toks[2].to_s.strip.gsub(/[^[:print:]]/, '_') ] )
					# samusers.push( [ toks[1].to_s.strip, toks[2].to_s.strip ] )
					samusers.push toks[1].to_s.strip
					combobox.append_text toks[2].to_s.strip
					clearusers.push toks[2].to_s.strip
				end
				accstart = true if $_ =~ / ^|\sRID/
			end
		}
		p.umount
		combobox.active = 0 
		return samusers, clearusers
	end

	def run_chntpw(partition, user)
		puts partition.device
		puts user
		mountpoint = "/var/run/lesslinux/" + $$.to_s + "/testmount"
		partition.mount("rw", mountpoint) 
		samfile = ""
		[ "#{mountpoint}/Windows/System32/config/SAM", 
			"#{mountpoint}/WINDOWS/system32/config/SAM" ].each { |s|
			samfile = s if File.exist?(s)
		}
		# valid_reg = system('echo -e "q\n" | chntpw -e ' + reg_file) 
		exstring = "printf \"1\\ny\\n\" | chntpw -u 0x" + user + " " + samfile
		# exstring = 'echo -e "1\ny\n" | chntpw -u 0x' + user + ' ' + samfile
		puts exstring
		retval = system(exstring)
		partition.umount 
		puts retval.to_s
		return retval
	end
	
	
	
end