#NoTrayIcon
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=T:\FirefoxPrompt.ico
#AutoIt3Wrapper_Outfile=T:\FirefoxPrompt.exe
#AutoIt3Wrapper_UseX64=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
; ===============================================================
; This script was designed for brooksndun at eightforums.com
;
; It's messy and probably could be written better, however it
; appears to work correctly without any major issues.
;
; This script attempts to circumvent programs opening firefox
; without permission.
;
; This is deisgned to only work with Firefox, and
; will not prevent other browsers from being
; launched.
;
; This script is to be used at your own risk.
; Nobody can be held responsible for the use
; or misuse of this script, or any outcome
; from the use or misuse of this script.
;
; ===============================================================
#include <Process.au3>
#include <file.au3>
Main()
Func Main()
Local $Firefox = @ScriptDir&"\firefox.exe"
Local $FirefoxBin = @ScriptDir&"\firefox-bin.exe"
Local $NewCmdLine = $CmdLineRaw
; Ensures script is compiled. It will not function correctly unless compiled.
If Not @Compiled Then
MsgBox(0,"","Error: Script is not compiled."[EMAIL="&@CRLF&@CRLF&"This"]&@CRLF&@CRLF&"This[/EMAIL] script uses WindowsAPI calls which will not work properly unless the scrip is compiled into an exe")
Exit
EndIf
; Check if firefox.exe is our directory
If Not FileExists($Firefox) Then
MsgBox(0,"","Error: Cannot fine firefox.exe"[EMAIL="&@CRLF&@CRLF&"Please"]&@CRLF&@CRLF&"Please[/EMAIL] place in the same directory as firefox.exe")
Exit
EndIf
; Main logic of the script
If Not CheckIfHijackInstalled() Then
CreateImageHijackFile()
Exit
Else
FirefoxBinSetup($Firefox, $FirefoxBin)
Local $Parent = "Process No Longer Exists"
Local $ParentPID = ScriptGetParentProcess()
If ProcessExists($ParentPID) Then
$Parent = _ProcessGetName($ParentPID)
EndIf
If $CmdLine[0] > 0 Then
If $CmdLine[1] = "firefox.exe" OR $CmdLine[1] = $Firefox Then
$NewCmdLine = StringReplace($NewCmdLine, $CmdLine[1], "")
$NewCmdLine = StringReplace($NewCmdLine, '""', '')
EndIf
EndIf
If $Parent = "explorer.exe" Then
LaunchFirefox($FirefoxBin, $NewCmdLine)
Exit
EndIf
Local $Action = MsgBox(308,"Firefox launch", "Allow Firefox to launch?"[EMAIL="&@CRLF&"Calling"]&@CRLF&"Calling[/EMAIL] Process: "[EMAIL="&$Parent&@CRLF&@CRLF&"Commandline"]&$Parent&@CRLF&@CRLF&"Commandline[/EMAIL]: "&$NewCmdLine)
Switch $Action
Case 6 ;yes
LaunchFirefox($FirefoxBin, $NewCmdLine)
Exit
Case Else ;no or anything else
Exit
EndSwitch
EndIf
EndFunc
Func LaunchFirefox($FirefoxBin, $NewCmdLine)
Run($FirefoxBin&' '&$NewCmdLine)
EndFunc
; Check if we're still properly installed, if not warn user and offer to install or properly uninstall
Func CheckIfHijackInstalled() ; Bool
Local $Ret = True
Local $Debugger = RegRead("HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\firefox.exe", "Debugger")
If Not FileExists(StringReplace($Debugger,'"','')) Or StringReplace($Debugger,'"','') <> @ScriptFullPath Then
$Ret = False
EndIf
Return $Ret
EndFunc
; Creates .reg file to properly install image hijack for script
Func CreateImageHijackFile()
CreateUninstaller()
Local $File_RegSetup = @DesktopDir&"\Firefox Prompt Registry Install.reg"
If FileExists($File_RegSetup) Then FileDelete($File_RegSetup)
If @error Then
MsgBox(0,"",'There was an error creating the registry file, please ensure "' & $File_RegSetup & '" does not [EMAIL="exist.'&@CRLF&@CRLF&'If"]exist.'&@CRLF&@CRLF&'If[/EMAIL] the file does exist, delete it and try again')
Exit
EndIf
FileWriteLine($File_RegSetup,"Windows Registry Editor Version 5.00")
If @error Then
MsgBox(0,"",'Permission [EMAIL="error.'&@CRLF&@CRLF&'Insufficient"]error.'&@CRLF&@CRLF&'Insufficient[/EMAIL] permissions to create file: "' & $File_RegSetup & '"')
Exit
EndIf
Local $RegScriptPath = StringReplace(@ScriptFullPath,'\','\\')
IniWrite($File_RegSetup, "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\firefox.exe", '"Debugger"', '"'&$RegScriptPath&'"')
If @error Then
MsgBox(0,"",'Permission [EMAIL="error.'&@CRLF&@CRLF&'Insufficient"]error.'&@CRLF&@CRLF&'Insufficient[/EMAIL] permissions to create file: "' & $File_RegSetup & '"')
Exit
EndIf
MsgBox(0,"","The registry file has been created on your desktop."[EMAIL="&@CRLF&@CRLF&"Please"]&@CRLF&@CRLF&"Please[/EMAIL] merge the registry file into the system registry to complete the setup."[EMAIL="&@CRLF&@CRLF&"Then"]&@CRLF&@CRLF&"Then[/EMAIL] firefox.exe should be properly set to prompt when executed")
EndFunc
; Copies firefox.exe to firefox-bin.exe so that the image hijack works correcly (breaks taskbar grouping)
Func FirefoxBinSetup($Firefox, $FirefoxBin)
If ProcessExists("firefox-bin.exe") Then Return
If FileExists($FirefoxBin) Then
Local $FirefoxSize = FileGetSize($Firefox)
Local $FirefoxBinSize = FileGetSize($FirefoxBin)
If $FirefoxBinSize = $FirefoxSize Then
Return
EndIf
EndIf
FileCopy($Firefox,$FirefoxBin)
EndFunc
; Create uninstaller batch file
Func CreateUninstaller()
Local $UninstallFile = @ScriptDir&"\UninstallFirefoxPrompt (Run as admin).bat"
If FileExists($UninstallFile) Then Return
FileWriteLine($UninstallFile, [EMAIL="'@ECHO"]'@ECHO[/EMAIL] OFF')
FileWriteLine($UninstallFile, 'REG DELETE "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\firefox.exe" /f')
FileWriteLine($UninstallFile, 'PAUSE')
EndFunc
; Finds the parent process of this script
; Thanks to SmOke_N of the AutoIt community forums.
Func ScriptGetParentProcess() ; Int (PID)
; * Requires the script be compiled into an exe
; * Requires the compiled script use 32 bit AutoIt
Local Const $TH32CS_SNAPPROCESS = 0x00000002
Local $a_tool_help = DllCall("Kernel32.dll", "long", "CreateToolhelp32Snapshot", "int", $TH32CS_SNAPPROCESS, "int", 0)
If IsArray($a_tool_help) = 0 Or $a_tool_help[0] = -1 Then Return SetError(1, 0, @AutoItPID)
Local $tagPROCESSENTRY32 = _
DllStructCreate _
( _
"dword dwsize;" & _
"dword cntUsage;" & _
"dword th32ProcessID;" & _
"uint th32DefaultHeapID;" & _
"dword th32ModuleID;" & _
"dword cntThreads;" & _
"dword th32ParentProcessID;" & _
"long pcPriClassBase;" & _
"dword dwFlags;" & _
"char szExeFile[260]" _
)
DllStructSetData($tagPROCESSENTRY32, 1, DllStructGetSize($tagPROCESSENTRY32))
Local $p_PROCESSENTRY32 = DllStructGetPtr($tagPROCESSENTRY32)
Local $a_pfirst = DllCall("Kernel32.dll", "int", "Process32First", "long", $a_tool_help[0], "ptr", $p_PROCESSENTRY32)
If IsArray($a_pfirst) = 0 Then Return SetError(2, 0, @AutoItPID)
Local $a_pnext, $i_return = 0
If DllStructGetData($tagPROCESSENTRY32, "th32ProcessID") = @AutoItPID Then
$i_return = DllStructGetData($tagPROCESSENTRY32, "th32ParentProcessID")
DllCall("Kernel32.dll", "int", "CloseHandle", "long", $a_tool_help[0])
If $i_return Then Return $i_return
Return @AutoItPID
EndIf
While 1
$a_pnext = DLLCall("Kernel32.dll", "int", "Process32Next", "long", $a_tool_help[0], "ptr", $p_PROCESSENTRY32)
If IsArray($a_pnext) And $a_pnext[0] = 0 Then ExitLoop
If DllStructGetData($tagPROCESSENTRY32, "th32ProcessID") = @AutoItPID Then
$i_return = DllStructGetData($tagPROCESSENTRY32, "th32ParentProcessID")
If $i_return Then ExitLoop
$i_return = @AutoItPID
ExitLoop
EndIf
WEnd
If $i_return = "" Then $i_return = @AutoItPID
DllCall("Kernel32.dll", "int", "CloseHandle", "long", $a_tool_help[0])
Return $i_return
EndFunc