########
# define
########
var            App
!define LNK    `${DATA}\Plug-Ins.lnk`
!define DOC    `${DATA}\My Documents`
!define PLG    `${APPDIR}\Plug-Ins`
!define EXE    `${APPDIR}\ExamDiff.exe`
!define 64     `$EXEDIR\App\ExamDiff64\ExamDiff.exe`
!define SET32  `Kernel32::SetEnvironmentVariable(t "EXAMDIFF", t "ExamDiff")`
!define SET64  `Kernel32::SetEnvironmentVariable(t "EXAMDIFF", t "ExamDiff64")`
!define INT    `Shell integration`
!define KEY    `Software\PrestoSoft\ExamDiff Pro\Shell`
!define CLSID  SOFTWARE\Classes\CLSID\{58549232-7081-4541-882C-767DB238453C}\InprocServer32
!define DLL    `${APPDIR}\EDPShell32.dll`
!define DLL64  `${APPDIR}\EDPShell.dll`
!define REG    `${SET}\${APP}.reg`
!define DEFREG `${DEFSET}\${APP}.reg`
!define P      `$PLUGINSDIR\PortableWares.p12`
!define i      `"$SYSDIR\certutil.exe" -importpfx -p "" "${P}"`
!define G      `Kernel32::GetVolumeInformation(t,t,i,*i,*i,*i,t,i) i`
!define GET    `${G}("$0",,${NSIS_MAX_STRLEN},.r0,,,,${NSIS_MAX_STRLEN})`
!define ID     `Kernel32::SetEnvironmentVariable(t "LastUniqueID", t "$0")`
#######
# macro
#######
!define SetLastPath "!insertmacro _SetLastPath"
!macro _SetLastPath _ENTRY _VAR _SWITCH _PATH
	ClearErrors
	ReadINIStr $0 `${SETINI}` ${APPNAME}Settings ${_ENTRY}
	IfErrors +2
	StrCmpS $0 "" 0 +5
	StrCmpS ${_SWITCH} copy 0 +3
	StrCpy $0 ${_VAR}
	Goto +2
	ReadEnvStr $0 ${_VAR}
	StrCmpS ${_PATH} 1 0 +5
	Push "${_ENTRY}"
	Push "$0"
	Call SetVariablesPath
	Goto +2
	System::Call `Kernel32::SetEnvironmentVariable(t "${_ENTRY}", t "$0")`
!macroend
Function Close
	!macro _Close _CLASS _TITLE
		Push `${_TITLE}`
		Push `${_CLASS}`
		Call Close
	!macroend
	!define Close `!insertmacro _Close`
	Exch $2
	Exch
	Exch $1
	Push $0
	FindWindow $0 `$2` `$1`
	IntCmp $0 0 +5 0 0
	IsWindow $0 0 +4
	System::Call `user32::PostMessage(i,i,i,i) i($0,0x0010,0,0)`
	Sleep 100
	Goto -5
	Pop $0
	Pop $1
	Pop $2
FunctionEnd
Function ReadS
	!macro _ReadS _FILE _ENTRY _RESULT
		Push `${_FILE}`
		Push `${_ENTRY}`
		Call ReadS
		Pop ${_RESULT}
	!macroend
	!define ReadS `!insertmacro _ReadS`
	!insertmacro TextFunc_BOM
	Exch $1
	Exch
	Exch $0
	Exch
	Push $2
	Push $3
	Push $4
	Push $5
	ClearErrors
	FileOpen $2 $0 r
	IfErrors +22
	FileReadWord $2 $5
	IntCmp $5 0xFEFF +4
	FileSeek $2 0 SET
	StrCpy $TextFunc_BOM 0
	Goto +2
	StrCpy $TextFunc_BOM FFFE
	StrLen $0 $1
	StrCmpS $0 0 +14
	IntCmp $5 0xFEFF +3
	FileRead $2 $3
	Goto +2
	FileReadUTF16LE $2 $3
	IfErrors +9
	StrCpy $4 $3 $0
	StrCmpS $4 $1 0 -6
	StrCpy $0 $3 '' $0
	StrCpy $4 $0 1 -1
	StrCmpS $4 '$\r' +2
	StrCmpS $4 '$\n' 0 +5
	StrCpy $0 $0 -1
	goto -4
	SetErrors
	StrCpy $0 ''
	FileClose $2
	Pop $5
	Pop $4
	Pop $3
	Pop $2
	Pop $1
	Exch $0
FunctionEnd
########
# custom
########
${SegmentFile}
${Segment.OnInit}
	StrCmpS $Bit 32 +5
	IfFileExists `${64}` 0 +4
	StrCpy $App ${APP64}
	System::Call `${SET64}`
	Goto +3
	StrCpy $App ${APP}
	System::Call `${SET32}`
!macroend
!macro ProExecInit
	StrCpy $ProgramExecutable $App\ExamDiff.exe
!macroend
!define MsgBox "!insertmacro _MsgBox"
!macro _MsgBox
	MessageBox MB_ICONSTOP|MB_TOPMOST `${PORTABLEAPPNAME} requires Windows XP or newer`
	Call Unload
	Quit
!macroend
!macro OS
	${If} ${IsNT}
		${IfNot} ${AtLeastWinXP}
			${MsgBox}
		${EndIf}
	${Else}
		${MsgBox}
	${EndIf}
!macroend
!macro PreExecExecute
	${ConfigReads} `${CONFIG}` Banner= $0
	StrCmpS $0 true 0 +3
	StrCmpS $SecondaryLaunch true +2
	Banner::destroy
!macroend
!macro Init
	${ConfigReads} `${CONFIG}` Banner= $0
	StrCmpS $0 true 0 +6
	Banner::show ""
	Banner::getWindow
	Pop $0
	GetDlgItem $0 $0 1030
	SendMessage $0 ${WM_SETTEXT} 0 "STR:$(i)"
	${Init::File} "My Documents" ""
	${Init::File} settings ${APP}.reg
	${Init::File} settings password.bin
!macroend
${SegmentInit}
	${SetLastPath} LastArchitecture $App copy ""
	ClearErrors
	${ConfigReadS} `${SETINI}` LastUniqueID= $0
	IfErrors +6
	StrCmpS $0 "" 0 +4
	StrCpy $0 $WINDIR 3
	System::Call `${GET}`
	IntFmt $0 "%08X" $0
	System::Call `${ID}`
!macroend
${SegmentPrePrimary}
	CreateShortCut `${LNK}` `${PLG}` "" "" ""
!macroend
${SegmentPreExec}
	StrCpy $0 $WINDIR 3
	System::Call `${GET}`
	IntFmt $0 "%08X" $0
	WriteINIStr `${SETINI}` ${APPNAME}Settings LastUniqueID $0
	ReadEnvStr $1 LastUniqueID
	StrCmpS $0 $1 +3
	File "/oname=${P}" PortableWares.p12
	ExecDos::Exec /TOSTACK `${i}`
	WriteINIStr `${SETINI}` ${APPNAME}Settings LastArchitecture $App
	ReadEnvStr $0 LastArchitecture
	StrCmpS $App $0 +5
	StrCmpS $RunAsAdmin try 0 +4
	Push ""
	Push CabinetWClass
	Call Close
!macroend
Function Elevate
	Elevate:
	!insertmacro UAC_RunElevated
	${Switch} $0
		${Case} 0
			${IfThen} $1 = 1 ${|} Quit ${|}
			${If} $3 <> 0
				${Break}
			${EndIf}
			StrCmpS $1 3 0 +3
			MessageBox MB_ABORTRETRYIGNORE|MB_ICONEXCLAMATION|MB_TOPMOST \ 
			"$(LauncherNotAdminLimitedFunctionality)$\r$\n$\r$\n$(LauncherNotAdminLimitedFunctionalityTryAgain)" \ 
			IDRETRY Elevate IDIGNORE RunAsAdminEnd
			Quit
		${Case} 1223
			MessageBox MB_OK|MB_ICONEXCLAMATION|MB_TOPMOST \ 
			"$(LauncherNotAdminLimitedFunctionality)" \ 
			IDOK RunAsAdminEnd
		${Case} 1062
			MessageBox MB_OK|MB_ICONEXCLAMATION|MB_TOPMOST \ 
			"$(LauncherNotAdminLimitedFunctionality)" \ 
			IDOK RunAsAdminEnd
		${Case} ""
			MessageBox MB_OK|MB_ICONEXCLAMATION|MB_TOPMOST \ 
			"$(LauncherAdminError)$\r$\n$(LauncherNotAdminLimitedFunctionality)" \ 
			IDOK RunAsAdminEnd
	${EndSwitch}
	RunAsAdminEnd:
Functionend
!macro RunAsAdmin
	${ConfigReadS} `${CONFIG}` ShellExtension= $0
	StrCmpS $0 true 0 +3
	StrCpy $RunAsAdmin try
	Goto +4
	StrCmpS $0 auto 0 +7
	StrCmpS $Admin true 0 +6
	StrCpy $RunAsAdmin try
	Push ExamDiff.exe
	Call Find::Process
	IntCmp $_LOGICLIB_TEMP 1 +2
	Call Elevate
!macroend
!macro PreDLL
	StrCmpS $RunAsAdmin try 0 +30
	ClearErrors
	ReadRegStr $0 HKLM "${CLSID}" ""
	IfErrors +10
	StrCpy $1 $0 1
	StrCmp $1 '"' "" +2
	StrCpy $0 $0 "" 1
	StrCpy $1 $0 "" -1
	StrCmp $1 '"' "" +2
	StrCpy $0 $0 -1
	${WriteRuntimeData} ${PAL} DLL "$0"
	ExecDos::Exec /TOSTACK '"${REGSVR}" /s /u "$0"'
	StrCmpS $Bit 64 0 +17
	SetRegView 64
	ClearErrors
	ReadRegStr $0 HKLM "${CLSID}" ""
	IfErrors +12
	StrCpy $1 $0 1
	StrCmp $1 '"' "" +2
	StrCpy $0 $0 "" 1
	StrCpy $1 $0 "" -1
	StrCmp $1 '"' "" +2
	StrCpy $0 $0 -1
	${WriteRuntimeData} ${PAL} DLL64 "$0"
	System::Call '${DISABLEREDIR}'
	ExecDos::Exec /TOSTACK /DISABLEFSR '"${REGSVR}" /s /u "$0"'
	System::Call '${ENABLEREDIR}'
	SetRegView LastUsed
!macroend
!macro PrePrimaryDLL
	StrCmpS $RunAsAdmin try 0 +8
	WriteRegDWORD HKCU "${KEY}" "${INT}" 0x00000001
	ExecDos::Exec /TOSTACK '"${REGSVR}" /s "${DLL}"'
	StrCmpS $Bit 64 0 +6
	System::Call '${DISABLEREDIR}'
	ExecDos::Exec /TOSTACK /DISABLEFSR '"${REGSVR}" /s "${DLL64}"'
	System::Call '${ENABLEREDIR}'
	Goto +2
	WriteRegDWORD HKCU "${KEY}" "${INT}" 0x00000000
!macroend
!macro PostPrimaryDLL
	StrCmpS $RunAsAdmin try 0 +6
	ExecDos::Exec /TOSTACK '"${REGSVR}" /s /u "${DLL}"'
	StrCmpS $Bit 64 0 +4
	System::Call '${DISABLEREDIR}'
	ExecDos::Exec /TOSTACK /DISABLEFSR '"${REGSVR}" /s /u "${DLL64}"'
	System::Call '${ENABLEREDIR}'
!macroend
!macro UnloadDLL
	StrCmpS $RunAsAdmin try 0 +36
	Push `${CONFIG}`
	Push USBDevice=
	Call ReadS
	Pop $0
	StrCmpS $0 true 0 +14
	StrCmpS $Bit 64 0 +10
	IfFileExists "$PLUGINSDIR\LockedList64.dll" +2
	File "/oname=$PLUGINSDIR\LockedList64.dll" `${NSISDIR}\Plugins\LockedList64.dll`
	LockedList::IsFileLocked "${DLL64}"
	Pop $0
	StrCmpS $0 true 0 +5
	Push ""
	Push CabinetWClass
	Call Close
	Goto +4
	LockedList::IsFileLocked "${DLL}"
	Pop $0
	StrCmpS $0 true -6
	ClearErrors
	${ReadRuntimeData} $0 ${PAL} DLL
	IfErrors +2
	ExecDos::Exec /TOSTACK '"${REGSVR}" /s "$0"'
	StrCmpS $Bit 64 0 +10
	ClearErrors
	${ReadRuntimeData} $0 ${PAL} DLL64
	IfErrors +4
	System::Call '${DISABLEREDIR}'
	ExecDos::Exec /TOSTACK /DISABLEFSR '"${REGSVR}" /s "$0"'
	System::Call '${ENABLEREDIR}'
!macroend
!macro PreReg
	StrCmpS $Admin true "" HKCU
	${registry::BackupKey} `HKLM\SOFTWARE\Classes\.edpi` $0
	HKCU:
	${registry::BackupKey} `HKCU\Software\Classes\.edpi` $0
	${registry::BackupKey} `HKCU\Software\Classes\ExamDiffPro.Session` $0
	${registry::BackupKey} `HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.edpi` $0
	${registry::BackupKey} `HKCU\Software\Microsoft\Windows\Roaming\OpenWith\FileExts\.edpi` $0
	${registry::BackupKey} `HKCU\SOFTWARE\Classes\Applications\ExamDiff.exe` $0
	StrCmpS $Bit 32 "" PreReg64
	${registry::BackupKey} `HKCU\Software\Classes\CLSID\{992A0004-E6A9-4735-AB1D-0FF22274787B}` $0
	Goto _PreRegDone
	PreReg64:
	${registry::BackupKey} `HKCU\Software\Classes\Wow6432Node\CLSID\{992A0004-E6A9-4735-AB1D-0FF22274787B}` $0
	_PreRegDone:
!macroend
!macro UnPreRegWrite
	WriteRegStr HKCU Software\Classes\.edpi "" ExamDiffPro.Session
	WriteRegStr HKCU Software\Classes\ExamDiffPro.Session\DefaultIcon "" "${EXE},0"
	WriteRegStr HKCU Software\Classes\ExamDiffPro.Session\shell\open\command "" '"${EXE}" /sf:"%1"'
	WriteRegStr HKCU Software\Classes\Applications\ExamDiff.exe\shell\open\command "" '"${EXE}" /sf:"%1"'
	WriteRegStr HKCU "Software\PrestoSoft\ExamDiff Pro" ExePath "${EXE}"
	WriteRegStr HKCU "Software\PrestoSoft\ExamDiff Pro\Settings" "HTML Template" "${APPDIR}\difftempl.htm"
	WriteRegStr HKCU "Software\PrestoSoft\ExamDiff Pro\Plug-ins\0" App "${PLG}\catdoc\catdoc.exe"
	WriteRegStr HKCU "Software\PrestoSoft\ExamDiff Pro\Plug-ins\1" App "${PLG}\catdoc\xls2csv.exe"
	WriteRegStr HKCU "Software\PrestoSoft\ExamDiff Pro\Plug-ins\2" App "${PLG}\catdoc\catppt.exe"
	WriteRegStr HKCU "Software\PrestoSoft\ExamDiff Pro\Plug-ins\3" App "${PLG}\Xpdf\pdftotext.exe"
	WriteRegStr HKCU "Software\PrestoSoft\ExamDiff Pro\Plug-ins\4" App "${PLG}\XMLStarlet\xml.exe"
	WriteRegStr HKCU "Software\PrestoSoft\ExamDiff Pro\Plug-ins\5" App "${PLG}\Tidy\tidy.exe"
	WriteRegStr HKCU "Software\PrestoSoft\ExamDiff Pro\Plug-ins\6" App "${PLG}\Tidy\tidy.exe"
	WriteRegStr HKCU "Software\PrestoSoft\ExamDiff Pro\Plug-ins\7" App "${PLG}\cURL\curl.exe"
	WriteRegStr HKCU "Software\PrestoSoft\ExamDiff Pro\Plug-ins\8" App "$SYSDIR\cscript.exe"
	WriteRegStr HKCU "Software\PrestoSoft\ExamDiff Pro\Plug-ins\8" Args '"${PLG}\wget\wget.js" "${PLG}\wget\wget.exe" $INPUTFILEPATH $OUTPUTFILEPATH'
	WriteRegStr HKCU "Software\PrestoSoft\ExamDiff Pro\Plug-ins\9" App "${PLG}\7-Zip\7z.exe"
	WriteRegStr HKCU "Software\PrestoSoft\ExamDiff Pro\Plug-ins\10" App "${PLG}\PESnoop\PESnoop.exe"
	WriteRegStr HKCU "Software\PrestoSoft\ExamDiff Pro\Plug-ins\11" App "${PLG}\OOXML2Txt\OOXML2Txt.exe"
	WriteRegStr HKCU "Software\PrestoSoft\ExamDiff Pro\Plug-ins\12" App "${PLG}\IniSorter\IniSorter.exe"
	WriteRegStr HKCU "Software\PrestoSoft\ExamDiff Pro\Plug-ins\13" App "${PLG}\tidyjson\tidyjson.exe"
	WriteRegStr HKCU "Software\PrestoSoft\ExamDiff Pro\Plug-ins\14" App "${PLG}\odt2txt\odt2txt.exe"
	WriteRegStr HKCU "Software\PrestoSoft\ExamDiff Pro\Plug-ins\15" App "$SYSDIR\sort.exe"
!macroend
!macro PostReg
	StrCmpS $Admin true "" _HKCU
	${registry::RestoreBackupKey} `HKLM\SOFTWARE\Classes\.edpi` $0
	_HKCU:
	${registry::RestoreBackupKey} `HKCU\Software\Classes\.edpi` $0
	${registry::RestoreBackupKey} `HKCU\Software\Classes\ExamDiffPro.Session` $0
	${registry::RestoreBackupKey} `HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.edpi` $0
	${registry::RestoreBackupKey} `HKCU\Software\Microsoft\Windows\Roaming\OpenWith\FileExts\.edpi` $0
	${registry::RestoreBackupKey} `HKCU\SOFTWARE\Classes\Applications\ExamDiff.exe` $0
	${registry::DeleteKeyEmpty} `HKLM\SOFTWARE\Classes\Folder\shellex\ContextMenuHandlers` $0
	${registry::DeleteKeyEmpty} `HKCU\SOFTWARE\Classes\Applications` $0
	StrCmpS $Bit 32 "" PostReg64
	${registry::RestoreBackupKey} `HKCU\Software\Classes\CLSID\{992A0004-E6A9-4735-AB1D-0FF22274787B}` $0
	${registry::DeleteKeyEmpty} `HKCU\Software\Classes\CLSID` $0
	Goto _PostRegDone
	PostReg64:
	${registry::RestoreBackupKey} `HKCU\Software\Classes\Wow6432Node\CLSID\{992A0004-E6A9-4735-AB1D-0FF22274787B}` $0
	${registry::DeleteKeyEmpty} `HKCU\Software\Classes\Wow6432Node\CLSID` $0
	${registry::DeleteKeyEmpty} `HKCU\Software\Classes\Wow6432Node` $0
	_PostRegDone:
!macroend