; Script generated by the HM NIS Edit Script Wizard.

################################################################################################################################################
## NOTE FOR ADDING NEW PLATFORMS TO THIS SCRIPT, Search ON [ ## ADDINGPLATFORM ## ]
## These will be sequentially incremented NOTES.  If you F3 through the script, handling each step as you go, you will not miss anything.
################################################################################################################################################


; HM NIS Edit Wizard helper defines
!define PRODUCT_NAME "Message Sniffer Server Installer"
## ADDINGPLATFORM ## STEP 0 :: INCREMENT BUILD NUMBER If Desired.
!define PRODUCT_VERSION "v3.3 - SNFv-E3.0.11"
!define PRODUCT_PUBLISHER "Arm Research"

SetCompressor lzma
!include "WinMessages.nsh" ; needed for Word searching of the Plugins.dat file.
!include "WordFunc.nsh"    ; needed for Word searching of the Plugins.dat file.

# already included !insertmacro GetParent    ; replace the moveup directory function.....
!include "Sections.nsh"
!include "FileFunc.nsh" ; needed for the ${GetParent} directory calls
!include "nsDialogs.nsh"  ; needed to dynamically handle custom page creation
!include "LogicLib.nsh" ; needed for if than do while.

#!insertmacro GetTime       ; compiler macro... needed to call before use
!insertmacro WordFind      ; compiler macro... needed to call before use



#############################################################################
## These variables hold the list of platforms for which we MAY install SNF.
## There may be one, more or many.

## ADDINGPLATFORM ## STEP 1 :: Add the isXYZINSTALLED variable.  This is a boolean flag to track a platform.
VAR /GLOBAL isIceWarpInstalled
VAR /GLOBAL isMailSiteInstalled
VAR /GLOBAL isKerioInstalled
VAR /GLOBAL isImailInstalled
VAR /GLOBAL isSmarterMailInstalled
VAR /GLOBAL isAlligateInstalled
VAR /GLOBAL isDecludeInstalled
VAR /GLOBAL isMXGuardInstalled
VAR /GLOBAL isMINIMIInstalled
VAR /GLOBAL isSNF4AlligateInstalled
Var /GLOBAL isMDaemonInstalled

## ADDINGPLATFORM ## STEP 2 :: If it is a shim module, then you need to add this conditional in order to support reinstall-new-vs-just-use option for the shim.
VAR /GLOBAL Set_For_MINIMI_INSTALL ; may or may not be set, depending of if the user wants to re-install MINIMI
VAR /GLOBAL Set_For_SNF4Alligate_INSTALL ; may or may not be set, depending of if the user wants to re-install MINIMI

VAR /GLOBAL SelectedCaseIndexForPlatformScreen ; This is the var for controlling the case display on the platform screen.  Indxed top to bottom.
## Now define the variables to hold the locations of WHERE we install SNF
## in the event we select any of these options.

## ADDINGPLATFORM ## STEP 3 :: Add the variable that will hold the foldername for the given platform.
VAR /GLOBAL IceWarpInstallFolder
VAR /GLOBAL MailSiteInstallFolder
VAR /GLOBAL KerioInstallFolder
VAR /GLOBAL ImailInstallFolder
VAR /GLOBAL SmarterMailInstallFolder
VAR /GLOBAL AlligateInstallFolder
VAR /GLOBAL DecludeInstallFolder
VAR /GLOBAL MXGuardInstallFolder
VAR /GLOBAL MINIMIInstallFolder
VAR /GLOBAL SNF4AlligateInstallFolder
VAR /GLOBAL MDaemonInstallFolder
##
##
##################################################################################

## Tests for file / directory finding
Var /GLOBAL SNF_SearchFor_Location_Button
Var /GLOBAL SNF_SearchFor_Location          ; This is the variable that holds what platform folder we're looking for initially. ( Install Platform Screen )
Var /GLOBAL SNF_SearchFor_Location_ButtonB
Var /GLOBAL SNF_SearchFor_LocationB

VAR /GLOBAL SNFServerInstallDir ; Path to the  InstallDirectory.
VAR /GLOBAL MessageSnifferRestoreDir ; Path to the ArchivedRestore Dir. Or blank for fresh install.
; VAR /GLOBAL PreExistingMessageSnifferInstallDirectory ; Path to MessageSniffer root directory
VAR /GLOBAL PreviousSnifferInstalled ; Flag to indicate if there was a previous sniffer install.
VAR /GLOBAL ArchivesAvailable ; Flag to indicate, if there isn't a sniffer version installed but there ARE archives... then we have another option set.
VAR /GLOBAL OldVersionOfSniffer  ; Flag to indicate that we need to deal with the /sniffer pathname.
VAR /GLOBAL ShowTelemetryPage    ; Flag to indicate that we need to show the status page.
VAR /GLOBAL ShowRestoreOptionsPage ; The flag to determine if the user wanted to install/restore and so to show the
                                   ; options page for that.
VAR /GLOBAL ShowArchiveOptionsPage ; Ok, this  will be the flag to display the archive screen.
VAR /GLOBAL HandleUninstallPage    ; Ok, we don't want to flash to another page when we pick uninstall.  ( It was jumping to the Master Utilities,
                                   ; installation screen before it called the section code... and it was looking strange from the user's persepctive
                                   ; like there was unintended page flicker.
VAR /GLOBAL CustomFolderName       ; User input variable to name the archive folder.
VAR /GLOBAL LicenseID
VAR /GLOBAL Authentication

VAR /GLOBAL BaseRadioDefault       ; this is the Int id of the section that will be the minimal permitted default on either the Platforms or the Utilities screen.
VAR /GLOBAL currentPlatformSelection       ; this is the Int id of the section that is the current select option for the Platforms or the Utilities screen.
VAR /GLOBAL currentUtilitySelection       

# These vars are used by the page that looks for missing folders.
Var /GLOBAL FindApplicationMessage ; This is used to abstract the search page.
Var /GLOBAL MissingApplicationName ; This is used to identify the abstracted application name.
Var /GLOBAL MissingApplicationFolder ; This is used to identify the abstracted application folder to start the search from
Var /GLOBAL Find_Explanation_INFO  ; if you want a verbose instruction put it here.

# For holding the shortened version of paths.
Var /GLOBAL localINSTDIR ; for use with shortente PROGR~1 path anmes.
Var /GLOBAL localSERVDIR

PageEx components
ComponentText "Welcome to the Message Sniffer Platforms Screen. $\nPlease select the platform you will use with Message Sniffer." "  " "Please select from these available platforms:"
PageCallbacks   "setupPlatforms" "" "" ; the setupPlatforms displays the lines based on DetermineInstallationPlatforms
PageExEnd                                       

# Prior to this call, you would have to set the parameters to indicate that you were looking for something, and what that was... otherwise
# This page will just skip.  If the user selects default install, it will put it in a default folder but let the user select another if they choose.
Page custom  "FindApplicationPath" "setupINSTALLDIR" "Confirm Install Location:"
                                                  ; setupINSTALLDIR sets the $INSTALLDIR and the archives folder flags if applicable for whatever
                                                  ; installation is relevant.... ( This has complicated MessageSnifferRegistry entries...)



PageEx components
ComponentText "Welcome to the Message Sniffer Server Install Utility.  Please select from the available activities."  "  " "Please select from the available activities:"
PageCallbacks "setupComponents2"  "" "Components2_Leave"
PageExEnd


Page custom "nsDialogsTelemetryShow" "nsDialogsTelemetryLeave" "Status Viewer"

;Page custom nsDialogsSelectRestoreDir nsDialogsSelectRestoreDir_leave   "Restore Or Archive"
;Page custom nsDialogsSelectRestoreDir nsDialogsSelectRestoreDir_leave   "Restore Or Archive"
;Page custom nsDialogsInstallRestoreDir nsDialogsInstallRestoreDir_leave "Install"
;Page custom nsDialogHandleArchive nsDialogArchive_leave "Archive"
Page custom nsDialogHandleUninstall "" "Uninstall"

Page instfiles nsDialogInstall "" ""

Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"

## ADDINGPLATFORM ## STEP 4 :: INCREMENT BUILD NAME IF DESIRED
OutFile "SNF_CS_Installer.exe"

ShowInstDetails show

AddBrandingImage left 140

!insertmacro GetParent

!macro BIMAGE IMAGE PARMS
	Push $0
	GetTempFileName $0
	File /oname=$0 "${IMAGE}"
	SetBrandingImage ${PARMS} $0
	Delete $0
	Pop $0
!macroend

###############################################################################
##
##  Open source functional additions from NSIS website.  Provided by users.
##
##
###############################################################################

; BEGIN REPLACEINFILE SUBTOUTINES

; StrReplace
; Replaces all ocurrences of a given needle within a haystack with another string
; Written by dandaman32

Var STR_REPLACE_VAR_0
Var STR_REPLACE_VAR_1
Var STR_REPLACE_VAR_2
Var STR_REPLACE_VAR_3
Var STR_REPLACE_VAR_4
Var STR_REPLACE_VAR_5
Var STR_REPLACE_VAR_6
Var STR_REPLACE_VAR_7
Var STR_REPLACE_VAR_8

Function StrReplace
  Exch $STR_REPLACE_VAR_2
  Exch 1
  Exch $STR_REPLACE_VAR_1
  Exch 2
  Exch $STR_REPLACE_VAR_0
    StrCpy $STR_REPLACE_VAR_3 -1
    StrLen $STR_REPLACE_VAR_4 $STR_REPLACE_VAR_1
    StrLen $STR_REPLACE_VAR_6 $STR_REPLACE_VAR_0
    loop:
      IntOp $STR_REPLACE_VAR_3 $STR_REPLACE_VAR_3 + 1
      StrCpy $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_4 $STR_REPLACE_VAR_3
      StrCmp $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_1 found
      StrCmp $STR_REPLACE_VAR_3 $STR_REPLACE_VAR_6 done
      Goto loop
    found:
      StrCpy $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_3
      IntOp $STR_REPLACE_VAR_8 $STR_REPLACE_VAR_3 + $STR_REPLACE_VAR_4
      StrCpy $STR_REPLACE_VAR_7 $STR_REPLACE_VAR_0 "" $STR_REPLACE_VAR_8
      StrCpy $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_5$STR_REPLACE_VAR_2$STR_REPLACE_VAR_7
      StrLen $STR_REPLACE_VAR_6 $STR_REPLACE_VAR_0
      Goto loop
    done:
  Pop $STR_REPLACE_VAR_1 ; Prevent "invalid opcode" errors and keep the
  Pop $STR_REPLACE_VAR_1 ; stack as it was before the function was called
  Exch $STR_REPLACE_VAR_0
FunctionEnd

Function un.StrReplace
  Exch $STR_REPLACE_VAR_2
  Exch 1
  Exch $STR_REPLACE_VAR_1
  Exch 2
  Exch $STR_REPLACE_VAR_0
    StrCpy $STR_REPLACE_VAR_3 -1
    StrLen $STR_REPLACE_VAR_4 $STR_REPLACE_VAR_1
    StrLen $STR_REPLACE_VAR_6 $STR_REPLACE_VAR_0
    loop:
      IntOp $STR_REPLACE_VAR_3 $STR_REPLACE_VAR_3 + 1
      StrCpy $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_4 $STR_REPLACE_VAR_3
      StrCmp $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_1 found
      StrCmp $STR_REPLACE_VAR_3 $STR_REPLACE_VAR_6 done
      Goto loop
    found:
      StrCpy $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_3
      IntOp $STR_REPLACE_VAR_8 $STR_REPLACE_VAR_3 + $STR_REPLACE_VAR_4
      StrCpy $STR_REPLACE_VAR_7 $STR_REPLACE_VAR_0 "" $STR_REPLACE_VAR_8
      StrCpy $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_5$STR_REPLACE_VAR_2$STR_REPLACE_VAR_7
      StrLen $STR_REPLACE_VAR_6 $STR_REPLACE_VAR_0
      Goto loop
    done:
  Pop $STR_REPLACE_VAR_1 ; Prevent "invalid opcode" errors and keep the
  Pop $STR_REPLACE_VAR_1 ; stack as it was before the function was called
  Exch $STR_REPLACE_VAR_0
FunctionEnd

!macro _strReplaceConstructor OUT NEEDLE NEEDLE2 HAYSTACK
  Push "${HAYSTACK}"
  Push "${NEEDLE}"
  Push "${NEEDLE2}"
  Call StrReplace
  Pop "${OUT}"
!macroend

!macro un._strReplaceConstructor OUT NEEDLE NEEDLE2 HAYSTACK
  Push "${HAYSTACK}"
  Push "${NEEDLE}"
  Push "${NEEDLE2}"
  Call un.StrReplace
  Pop "${OUT}"
!macroend

!define StrReplace '!insertmacro "_strReplaceConstructor"'
!define un.StrReplace '!insertmacro "un._strReplaceConstructor"'

!macro ReplaceInFile SOURCE_FILE SEARCH_TEXT REPLACEMENT
  Push "${SOURCE_FILE}"
  Push "${SEARCH_TEXT}"
  Push "${REPLACEMENT}"
  Call RIF
!macroend

!macro un.ReplaceInFile SOURCE_FILE SEARCH_TEXT REPLACEMENT
  Push "${SOURCE_FILE}"
  Push "${SEARCH_TEXT}"
  Push "${REPLACEMENT}"
  Call un.RIF
!macroend

Function RIF

  ClearErrors  ; want to be a newborn

  Exch $0      ; REPLACEMENT
  Exch
  Exch $1      ; SEARCH_TEXT
  Exch 2
  Exch $2      ; SOURCE_FILE

  Push $R0     ; SOURCE_FILE file handle
  Push $R1     ; temporary file handle
  Push $R2     ; unique temporary file name
  Push $R3     ; a line to sar/save
  Push $R4     ; shift puffer

  IfFileExists $2 +1 RIF_error      ; knock-knock
  FileOpen $R0 $2 "r"               ; open the door

  GetTempFileName $R2               ; who's new?
  FileOpen $R1 $R2 "w"              ; the escape, please!

  RIF_loop:                         ; round'n'round we go
    FileRead $R0 $R3                ; read one line
    IfErrors RIF_leaveloop          ; enough is enough
    RIF_sar:                        ; sar - search and replace
      Push "$R3"                    ; (hair)stack
      Push "$1"                     ; needle
      Push "$0"                     ; blood
      Call StrReplace               ; do the bartwalk
      StrCpy $R4 "$R3"              ; remember previous state
      Pop $R3                       ; gimme s.th. back in return!
      StrCmp "$R3" "$R4" +1 RIF_sar ; loop, might change again!
    FileWrite $R1 "$R3"             ; save the newbie
  Goto RIF_loop                     ; gimme more

  RIF_leaveloop:                    ; over'n'out, Sir!
    FileClose $R1                   ; S'rry, Ma'am - clos'n now
    FileClose $R0                   ; me 2
    ;MessageBox MB_OK "Files Closed. $R1 , $R0"
    Delete "$2.old"                 ; go away, Sire
    ;MessageBox MB_OK "Deleete $2.old"
    Rename "$2" "$2.old"            ; step aside, Ma'am
    ;MessageBox MB_OK "Rename $2 to $2.old"
    Rename "$R2" "$2"               ; hi, baby!
    ;MessageBox MB_OK "Rename $R2 to $2"
    Delete "$2.old"
    ClearErrors                     ; now i AM a newborn
    Goto RIF_out                    ; out'n'away

  RIF_error:                        ; ups - s.th. went wrong...
    SetErrors                       ; ...so cry, boy!

  RIF_out:                          ; your wardrobe?
  Pop $R4
  Pop $R3
  Pop $R2
  Pop $R1
  Pop $R0
  Pop $2
  Pop $0
  Pop $1

FunctionEnd

Function un.RIF

  ClearErrors  ; want to be a newborn

  Exch $0      ; REPLACEMENT
  Exch
  Exch $1      ; SEARCH_TEXT
  Exch 2
  Exch $2      ; SOURCE_FILE

  Push $R0     ; SOURCE_FILE file handle
  Push $R1     ; temporary file handle
  Push $R2     ; unique temporary file name
  Push $R3     ; a line to sar/save
  Push $R4     ; shift puffer

  IfFileExists $2 +1 RIF_error      ; knock-knock
  FileOpen $R0 $2 "r"               ; open the door

  GetTempFileName $R2               ; who's new?
  FileOpen $R1 $R2 "w"              ; the escape, please!

  RIF_loop:                         ; round'n'round we go
    FileRead $R0 $R3                ; read one line
    IfErrors RIF_leaveloop          ; enough is enough
    RIF_sar:                        ; sar - search and replace
      Push "$R3"                    ; (hair)stack
      Push "$1"                     ; needle
      Push "$0"                     ; blood
      Call un.StrReplace               ; do the bartwalk
      StrCpy $R4 "$R3"              ; remember previous state
      Pop $R3                       ; gimme s.th. back in return!
      StrCmp "$R3" "$R4" +1 RIF_sar ; loop, might change again!
    FileWrite $R1 "$R3"             ; save the newbie
  Goto RIF_loop                     ; gimme more

  RIF_leaveloop:                    ; over'n'out, Sir!
    FileClose $R1                   ; S'rry, Ma'am - clos'n now
    FileClose $R0                   ; me 2
    ;MessageBox MB_OK "Files Closed. $R1 , $R0"
    Delete "$2.old"                 ; go away, Sire
    ;MessageBox MB_OK "Deleete $2.old"
    Rename "$2" "$2.old"            ; step aside, Ma'am
    ;MessageBox MB_OK "Rename $2 to $2.old"
    Rename "$R2" "$2"               ; hi, baby!
    ;MessageBox MB_OK "Rename $R2 to $2"
    Delete "$2.old"
    ClearErrors                     ; now i AM a newborn
    Goto RIF_out                    ; out'n'away

  RIF_error:                        ; ups - s.th. went wrong...
    SetErrors                       ; ...so cry, boy!

  RIF_out:                          ; your wardrobe?
  Pop $R4
  Pop $R3
  Pop $R2
  Pop $R1
  Pop $R0
  Pop $2
  Pop $0
  Pop $1

FunctionEnd

; END REPLACE IN FILE SUBROUTINES

; The following code is for finding strings inbetween two markers... reguardless of linefeeds.

!macro GetBetween This AndThis In Return
Push "${This}"
Push "${AndThis}"
Push "${In}"
 Call GetBetween
Pop "${Return}"
!macroend
!define GetBetween "!insertmacro GetBetween"

Function GetBetween
 Exch $R0 ; file    ; $R0_Old + AndThis + This + Stack
 Exch               ;  AndThis + $R0_Old + This + Stack
 Exch $R1 ; before this (marker 2)  ;  $R1_Old + $R0_Old + This + Stack
 Exch 2             ;  This + $R0_Old + $R1_Old + Stack
 Exch $R2 ; after this  (marker 1) $R2_Old + $R0_OLD + $R1_Old + Stack
 Exch 2             ; $R1_Old + $R0_OLD + $R2_Old + Stack
 Exch               ; $R0_Old + $R1_OLD + $R2_Old + Stack
 Exch 2             ; $R2_Old + $R1_OLD + $R0_Old + Stack
 Push $R3 ; marker 1 len R3,R2,R1,R0,Stack
 Push $R4 ; marker 2 len R4,R3,R2,R1,R0,Stack
 Push $R5 ; marker pos   R5,R4,R3,R2,R1,R0,Stack
 Push $R6 ; file handle  R6,R5,R4,R3,R2,R1,R0,Stack
 Push $R7 ; current line string R7,R6,R5,R4,R3,R2,R1,R0,Stack
 Push $R8 ; current chop R8,R7,R6,R5,R4,R3,R2,R1,R0,Stack


 FileOpen $R6 $R0 r

 StrLen $R4 $R2
 StrLen $R3 $R1

 StrCpy $R0 ""

 Read1:
  ClearErrors
  FileRead $R6 $R7
  IfErrors Done
  StrCpy $R5 0

 FindMarker1:
  IntOp $R5 $R5 - 1
  StrCpy $R8 $R7 $R4 $R5
  StrCmp $R8 "" Read1
  StrCmp $R8 $R2 0 FindMarker1
   IntOp $R5 $R5 + $R4
   StrCpy $R7 $R7 "" $R5

  StrCpy $R5 -1
  Goto FindMarker2

 Read2:
  ClearErrors
  FileRead $R6 $R7
  IfErrors Done
  StrCpy $R5 -1

 FindMarker2:
  IntOp $R5 $R5 + 1
  StrCpy $R8 $R7 $R3 $R5
  StrCmp $R8 "" 0 +3
   StrCpy $R0 $R0$R7
  Goto Read2
  StrCmp $R8 $R1 0 FindMarker2
   StrCpy $R7 $R7 $R5
   StrCpy $R0 $R0$R7

 Done:
  FileClose $R6

 Pop $R8
 Pop $R7
 Pop $R6
 Pop $R5
 Pop $R4
 Pop $R3
 Pop $R2
 Pop $R1
 Exch $R0
FunctionEnd

; End code for FindBetween functions and macro



;----------------------------------------------------------------------------
; Title             : Go to a NSIS page     
; Short Name        : RelGotoPage
; Last Changed      : 22/Feb/2005
; Code Type         : Function
; Code Sub-Type     : Special Restricted Call, One-way StrCpy Input
;----------------------------------------------------------------------------
; Description       : Makes NSIS to go to a specified page relatively from
;                     the current page. See this below for more information:
;                     "http://nsis.sf.net/wiki/Go to a NSIS page"
;----------------------------------------------------------------------------
; Function Call     : StrCpy $R9 "(number|X)"
;
;                     - If a number &gt; 0: Goes foward that number of
;                       pages. Code of that page will be executed, not
;                       returning to this point. If it excess the number of
;                       pages that are after that page, it simulates a
;                       "Cancel" click.
;
;                     - If a number &lt; 0: Goes back that number of pages.
;                       Code of that page will be executed, not returning to
;                       this point. If it excess the number of pages that
;                       are before that page, it simulates a "Cancel" click.
;
;                     - If X: Simulates a "Cancel" click. Code will go to
;                       callback functions, not returning to this point.
;
;                     - If 0: Continues on the same page. Code will still
;                        be running after the call.
;
;                     Call RelGotoPage
;----------------------------------------------------------------------------
; Author            : Diego Pedroso
; Author Reg. Name  : deguix
;----------------------------------------------------------------------------

Function RelGotoPage
  IntCmp $R9 0 0 Move Move
    StrCmp $R9 "X" 0 Move
      StrCpy $R9 "120"

  Move:
  SendMessage $HWNDPARENT "0x408" "$R9" ""
FunctionEnd






## ADDINGPLATFORM ## STEP 5 :: Add DetermineXYZPlatform Subroutine.
##This is the code that looks/hunts to see if we can predetermine the folder for an expected platform.
## Besure to set the Folder and the IsInstalled varables for any specific DetermineXYZ sub that you add.

Function DetermineMDaemon
  ; Clear flag.

  StrCpy $isMDaemonInstalled "0"
  
   ReadRegStr $MDaemonInstallFolder HKLM "SOFTWARE\Alt-N Technologies\MDaemon" "AppPath"
   StrCmp $MDaemonInstallFolder "" ReportFalse 0
        StrCpy $isMDaemonInstalled "1"
   ; But the App Registry var has the \App\ appended.  We want that removed. soo...
   ${GetParent} $MDaemonInstallFolder $MDaemonInstallFolder ; get the parent of the AppPath and mark it as the master MDaemon dir.
   ; No the plugins.dat file might not exist, but we need to confirm that the folders are there.
   ifFileExists "$MDaemonInstallFolder\App\*.*" 0 ReportFalse
   ifFileExists "$MDaemonInstallFolder\SpamAssassin\rules\*.*" 0 ReportFalse
   
  StrCpy $isMDaemonInstalled "1"
  ReportFalse:
  Return
FunctionEnd


Function DetermineIceWarp
  ; Clear flag.
  StrCpy $isIceWarpInstalled "0"
  ; Icewarp registry files are stored in:
  ReadRegStr $IceWarpInstallFolder HKLM "SOFTWARE\IceWarp\Merak Mail Server" "InstallDir"
   StrCpy $IceWarpInstallFolder $IceWarpInstallFolder -1 ; Take the slash off the last end to conform with the rest of the paradigm.
      StrCmp $IceWarpInstallFolder "" ReportFalse 0
        StrCpy $isIceWarpInstalled "1"
  ; Now if they don't have any Content Filters created yet, there won't be a file.  And we don't want that to be the case,
  ; so if we find the folder, then we'll create the file in anticipation of installing it.
  ifFileExists "$IceWarpInstallFolder\config\*.*" 0 skipFilecreation
    ifFileExists "$IceWarpInstallFolder\config\content.xml" skipFilecreation 0
          Var /GLOBAL tempFileHandle
          FileOpen $tempFileHandle "$IceWarpInstallFolder\config\content.xml" w ; so create an empty file.  It doesn't bother IceWarp, and it will maintain the integrity
          FileClose $tempFileHandle
    skipFileCreation:                                             ; of the file check portion of the directory selection popups.
  ReportFalse:
  Return
FunctionEnd

Function DetermineSNF4Alligate
  ; If there's no Alligate, there can't be SNF4Alligate
  StrCmp $isAlligateInstalled "0" ReportFalse 0

  ; Currently we have a small SMTP rerouting application called SNF4Alligate
  ; we can know this if we check the FilterEXE value
  Var /GLOBAL FilterEXE
  ReadRegStr $FilterEXE HKLM "SOFTWARE\SolidOak\Alligate\Settings" "FilterEXE"
  Var /GLOBAL SNF4AWordCount
    StrCmp $FilterEXE "" ReportFalse 0
    ${WordFind} $FilterEXE "SNF4Alligate" "E*" $SNF4AWordCount ; This will return in #R0 the number of times the delimiter  was found in the testString.
               iferrors ReportFalse 0 ; if errors is true $R0 will be 1... indicating not-found...
                 ${IF} $SNF4AWordCount > "0" ; But witn no errors, 1 means it found 1 instandce.
                     ; then we display the option.
                     ; It found the exe file in the path... good to go.
                       StrCpy $isSNF4AlligateInstalled "1"
                 ${endif}

    ; Now set the magic folder at:
    ReadRegStr $SNF4AlligateInstallFolder HKLM  "SOFTWARE\SolidOak\Alligate\Settings" "InstallDir"
    StrCpy $SNF4AlligateInstallFolder $SNF4AlligateInstallFolder -1 ; Take the slash off the last end to conform with the rest of the paradigm.
  Return
  ReportFalse:
  StrCpy  $isSNF4AlligateInstalled "0"
  StrCpy  $SNF4AlligateInstallFolder ""
FunctionEnd

Function DetermineMINIMI
  ; If there's no imail, there can't be MINIMI
  StrCmp $isIMailInstalled "0" ReportFalse 0

  ; Currently we have a small SMTP rerouting application called MINIMI.
  ; we can know this if we check the send mail
  Var /GLOBAL SendNameValue
  ReadRegStr $SendNameValue HKLM "SOFTWARE\Ipswitch\IMail\Global" "SendName"
  Var /GLOBAL WordCount
    StrCmp $SendNameValue "" ReportFalse 0
    ${WordFind} $SendNameValue "SNFIMailShim.exe" "E*" $WordCount ; This will return in #R0 the number of times the delimiter  was found in teh testString.
               iferrors ReportFalse 0 ; if errors is true $R0 will be 1... indicating not-found...
                 ${IF} $WordCount > "0" ; But witn no errors, 1 means it found 1 instandce.
                     ; then we display the option.
                     ; It found the exe file in the path... good to go.
                       StrCpy $isMINIMIInstalled "1"
                 ${endif}
               ReportFalse:
    ; Now set the magic folder at:
    ReadRegStr $MINIMIInstallFolder HKLM "SOFTWARE\Ipswitch\IMail\Global" "TopDir"

  Return
FunctionEnd




## ADDINGPLATFORM ## STEP 6  Add SetInstallForXYZPlatform suboutine.
## THIS IS ONLY NECESSARY FOR SHIM STYLE INSTALLS SUCH AS MINIMI OR SNF4ALLIGATE
## Test for the existance, reword the popup, and put the proper variables for the boolean flags.

Function SetInstallForSNF4Alligate
    ; Ok , new happening here. Up to this point, the only thing that was different with the installs was where it was being put.
  ; The Install script was the same.... but here we have a branch effect.  Because the setup for the install, isnt' just picking the placement folder.
  ; it now includes the installation of the SNF5Alligate application.  So.... we need to set the flag for installing SNF4Alligate
  ; Presumabely IF SNF4Alligate has already been installed, we don't need to call it....
  Var /GLOBAL WAS_SNF4AlligateInstalledAlready
  ReadRegStr $WAS_SNF4AlligateInstalledAlready HKLM "Software\MessageSniffer" "isSNF4AlligateInstalled"
  iferrors Install_SNF4Alligate ; no key, just go and set the install flag, for after we leave the components page.
  StrCmp $WAS_SNF4AlligateInstalledAlready "1" 0 Install_SNF4Alligate  ; if it is, then drop in and handle the tests.....
    MessageBox MB_OKCANCEL "A previous installation of SNF4Alligate was detected.  Select OK to reinstall or CANCEL to work with the existing version?" IDOK Install_SNF4Alligate IDCANCEL SkipInstall
  Install_SNF4Alligate:
    StrCpy $Set_For_SNF4Alligate_INSTALL "1" # This is set because SetInstallForMINIMI gets called if you check the box, but we only want to call
                                       # the install on the page leave function.
    Return
  SkipInstall:
    StrCpy $Set_For_SNF4Alligate_INSTALL "0"
    Return
FunctionEnd



## ADDINGPLATFORM ## STEP 7 Add installXYZPLATFORM Shim routine.
## THIS IS ONLY NECESSARY FOR SHIM STYLE INSTALLS SUCH AS MINIMI or SNF4ALIGATE.

Function installSNF4Alligate

  ; This function puts SNF4Alligate in the proper location. It depends on an install of Alligate being present.
  ; if Alligate is not present this function exits.
    StrCmp $isAlligateInstalled "0" ReportFalse 0  ; ok, if Alligate is up, then we'll try to unpack SNF4Alligate

  ; It also registers with MessageSniffer the location of the SNF4Alligate Install.
  ; First we must find the FilterEXE key in the Alligate registry folder.
  ## So test to be sure the path is combined properly with Alligate
  Var /GLOBAL LocalKeyhandle
  Var /GLOBAL defaultHoldValue ; dummy var
  Var /GLOBAL defaultDeliveryValue ; dummy var

  nsExec::Exec 'NET STOP "Alligate SMTP Service"' '' SH_HIDE

  ;MessageBox MB_OK "Installing SNF4Alligate"

               ; Ok, SNF4Allgiate goes in Alligate's InstallDir, where it  stores AgFiltSvc.exe
               ; Get InstallDir registry key....
               ReadRegStr $LocalKeyhandle HKLM "SOFTWARE\SolidOak\Alligate\Settings" "InstallDir"
               StrCmp $LocalKeyhandle "" ReportFalse 0 ; ensure no empty string.
               ; Local key handle now holds the top directory where AGFiltSvc.exe should reside.

               ; lop last char '\' off end
               StrCpy $LocalKeyhandle $LocalKeyhandle -1 ; because Alligate postpends a \ on the backside of their paths...
               
               IfFileExists "$LocalKeyhandle\AGFiltSvc.exe" +2 0
                 MessageBox MB_OK "Can't find AGFiltSvc.exe in ImAlligate's root directory: $LocalKeyhandle.  SNF4Alligate's xml config file will need manual file correction and you will need to install and start Alligates AGFiltSvc manually."
                 ; Ok, file exists.... then we'll put MINIMI right here...
                 StrCpy $SNF4AlligateInstallFolder $LocalKeyhandle
                 SetOutPath $SNF4AlligateInstallFolder

                 IfFileExists "$SNF4AlligateInstallFolder\SNF4Alligate.exe" 0 +2 ; if we're doing a re-install we need to be able to put it all back....
                   Rename "$SNF4AlligateInstallFolder\SNF4Alligate.exe" "$SNF4AlligateInstallFolder\OLD_SNF4Alligate.exe" ; leave this to be consumed by the Archiver.
                 File "SNF4Alligate.exe"  ; We can install a new SNF4Alligate.exe file in case updates...

            ;Now create the hold location for SNF4Alligate:
            IfFileExists "$LocalKeyhandle\Hold\*.*" +2 0  ; check to see if exists, if so,skip line, otherwise make dir.
              CreateDirectory "$LocalKeyhandle\Hold"  ; Recreates target folder.  Sniffer and SNF safe...


            IfFileExists "$SNF4AlligateInstallFolder\SNF4Alligate.xml" UseExistingXML 0 ; if doesnt' exist then drop in.... and dump the file.
              ; If this was already installed, then editing it will create issues
              ; because you can't just take the target from Alligate cause SNF5Alligate has set itself to be the target.
              ; but if it doesn't exist then we just drop in here and write out the file.
              File "SNF4Alligate.xml"
              ; SNF4Alligate.xml files are unpacked.
            UseExistingXML:
            
            
          ; Set the processing folder.
          WriteRegStr    HKLM "SOFTWARE\SolidOak\Alligate\Settings" "DropDir" "$SNF4AlligateInstallFolder\Drop"

          ; Set the user help keys for integration with the Alligate Controlpanel.
          WriteRegStr HKLM SOFTWARE\SolidOak\Alligate\Settings\Addins\MsgSniffer\  "ProcessDirHint" "Sniffer" ; this holds the verbage for the Alligate Inteface clue.
          WriteRegStr HKLM SOFTWARE\SolidOak\Alligate\Settings\Addins\MsgSniffer\  "ProcessDir" "$SNF4AlligateInstallFolder\Drop"  ; This flags the directory.
          WriteRegStr HKLM SOFTWARE\SolidOak\Alligate\Settings\Addins\MsgSniffer\  "ProcessDirLabel" "If you are using the Routing table feature to expressly define processing directories then you will need to manually set the folders you want Sniffer to scan, to process messages in the \Drop\ folder." ; This is "Sniffer"

                 ; Now we determine what Alligate was pointing at:
               ReadRegStr $LocalKeyhandle HKLM "SOFTWARE\SolidOak\Alligate\Settings" "FilterEXE"

                 ; if this returns with an error and an empty string, the tag didn't exist. LocalKeyhandle will be "";
               ; WordCount is a dummy var defined in an earlier sub.... just a handler...
               ${WordFind} $LocalKeyhandle "SNF4Alligate.exe" "E*" $WordCount ; This will return in WordCount the number of times the delimiter  was found in teh testString.
               iferrors NoSNFIPRESENT_OK SKIP_INCHAIN_DELIVERY_ALTERAION ; if errors is true this indicates not-found...

                 ; If we have sniffy present then we need to skip all this file setup because the chain is intact.
               NoSNFIPRESENT_OK:
                 StrCmp $LocalKeyhandle "" 0 SkipCreatingFilterExe  ; $R0 equalling empty indicates that there was no target... otherwise notify user.... ( This test is redundant...
                   WriteRegStr    HKLM "SOFTWARE\SolidOak\Alligate\Settings" "FilterEXE" "SNF4Alligate.exe"
                   WriteRegDWORD  HKLM "SOFTWARE\SolidOak\Alligate\Settings" "FilterThreads" "20"
                 SkipCreatingFilterExe:

                 StrCmp $LocalKeyhandle "" +2 0  ; $R0 equalling empty indicates that there was no target... otherwise notify user.... ( This test is redundant...
                   NoSMTP32: MessageBox MB_OK "Alligate is currently delivering its messages to: $LocalKeyHandle $\r$\n  SNF4Alligate will insert itself ahead of that call, and send valid messages to its custom handler upon completion."



                   ; Normal delivery line for SNF4Alligate looks like this: " <delivery program='d:\Alligate\XYZPDQ.exe'/>" or 'none'
                   ${GetBetween} "<delivery program='" "'/>$\r$\n" "$SNF4AlligateInstallFolder\SNF4Alligate.xml" "$defaultDeliveryValue"  ; This makes it not brittly dependant on the default value. i.e. It would
                   
                   ; If empty replace delivery with "none"  otherwise replace with path/file.exe
                   
                   StrCmp $LocalKeyhandle "" 0 ReplaceWithValue
                     !insertmacro ReplaceInFile "$SNF4AlligateInstallFolder\SNF4Alligate.xml" "<delivery program='$defaultDeliveryValue'/>$\r$\n" "<delivery program='none'/>$\r$\n"
                     Goto NextTest
                   ReplaceWithValue:
                     !insertmacro ReplaceInFile "$SNF4AlligateInstallFolder\SNF4Alligate.xml" "<delivery program='$defaultDeliveryValue'/>$\r$\n" "<delivery program='$LocalKeyhandle'/>$\r$\n"
                   NextTest:
                   ClearErrors
## IS this an error?  What if the LocalKeyHandle was Path\SNFClient.exe  the following wouldn't make sense.
                  ${GetBetween} "<hold path='" "'/>" "$SNF4AlligateInstallFolder\SNF4Alligate.xml" "$defaultHoldValue"  ; This makes it not brittly dependant on the default value. i.e. It would
                 StrCmp $defaultHoldValue "$LocalKeyhandle\Hold\" NextTest2 0 ; If there the same, don't replace, otherwise replace.
                   !insertmacro ReplaceInFile "$SNF4AlligateInstallFolder\SNF4Alligate.xml" "<hold path='$defaultHoldValue'/>" "<hold path='$LocalKeyhandle\Hold\'/>"
                 NextTest2:  ClearErrors
                 ; Hold is defined.
                 
                 SKIP_INCHAIN_DELIVERY_ALTERAION:
                 ExecWait "$SNF4AlligateInstallFolder\AGFiltSvc.exe /install"
                 
                 iferrors WeMustUndo 0



            Done:
               SetOutPath $INSTDIR ; return this path to what it normally is.
               WriteRegStr HKLM "Software\MessageSniffer" "isSNF4AlligateInstalled" "1"
               WriteRegStr HKLM "Software\MessageSniffer" "SNF4AlligateInstallFolder" "$SNF4AlligateInstallFolder"
                       ; good to go.
               StrCpy $isSNF4AlligateInstalled "1"
               nsExec::Exec 'NET START AgSMTPSvc' '' SH_HIDE
               nsExec::Exec 'NET START AGFiltSvc' '' SH_HIDE
               return

  ReportFalse: MessageBox MB_OK "Unable to find valid Alligate InstallDir from the registry.  SNF4Alligate Install was aborted."
               nsExec::Exec 'NET START AgSMTPSvc' '' SH_HIDE
               Return

  WeMustUndo:
            MessageBox MB_OKCANCEL "Failed Attempt. Clean Up?$\r$\nDetails:  SNF4Alligate install script was unable to write to the Alligate FilterEXE registry key. ( To instert SNF4Alligate into the message control stream. ) Click OK if you want the installer to remove and restore the intallation attempt?  ( Cancel if you want to leave the two SNF4Aligate files.  i.e. You might want to try to tie in SNF4Alligate through Alligate's Administration screens? )" IDOK cleanupFiles IDCANCEL leaveFiles
            nsExec::Exec 'NET START AgSMTPSvc' '' SH_HIDE
          cleanupFiles:
            ; since we couldn't edit the registry, we don't need to worry abou tit. Now Kill attempt:
            ifFileExists "$SNF4AlligateInstallFolder\SNF4AlligateNEW.xml" 0 +2
              Delete "$SNF4AlligateInstallFolder\SNF4AlligateNEW.xml"
            ifFileExists "$SNF4AlligateInstallFolder\OLD_SNF4Alligate.xml" 0 +2
              Delete "$SNF4AlligateInstallFolder\OLD_SNF4Alligate.xml"
            ifFileExists "$SNF4AlligateInstallFolder\OLD_SNF4Alligate.exe" 0 +2
              Delete "$SNF4AlligateInstallFolder\OLD_SNF4Alligate.exe"
            ifFileExists "$SNF4AlligateInstallFolder\SNF4Aligate.xml" 0 +2
              Delete "$SNF4AlligateInstallFolder\SNF4Alligate.xml"
            ifFileExists "$SNF4AlligateInstallFolder\SNF4Alligate.exe" 0 +2
              Delete "$SNF4AlligateInstallFolder\SNF4Alligate.exe"
          leaveFiles:
            return
FunctionEnd

Function SetInstallForMINIMI
    ; Ok , new happening here. Up to this point, the only thing that was different with the installs was where it was being put.
  ; The Install script was the same.... but here we have a branch effect.  Because the setup for the install, isnt' just picking the placement folder.
  ; it now includes the installation of the MINIMI application.  So.... we need to set the flag for installing MINIMI.
  ; Presumabely IF MINIMI has already been installed, we don't need to call it....
  Var /GLOBAL WAS_MINIMIInstalledAlready
  ReadRegStr $WAS_MINIMIInstalledAlready HKLM "Software\MessageSniffer" "isMINIMIInstalled"
  iferrors Install_MINIMI ; no key, just go and set the install flag, for after we leave the components page.
  StrCmp $WAS_MINIMIInstalledAlready "1" 0 Install_MINIMI  ; if it is, then drop in and handle the tests.....
    MessageBox MB_OKCANCEL "A previous installation of MINIMI was detected.  Select OK to reinstall or CANCEL to work with the existing version?" IDOK Install_MINIMI IDCANCEL SkipInstall
  Install_MINIMI:
    StrCpy $Set_For_MINIMI_INSTALL "1" # This is set because SetInstallForMINIMI gets called if you check the box, but we only want to call
                                       # the install on the page leave function.
    Return
  SkipInstall:
    StrCpy $Set_For_MINIMI_INSTALL "0"
    Return
FunctionEnd



Function installMINIMI

  ; This function puts MINIMI in the proper location. It depends on an install of IMail being present.
  ; if IMail is not present this function exits.
    StrCmp $isIMailInstalled "0" ReportFalse 0  ; ok, if Imail is up, then we'll try to unpack MINIMI.

  ; It also registers with MessageSniffer the location of the MINIMI Install.
  ; First we must find the SENDNAME key in the Imail folder.
  ## So test to be sure the path is combined properly with Imail
  ##Var /GLOBAL LocalKeyhandle                           -   declared in installSNF4Alligate
  ##Var /GLOBAL defaultHoldValue ; dummy var             -   declared in installSNF4Alligate
  ##Var /GLOBAL defaultDeliveryValue ; dummy var         -   declared in installSNF4Alligate

  ;MessageBox MB_OK "Installing MINIM"
  
               ; Ok, MINIMI goes in IMAILS Top Directory, where it usually stores SMTP32.exe
               ; Get TopDir registry key....
               ReadRegStr $LocalKeyhandle HKLM "SOFTWARE\Ipswitch\IMail\Global" "TopDir"
               StrCmp $LocalKeyhandle "" ReportFalse 0 ; ensure no empty string.
               ; Local key handle now holds the top directory where SMTP32.exe should reside.
               IfFileExists "$LocalKeyhandle\SMTP32.exe" +2 0
                 MessageBox MB_OK "Can't find SMTP32.exe in Imail's root directory: $LocalKeyhandle.  MINIMI's xml config file will need manual file correction."
                 ; Ok, file exists.... then we'll put MINIMI right here...
                 StrCpy $MINIMIInstallFolder $LocalKeyhandle
                 SetOutPath $MINIMIInstallFolder

                 IfFileExists "$MINIMIInstallFolder\SNFIMailShim.exe" 0 +2 ; if we're doing a re-install we need to be able to put it all back....
                   Rename "$MINIMIInstallFolder\SNFIMailShim.exe" "$MINIMIInstallFolder\OLD_SNFIMailShim.exe" ; leave this to be consumed by the Archiver.
                 File "SNFIMailShim.exe"  ; We can install a new SNFIMailShim.exe file in case updates...
                 File "MIMIMIreadme.txt"  ; output instruction file.



            IfFileExists "$MINIMIInstallFolder\SNFIMailShim.xml" UseExistingXML 0 ; if doesnt' exist then drop in.... and dump the file.
              ; If this was already installed, then editing it will create issues
              ; because you can't just take the target from IMail cause IMAIL has set MINIMI to be the target.
              ; but if it doesn't exist then we just drop in here and write out the file.
              File "SNFIMailShim.xml"
              ; MINIMI files are unpacked.

            UseExistingXML:
            ; if the MINIMI files were already installed, then we'll presume the registry settings and the folders are set up,
            ; and all the tests were run... so we're just going to plugin the things we currently know into a new file.... incase there are
            ; XML changes in the MINIMI xml file that don't require installer adjustment, but get repackaged.  i.e. new settings etc.
            ; So handle the target setting.
            ;MessageBox MB_OKCancel "Would you like to keep your current MINIMI configuration, select cancel to reset to the defaults." IDOK SkipIt IDCANCEL DoIt
            ;  DoIt:
            ;   SetoutPath "$MINIMIInstallFolder"
            ;   File /oname=SNFIMailShimNEW.xml "SNFIMailShim.xml" ; Ok, well even though we overwriting, we need to get the data out.... so put a temp file in.
            ;     Var /GLOBAL existingSetting
                         ; Normal delivery line for MINIM looks like this: " <delivery program='d:\IMail\smtp32.exe'/>"
                         ; Get existing value
            ;             ${GetBetween} "<delivery program='" "'/>$\r$\n" "$MINIMIInstallFolder\SNFIMailShim.xml" "$existingSetting"  ; This makes it not brittly dependant on the default value. i.e. It would
                         ; Get default value in new file
            ;             ${GetBetween} "<delivery program='" "'/>$\r$\n" "$MINIMIInstallFolder\SNFIMailShimNEW.xml" "$defaultDeliveryValue"  ; This makes it not brittly dependant on the default value. i.e. It would
                         ; if different then replace new with old.
            ;             StrCmp $existingSetting $defaultDeliveryValue SkipDeliveryReplacment 0 ; If they're the same, don't replace, otherwise replace.
            ;               !insertmacro ReplaceInFile "$MINIMIInstallFolder\SNFIMailShimNEW.xml" "<delivery program='$defaultDeliveryValue'/>$\r$\n" "<delivery program='$existingSetting'/>$\r$\n"
            ;             SkipDeliveryReplacment: ClearErrors

                         ; Now do for the hold path.... all other settings are gone baby gone....
            ;             ${GetBetween} "<hold path='" "\spam\'/>$\r$\n" "$MINIMIInstallFolder\SNFIMailShim.xml" "$existingSetting"  ; This makes it not brittly dependant on the default value. i.e. It would
            ;             ${GetBetween} "<hold path='" "\spam\'/>$\r$\n" "$MINIMIInstallFolder\SNFIMailShimNEW.xml" "$defaultHoldValue"  ; This makes it not brittly dependant on the default value. i.e. It would
            ;             StrCmp $existingSetting $$defaultHoldValue SkipHoldFolderReplacement 0 ; If there the same, don't replace, otherwise replace.
            ;               !insertmacro ReplaceInFile "$MINIMIInstallFolder\SNFIMailShimNEW.xml" "<hold path='$defaultHoldValue\spam\'/>$\r$\n" "<hold path='$existingSetting\spam\'/>$\r$\n"
            ;             SkipHoldFolderReplacement:  ClearErrors

                 ; Now delete existing config file.
            ;     Rename "$MINIMIInstallFolder\SNFIMailShim.xml" "$MINIMIInstallFolder\OLD_SNFIMailShim.xml"
                  ; NOTE: This should be archived.... in a perfect world..... leaving it for the Archiver to grab when it wants to.
            ;     Rename "$MINIMIInstallFolder\SNFIMailShimNEW.xml" "$MINIMIInstallFolder\SNFIMailShim.xml"

            ;  SkipIt:


                 ; Now we determine what IMail was pointing at:
               ReadRegStr $LocalKeyhandle HKLM "SOFTWARE\Ipswitch\IMail\Global" "SendName"
               ; WordCount is a dummy var defined in an earlier sub.... just a handler...
               ${WordFind} $LocalKeyhandle "SNFIMailShim.exe" "E*" $WordCount ; This will return in #R0 the number of times the delimiter  was found in teh testString.
               iferrors NoSNFIPRESENT_OK SKIP_INCHAIN_DELIVERY_ALTERAION ; if errors is true $R0 will be 1... indicating not-found...

                 ; If we have sniffy present then we need to skip all this file setup because the chain is intact.
               NoSNFIPRESENT_OK:
               ${WordFind} $LocalKeyhandle "SMTP32.exe" "E*" $WordCount ; This will return in #R0 the number of times the delimiter  was found in teh testString.
               iferrors NoSMTP32 0 ; if errors is true $R0 will be 1... indicating not-found...
                 StrCmp $WordCount "0" 0 +2 ; $R0 equalling zero indicates that SMTP32.exe was not the target... notify user.... ( This test is redundant...)
                     ; then we record the SendMail32.exe path.
               NoSMTP32: MessageBox MB_OK "IMail is currently delivering its messages to: $LocalKeyHandle $\r$\n  MINIMI will insert itself ahead of that call, and send valid messages to its custom handler upon completion."

                 ; Normal delivery line for MINIM looks like this: " <delivery program='d:\IMail\smtp32.exe'/>"
                 ${GetBetween} "<delivery program='" "'/>$\r$\n" "$MINIMIInstallFolder\SNFIMailShim.xml" "$defaultDeliveryValue"  ; This makes it not brittly dependant on the default value. i.e. It would
                 StrCmp $defaultDeliveryValue $LocalKeyhandle NextTest 0 ; If they're the same, don't replace, otherwise replace.
                   !insertmacro ReplaceInFile "$MINIMIInstallFolder\SNFIMailShim.xml" "<delivery program='$defaultDeliveryValue'/>$\r$\n" "<delivery program='$LocalKeyhandle'/>$\r$\n"
                 NextTest: ClearErrors
                 
                 ;Now get the spool location for IMAIL:
                 ReadRegStr $LocalKeyhandle HKLM "SOFTWARE\Ipswitch\IMail\Global" "SpoolDir" ; Grab the path to the spool folder.
                 ; We presume to put the storage/hold folder for MINIMI inside the spool directory...
                 IfFileExists "$LocalKeyhandle\spam\*.*" +2 0  ; check to see if exists, if so,skip line, otherwise make dir.
                   CreateDirectory "$LocalKeyhandle\spam"  ; Recreates target folder.  Sniffer and SNF safe...
                 ; Ok, Spool is good, now set file for hold directory...
                 ; Normal hold definition for MINIMI looks like this: <hold path='d:\IMail\spool\spam\'/>
                 ${GetBetween} "<hold path='" "\spam\'/>$\r$\n" "$MINIMIInstallFolder\SNFIMailShim.xml" "$defaultHoldValue"  ; This makes it not brittly dependant on the default value. i.e. It would
                 StrCmp $defaultHoldValue $LocalKeyhandle NextTest2 0 ; If there the same, don't replace, otherwise replace.
                   !insertmacro ReplaceInFile "$MINIMIInstallFolder\SNFIMailShim.xml" "<hold path='$defaultHoldValue\spam\'/>$\r$\n" "<hold path='$LocalKeyhandle\spam\'/>$\r$\n"
                 NextTest2:  ClearErrors
                 ; Hold is defined.
                 
                 SKIP_INCHAIN_DELIVERY_ALTERAION: ; but still upgrade MINIMI to the proper location in the SENDNAME registry key....
                 WriteRegStr HKLM "SOFTWARE\Ipswitch\IMail\Global" "SendName" "$MINIMIInstallFolder\SNFIMailShim.exe"
                 
                 iferrors WeMustUndo 0
                         

              
            Done:
               SetOutPath $INSTDIR ; return this path to what it normally is.
                   WriteRegStr HKLM "Software\MessageSniffer" "isMINIMIInstalled" "1"
                   WriteRegStr HKLM "Software\MessageSniffer" "MINIMIInstallFolder" "$MINIMIInstallFolder"
                       ; good to go.
                       StrCpy $isMINIMIInstalled "1"
                       return

  ReportFalse: MessageBox MB_OK "Unable to find valid IMail TopDirector from the registry.  MINIMI Install was aborted."
  Return
  
  WeMustUndo:
    MessageBox MB_OKCANCEL "Failed Attempt. Clean Up?$\r$\nDetails:  MINIMI Install script was unable to write to the IMail SendName registry key. ( To instert MINIMI into the message control stream. ) Click OK if you want the installer to remove and restore the intallation attempt?  ( Cancel if you want to leave the three MINIMI files.  i.e. You might want to try to tie in MINIMI through Imails Administration screens? )" IDOK cleanupFiles IDCANCEL leaveFiles

  cleanupFiles:
    ; since we couldn't edit the registry, we don't need to worry abou tit. Now Kill attempt:
    ifFileExists "$MINIMIInstallFolder\SNFIMailShimNEW.xml" 0 +2
      Delete "$MINIMIInstallFolder\SNFIMailShimNEW.xml"
    ifFileExists "$MINIMIInstallFolder\OLD_SNFIMailShim.xml" 0 +2
      Delete "$MINIMIInstallFolder\OLD_SNFIMailShim.xml"
    ifFileExists "$MINIMIInstallFolder\OLD_SNFIMailShim.exe" 0 +2
      Delete "$MINIMIInstallFolder\OLD_SNFIMailShim.exe"
    ifFileExists "$MINIMIInstallFolder\SNFIMailShim.xml" 0 +2
      Delete "$MINIMIInstallFolder\SNFIMailShim.xml"
    ifFileExists "$MINIMIInstallFolder\SNFIMailShim.exe" 0 +2
      Delete "$MINIMIInstallFolder\SNFIMailShim.exe"
    ifFileExists "$MINIMIInstallFolder\MIMIMIreadme.txt" 0 +2
      Delete "$MINIMIInstallFolder\MIMIMIreadme.txt"
  leaveFiles:
    return
FunctionEnd


Function DetermineMXGuard
  ; NOTE: Currently the only test for MXGuard being installed is a looking at IMAILS SendName parameter.
  ; Versions of 4.1 of MXGUard will have a registry key put in for our use.
  ; The alternative is to ask for it, ???? or to guess in C:\Program Files\dgSoft Internet Services\mxGuard for Mail Servers

  ; dont' forget there can be the mxhook.exe
  
    StrCpy $isMXGuardInstalled "0"
               ;; If Imail is activated with MXGuard then its HKEY_LOCAL_MACHINE\SOFTWARE\Ipswitch\IMail\Global\SendName
               ;; registry entry will look like: C:\\anypath\\imailtomxguard.exe  This is valid test for MXGuard 3.2 - present.
  Var /GLOBAL MXPathVar
  Var /GLOBAl testVar
    StrCmp $isIMailInstalled "1" 0 TestSmarterMail
               ## So test to be sure the path is combined properly with Imail
               ReadRegStr $MXPathVar HKLM "SOFTWARE\Ipswitch\IMail\Global" "SendName"
               StrCmp $MXPathVar "" ReportFalse 0
               ${WordFind} $MXPathVar "imailtomxguard.exe" "E*" $R0 ; This will return in #R0 the number of times the delimiter  was found in teh testString.
               iferrors ReportFalse 0 ; if errors is true $R0 will be 1... indicating not-found...
                 ${IF} $R0 > "0" ; But witn no errors, 1 means it found 1 instandce.
                     ; then we display the option.
                     ; It found the exe file in the path... good to go.
                       StrCpy $isMXGuardInstalled "1"
                       ${GetParent} $MXPathVar $MXGuardInstallFolder
                 ${endif}
                 Return
  TestSmarterMail:
  StrCmp $isSmarterMailInstalled "1" 0 ReportFalse
     ifFileExists "C:\Program Files\dgSoft Internet Services\mxGuard for Mail Servers\mxGuard.xml" 0  Try4Pt2
       ; well we lucked out.  Looks like its here.
       ${GetBetween} "<type>" "</type>" "C:\Program Files\dgSoft Internet Services\mxGuard for Mail Servers\mxGuard.xml" "$testVar" 
         StrCmp $testVar "SmarterMail" 0 ReportFalse
           StrCpy $isMXGuardInstalled "1"
           StrCpy $MXGuardInstallFolder "C:\Program Files\dgSoft Internet Services\mxGuard for Mail Servers"
     Try4Pt2:
     ifFileExists "C:\Program Files\dgSoft Internet Services\mxGuard for Mail Servers v4.2\mxGuard.xml" 0  ReportFalse
       ; well we lucked out.  Looks like its here.
       ${GetBetween} "<type>" "</type>" "C:\Program Files\dgSoft Internet Services\mxGuard for Mail Servers v4.2\mxGuard.xml" "$testVar"
         StrCmp $testVar "SmarterMail" 0 ReportFalse
           StrCpy $isMXGuardInstalled "1"
           StrCpy $MXGuardInstallFolder "C:\Program Files\dgSoft Internet Services\mxGuard for Mail Servers v4.2"
     
 ReportFalse:
    Return
FunctionEnd

Function SetInstallForMXGuard
  ; Currently, it doesn't matter where sniffer is for MXGuard, so
  ; we're going to put it at C:\MessageSniffer\MXGuard
  ;CreateDirectory "C:\MessageSniffer\"
  ;CreateDirectory "C:\MessageSniffer\MXGuardRoot" ; This will be where the SNFArchive goes for the MXGuard Install....
  ;StrCpy $MXGuardInstallFolder "C:\MessageSniffer\MXGuard"
  ;StrCpy $SNFServerInstallDir $MXGuardInstallFolder
  ;StrCpy $INSTDIR "$SNFServerInstallDir\SNF"
FunctionEnd


Function DetermineDeclude
  ; Declude is detected by the following methods:

  ; First you locate its defined registry call in the following key:
  ; HKLM SOFTWARE ComputerizedHorizons
  ; Relevant Keys from Declude: DecludeInstalled , MailConfigFilePath, RootMailPath, SmarterMailPath
  StrCpy $isDecludeInstalled "0" ; Default to no until proven otherwise.
  StrCpy $DecludeInstallFolder = "";
  ; Now detect Declude:
  ; This is useless, it comes in as "01" or something.... incomparable with -1-
  ; ReadRegStr $isDecludeInstalled HKLM "SOFTWARE\ComputerizedHorizons" "DecludeInstalled"
  
  ReadRegStr $DecludeInstallFolder HKLM "SOFTWARE\ComputerizedHorizons" "RootMailPath"
      StrCmp $DecludeInstallFolder "" ReportBad 0
        IfFileExists "$DecludeInstallFolderdeclude" 0 ReportBad ; the RootMailPath has an ending slash.
        StrCpy $isDecludeInstalled "1" ; Default to no until proven otherwise
        Return
  ReportBad:
    StrCpy $isDecludeInstalled "0" ; Default to no until proven otherwise 
    
      Return
  ; The following items are of interest:  DecludeInstalled 0 or 01
  ; MailConfigFilePath ( for smatermail will be SmarterMailServiceFolder/mailConfig.xml
  ; RootMailPath ( for smartermail will be C:\Smartermail\ ) Add "declude\" for declude folder
  ; SmarterMailPath ( For smartermail will be the service folder.)
FunctionEnd ; end finding Declude

Function SetInstallForDeclude
      ; NOTE: Declude puts a slash at the end of its root path key... so we need to remove the slash from the string
    StrCpy $1 $DecludeInstallFolder "" -1 ; get the last char.
    StrCmp $1 "\" 0 JustCopy ; if its a slash, then lop it off....
    StrCpy $DecludeInstallFolder $DecludeInstallFolder -1 ; Lop off last char.
  JustCopy:
    StrCpy $SNFServerInstallDir "$DecludeInstallFolder\declude" ; So we're going to install the SNF here....
    StrCpy $INSTDIR "$SNFServerInstallDir\SNF"
FunctionEnd




Function DetermineAlligate
  StrCpy $isAlligateInstalled "0" ; Default to no until proven otherwise.
  StrCpy $AlligateInstallFolder = "";
  ; Now detect Alligate:
  ReadRegStr $AlligateInstallFolder HKLM "SOFTWARE\SolidOak\Alligate\Settings" "InstallDir"
  StrCpy $AlligateInstallFolder $AlligateInstallFolder -1 ; lop last '\' off end of alligates paths.....
  ; If Alligate exists, get its folder:
  StrCmp $AlligateInstallFolder "" ReportBad 0
        StrCpy $isAlligateInstalled "1" ; Default to no until proven otherwise
        Return
  ReportBad:
    StrCpy $isAlligateInstalled "0" ; Default to no until proven otherwise
    Return
 Return
FunctionEnd

Function DetermineSmarterMail
  ; Smarter mail is detected by the following methods:
  
  ; First you locate its defined registry call in the following key:
  ; HKLM SOFTWARE SmarterTools SmarterMail InstallPath
  ; When found, you then look in that directory for the the Service Folder and open the mailConfig.xml file.
  ; And then you find the SpoolPath i.e.
    ; <spoolPath>c:\SmarterMail\Spool\</spoolPath>
  StrCpy $isSmarterMailInstalled "0" ; Default to no until proven otherwise.
  StrCpy $SmarterMailInstallFolder = "";
  ; Now detect SmarterMail:
  ReadRegStr $SmarterMailInstallFolder HKLM "SOFTWARE\SmarterTools\SmarterMail" "InstallPath"
  ; If Declude exists, get its folder:
  StrCmp $SmarterMailInstallFolder "" ReportBad 0
        StrCpy $isSmarterMailInstalled "1" ; Default to no until proven otherwise
        Return
  ReportBad:
    StrCpy $isSmarterMailInstalled "0" ; Default to no until proven otherwise
    Return
  ; This tells you where the Spool folder for SmarterMail folder is.   Go up one directory and that is the root SmarterMail dir.
  ; This is where Declude will be installed if it is installed.
  ;
  return
FunctionEnd

Function DetermineImail

  StrCpy $isIMailInstalled "0" ; Default to no until proven otherwise.
  StrCpy $IMailInstallFolder = "";
  ; Now detect IMail:
  ReadRegStr $IMailInstallFolder HKLM "SOFTWARE\Ipswitch\Imail\Global" "TopDir"
  StrCmp $IMailInstallFolder "" ReportBad  0
  IfFileExists $IMailInstallFolder 0 ReportBad ; Check to see if path is valid.
    ; If Declude exists, get its folder:
        StrCpy $isIMailInstalled "1" ; Default to no until proven otherwise
         Return
  ReportBad:
    StrCpy $isIMailInstalled "0" ; Default to no until proven otherwise
    Return
 
FunctionEnd

Function DetermineInstallationPlatforms
  Call InitPlatformFlags
  ; This function determines and sets the flags on the installation platform options.
  ; We have several options available to us:


  ## ADDINGPLATFORM ## STEP 8  ADD LINE HERE TO CALL THE DetermineXYZPlatform option.  This ensures that when the time comes to
  ## Check all the known/supported platforms, that the check gets run.

   ; First determine mail platforms.
   Call DetermineIMail
   Call DetermineSmarterMail
   Call DetermineAlligate

   ; Now determine implementation platforms.
   Call DetermineDeclude
   Call DetermineMXGuard
   Call DetermineMINIMI
   Call DetermineMDaemon
   
FunctionEnd

Function UninstallXYNTService
   ; This stops and uninstalls the XYNTService
   nsExec::Exec "NET STOP SNFService" "" SH_HIDE
    ifFileExists "$SNFServerInstallDir\SNF\XYNTService.exe" 0 +2
      nsExec::Exec "$SNFServerInstallDir\SNF\XYNTService -u" "" SH_HIDE  ; This should run reguardless of where the master installer is located.
    ifFileExists "$SNFServerInstallDir\Sniffer\XYNTService.exe" 0 +2
      nsExec::Exec "$SNFServerInstallDir\Sniffer\XYNTService -u" "" SH_HIDE  ; This should run reguardless of where the master installer is located.
    return
    
FunctionEnd

Function checkTelemetry

    ${GetBetween} "licenseid='" "'" "$INSTDIR\identity.xml" $LicenseID ; This makes it not brittly dependant on the default value. i.e. It would
    ${GetBetween} "authentication='" "'" "$INSTDIR\identity.xml" $Authentication
    

        ; first test for valid rulebase Status
        nsExec::Exec /TIMEOUT=700 '"$INSTDIR\snf2check.exe" "$INSTDIR\$LicenseID.snf" "$Authentication"' SH_HIDE
        pop $0
        ${If} $0 = "0"
          Detailprint " The Rulebase passes the snf2check.exe authentication."
        ${Else}
          Detailprint " Snf2check fails: "
          ${Switch} $0
            ${Case} "0"
                DetailPrint " SNFClient successfuly connected with SNFServer."
                Goto EndSNF2CheckTest
            ${Case} "65"
                DetailPrint " {65} ERROR_CMDLINE.  SNF was called improperly."
                Goto EndSNF2CheckTest
             ${Case} "66"
                DetailPrint " {66}ERROR_LOGFILE Cannot open logfile."
                Goto EndSNF2CheckTest
             ${Case} "67"
                DetailPrint " {67} ERROR RULE FILE.  Cannot open rules file."
                Goto EndSNF2CheckTest
             ${Case} "68"
                DetailPrint " {68} ERROR_RULE_DATA Cannot create pattern matrix."
                Goto EndSNF2CheckTest
             ${Case} "69"
                DetailPrint " {69} ERROR_MSG_FILE Cannot open message file."
                Goto EndSNF2CheckTest
             ${Case} "70"
                DetailPrint " {70} ERROR_ALLOCATION Allocation error during processing."
                Goto EndSNF2CheckTest
             ${Case} "71"
                DetailPrint " {71} ERROR_BAD_MATRIX Pattern trace went out of range."
                Goto EndSNF2CheckTest
             ${Case} "72"
                DetailPrint " {72} ERROR_MAX_EVALS The maximum number of evaluation paths was exceeded."
                Goto EndSNF2CheckTest
             ${Case} "73"
                DetailPrint " {73} ERROR_RULE_AUTH The rulebase file did not authenticate properly."
                Goto EndSNF2CheckTest
             ${Case} "99"
                DetailPrint " {99} ERROR_UNKNOWN"
                Goto EndSNF2CheckTest
          ${EndSwitch}
          EndSNF2CheckTest:
        ${EndIF}
        
        ifFileExists "$SNFServerInstallDir\App\MDaemon.exe" 0 +3
          Detailprint "MDaemon Install system check complete."
          return
        
        
        DetailPrint "Checking SNFService:"
        nsExec::Exec /TIMEOUT=700 "NET START SNFService" SH_HIDE
        pop $0
        ${Switch} $0
            ${Case} "0"  
                DetailPrint " SNFService was started."
                Goto EndSNFServiceTest
            ${Case} "1"
                DetailPrint " SNFService was not supported."
                Goto EndSNFServiceTest
             ${Case} "2"
                DetailPrint " SNFService is running."
                Goto EndSNFServiceTest
             ${Case} "8"
                DetailPrint " Unknown failure starting SNFService."
                Goto EndSNFServiceTest
             ${Case} "10"
                DetailPrint " Installer has verified that SNFService is running."
                Goto EndSNFServiceTest
          ${EndSwitch}
        EndSNFServiceTest:
        
; These are the NET START return codes.
;        gs_service_status( 0) = "Success"
;        gs_service_status( 1) = "Not Supported"
;        gs_service_status( 2) = "Access Denied"
;        gs_service_status( 3) = "Dependent Services Running"
;        gs_service_status( 4) = "Invalid Service Control"
;        gs_service_status( 5) = "Service Cannot Accept Control"
;        gs_service_status( 6) = "Service Not Active"
;        gs_service_status( 7) = "Service Request Timeout"
;        gs_service_status( 8) = "Unknown Failure"
;        gs_service_status( 9) = "Path Not Found"
;        gs_service_status(10) = "Service Already Running"
;        gs_service_status(11) = "Service Database Locked"
;        gs_service_status(12) = "Service Dependency Deleted"
;        gs_service_status(13) = "Service Dependency Failure"
;        gs_service_status(14) = "Service Disabled"
;        gs_service_status(15) = "Service Logon Failure"
;        gs_service_status(16) = "Service Marked For Deletion"
;        gs_service_status(17) = "Service No Thread"
;        gs_service_status(18) = "Status Circular Dependency"
;        gs_service_status(19) = "Status Duplicate Name"
;        gs_service_status(20) = "Status Invalid Name"
;        gs_service_status(21) = "Status Invalid Parameter"
;        gs_service_status(22) = "Status Invalid Service Account"
;        gs_service_status(23) = "Status Service Exists"
;        gs_service_status(24) = "Service Already Paused"

        Sleep 3000
        DetailPrint "Waiting for SNFServer to spin up."
    
        ;  nsExec::ExecToLog /TIMEOUT=700 '$INSTDIR\SNFClient.exe -status.second'
        nsExec::Exec /TIMEOUT=700 '$INSTDIR\SNFClient.exe -status.second' SH_HIDE  ; This should run reguardless of where the master installer is located.
        pop $0
        
        ${Switch} $0
            ${Case} "0"
                DetailPrint " SNFClient successfuly connected with SNFServer."
                Goto EndSNFClientTest
            ${Case} "65"
                DetailPrint " {65} ERROR_CMDLINE.  SNF was called improperly."
                Goto EndSNFClientTest
             ${Case} "66"
                DetailPrint " {66}ERROR_LOGFILE Cannot open logfile."
                Goto EndSNFClientTest
             ${Case} "67"
                DetailPrint " {67} ERROR RULE FILE.  Cannot open rules file."
                Goto EndSNFClientTest
             ${Case} "68"
                DetailPrint " {68} ERROR_RULE_DATA Cannot create pattern matrix."
                Goto EndSNFClientTest
             ${Case} "69"
                DetailPrint " {69} ERROR_MSG_FILE Cannot open message file."
                Goto EndSNFClientTest
             ${Case} "70"
                DetailPrint " {70} ERROR_ALLOCATION Allocation error during processing."
                Goto EndSNFClientTest
             ${Case} "71"
                DetailPrint " {71} ERROR_BAD_MATRIX Pattern trace went out of range."
                Goto EndSNFClientTest
             ${Case} "72"
                DetailPrint " {72} ERROR_MAX_EVALS The maximum number of evaluation paths was exceeded."
                Goto EndSNFClientTest
             ${Case} "73"
                DetailPrint " {73} ERROR_RULE_AUTH The rulebase file did not authenticate properly."
                Goto EndSNFClientTest
             ${Case} "99"
                DetailPrint " {99} ERROR_UNKNOWN"
                Goto EndSNFClientTest
          ${EndSwitch}
        EndSNFClientTest:
        
              Detailprint "System test complete."
              Return  ; The Installed Restorer will have handled everything.
              
FunctionEnd



Section /o "New Install" g1o1
            ; This uninstalls the XYNTService if it exists.
            
            Call UninstallXYNTService
              ; Lastly, since we don't want to redo all this activity when we finally DO get to the archiver or the installer..... we need to put a local file
              ; in the root directory where the Archiver.exe or the Restorer.exe is going to be to give it a local reference.
              Call OutputLocalRootInfoFile
              
              ## ADDINGPLATFORM ## STEP 9  If you're install requires you to bounce a dependant service after doing all the installs,
              ## ensure that that happens here.
              
              StrCmp $isMDaemonInstalled "1" 0 TestNextHandle1
                ifFileExists "$MDaemonInstallFolder\App\MDaemon.exe" 0 TestNextHandle1
                nsExec::Exec 'NET STOP MDAEMON' "" SH_HIDE
                Sleep 1000
                ;nsExec::Exec 'net start MDAEMON' "" SH_HIDE
                ;Sleep 1000
              TestNextHandle1:

              StrCmp $isSNF4AlligateInstalled "1" 0 Handlenext1
                nsExec::Exec 'net stop AgSMTPSvc' "" SH_HIDE
                Sleep 1000
              Handlenext1:

              StrCmp $isMINIMIInstalled "1" 0 TestNext1
                nsExec::Exec 'NET STOP "IMail SMTP Server"' "" SH_HIDE
                Sleep 1000
             Testnext1:

              StrCmp $isDecludeInstalled "1" 0 +2
                nsExec::Exec "NET STOP Decludeproc" "" SH_HIDE

                
              ; This means that we made a fresh SNF folder and we're going to insert the files there.
              SetOutPath $INSTDIR ; determines where to put the Restorer/Installer
              File "Restorer.exe" ; Unpack the files.
              ExecWait "$INSTDIR\Restorer.exe -F" ; Execute it.

              StrCmp $isMDaemonInstalled "1" 0 TestNextHandle
                nsExec::Exec 'NET STOP MDAEMON' "" SH_HIDE
                Sleep 3000
                nsExec::Exec 'net start MDAEMON' "" SH_HIDE
                Sleep 1000
              TestNextHandle:

              StrCmp $isSNF4AlligateInstalled "1" 0 Handlenext
                nsExec::Exec 'net stop AgSMTPSvc' "" SH_HIDE
                Sleep 1000
                nsExec::Exec '"$SNF4AlligateInstallFolder\AGFiltSvc.exe" /start'   ; this will start it up with the reset FilterEXE registry settings.
                Sleep 1000
                nsExec::Exec 'net start AgSMTPSvc' "" SH_HIDE
                Sleep 1000
              Handlenext:

              StrCmp $isMINIMIInstalled "1" 0 TestNext
                nsExec::Exec 'NET STOP "IMail SMTP Server"' "" SH_HIDE
                Sleep 1000
                nsExec::Exec 'NET START "IMail SMTP Server"' "" SH_HIDE
                Sleep 1000
             Testnext:
              
              StrCmp $isDecludeInstalled "1" 0 ThenQuit
                nsExec::Exec "NET STOP Decludeproc" "" SH_HIDE
                Sleep 1000
                nsExec::Exec "NET START Decludeproc" "" SH_HIDE

        ThenQuit:
          call checkTelemetry
          return
        SectionEnd

 Section /o "Install Fresh (Discard local configuration.)" g1o2
            ; This uninstalls the XYNTService if it exists.
            Call UninstallXYNTService

          ; The decision tree here is do we want to maintain the configuration file, or blow it away.
          ; this section is for blowing it away.  We do record a rollback.

          StrCpy $CustomFolderName "" ; Leaving this as empty string means Just use the default naming convention inside ArchiveSnapshot.

          ; Lastly, since we don't want to redo all this activity when we finally DO get to the archiver or the installer..... we need to put a local file
          ; in the root directory where the the Restorer.exe is going to be to give it a local reference.
          Call OutputLocalRootInfoFile ; This needed to be done before you archive in order to get the LocalRoot.txt file included.

          ; Now create the folder to dump the Restorer.exe into.
          ifFileExists "$INSTDIR\*.*" +2 0
           CreateDirectory "$INSTDIR" ; create folder.

          ## ADDINGPLATFORM ## STEP 9B  If you're install requires you to bounce a dependant service after doing all the installs,
          ## ensure that that happens here as well as at #9.
          StrCmp $isMDaemonInstalled "1" 0 TestNextHandle
            nsExec::Exec 'NET STOP MDAEMON' "" SH_HIDE
            Sleep 1000
          TestNextHandle:

          StrCmp $Set_For_SNF4Alligate_INSTALL "1" 0 Handlenext
            nsExec::Exec '"$SNF4AlligateInstallFolder\AGFiltSvc.exe" /Stop' "" SH_HIDE  ; this will stop it and release the SNF4Alligate.exe file.
            Sleep 1000
            nsExec::Exec 'net stop AgSMTPSvc' SH_HIDE
            Sleep 1000
          Handlenext:
          
          StrCmp $isDecludeInstalled "1" 0 +2
            nsExec::Exec "NET STOP Decludeproc" "" SH_HIDE
          
          ; Exract the files.
          SetOutPath $INSTDIR
            File "Restorer.exe" ; Unpack the files.
          SetOutPath $SNFServerInstallDir
            ExecWait "$INSTDIR\Restorer.exe -F"  ; execute it for fresh install.
          ;nsExec::Exec 'NET START "SNFService"' "" SH_HIDE

          StrCmp $Set_For_SNF4Alligate_INSTALL "1" 0 Handlenext2
            nsExec::Exec '"$SNF4AlligateInstallFolder\AGFiltSvc.exe" /start' "" SH_HIDE   ; this will start it up with the reset FilterEXE registry settings.
                Sleep 1000
            nsExec::Exec 'net start AgSMTPSvc' "" SH_HIDE
                Sleep 1000
          Handlenext2:

          StrCmp $isMINIMIInstalled "1" 0 TestNext2
                nsExec::Exec 'NET STOP "IMail SMTP Server"' "" SH_HIDE
                Sleep 1000
                nsExec::Exec 'NET START "IMail SMTP Server"' "" SH_HIDE
                Sleep 1000
          Testnext2:

          StrCmp $isMDaemonInstalled "1" 0 TestNextHandle2
            nsExec::Exec 'NET STOP MDAEMON' "" SH_HIDE
            Sleep 3000
            nsExec::Exec 'net start MDAEMON' "" SH_HIDE
            Sleep 1000
          TestNextHandle2:
          
          StrCmp $isDecludeInstalled "1" 0 ThenQuit
                nsExec::Exec "NET STOP Decludeproc" "" SH_HIDE
                nsExec::Exec "NET START Decludeproc" "" SH_HIDE

ThenQuit:
        call checkTelemetry
        return
     SectionEnd

     Section  /o "Upgrade (Retain existing settings.)" g1o3
                    ; The decision tree here is do we want to maintain the configuration file, or blow it away.
                    ; this section is for blowing it away.  We do archive
          ;Stop the service if its working.
          Call UninstallXYNTService

          ; Since we don't want to redo all this path determination activity when we finally DO get to the archiver or the installer..... we need to put a local file
          ; in the root directory where the Archiver.exe or the Restorer.exe is going to be to give it a local reference.
          Call OutputLocalRootInfoFile ; This needed to be done before you archive in order to get the LocalRoot.txt file included.

          ############################################################
          ; Now create the folder to dump the Restorer.exe into.
          IfFileExists "$INSTDIR\*.*" +2 0
          CreateDirectory "$INSTDIR" ; create folder if it doesn't exist.  ( Meaning that the older sniffer files are left behind. )

          ## ADDINGPLATFORM ## STEP 9C  If you're install requires you to bounce a dependant service after doing all the installs,
          ## ensure that that happens here as well as at #9 and #9B.
          StrCmp $isMDaemonInstalled "1" 0 TestNextHandle
            nsExec::Exec 'NET STOP MDAEMON' "" SH_HIDE
            Sleep 3000
            ;nsExec::Exec 'net start MDAEMON' "" SH_HIDE
            ;Sleep 1000
          TestNextHandle:
          
          StrCmp $isSNF4AlligateInstalled "1" 0 Handlenext
            nsExec::Exec 'net stop AgSMTPSvc' "" SH_HIDE
            Sleep 1000
            nsExec::Exec '"$SNF4AlligateInstallFolder\AGFiltSvc.exe" /stop'  "" SH_HIDE
            Sleep 1000  ; this will stop it and release the SNF4Alligate.exe file.
          Handlenext:

          ; Exract the files.
          SetOutPath $INSTDIR
            File "Restorer.exe" ; Unpack the files.
          SetOutPath $SNFServerInstallDir
            ExecWait "$INSTDIR\Restorer.exe"  ; execute it for fresh install.   THIS IS THE DIFFERENCE NO -F in the command line attempts to ressurect the existing files.
          ;nsExec::Exec 'NET START "SNFService"' "" SH_HIDE

          StrCmp $isMDaemonInstalled "1" 0 TestNextHandle2
            nsExec::Exec 'NET STOP MDAEMON' "" SH_HIDE
            Sleep 1000
            nsExec::Exec 'net start MDAEMON' "" SH_HIDE
            Sleep 1000
          TestNextHandle2:

          StrCmp $Set_For_SNF4Alligate_INSTALL "1" 0 Handlenext3
            nsExec::Exec '"$SNF4AlligateInstallFolder\AGFiltSvc.exe" /start' "" SH_HIDE
            Sleep 1000   ; this will start it up with the reset FilterEXE registry settings.
            nsExec::Exec 'net start AgSMTPSvc' "" SH_HIDE
            Sleep 1000
           Handlenext3:

        ; If its a MINIMI install, bounce the IMAIL SMTP
        StrCmp $isMINIMIInstalled "1" 0 TestNext
                nsExec::Exec 'NET STOP "IMail SMTP Server"' "" SH_HIDE
                Sleep 1000
                nsExec::Exec 'NET START "IMail SMTP Server"' "" SH_HIDE
                Sleep 1000
        Testnext:
            
        StrCmp $isDecludeInstalled "1" 0 ThenQuit
                nsExec::Exec "NET STOP Decludeproc" "" SH_HIDE
                nsExec::Exec "NET START Decludeproc" "" SH_HIDE

        ThenQuit:
          call checkTelemetry
          return
        SectionEnd

        ; NOTE, if this doesn't exist in the current install, it must be greyed out.... or not displayed.
        Section /o "Archive Utility" g1o4
          ; The Intermediate archive display
          ; page handles this in the event flow.  By this point theres nothing to do.
        SectionEnd

        Section /o  "Restore Utility" g1o5
          ## This section is stubbed.
        SectionEnd
        ; NOTE, Same for this.... can't fire it, if it doesn't exist.
        Section  /o "Remove Install" g1o6
          ; By this point, its been handled, so there's nothign to do.  This response is handled
          ; in the callback funciton of hte components selection page.
        SectionEnd
        
      Section /o "Status Viewer" g1o6B
           ; Nothing happenes here.  This is here to enable it to show up in the sections components viewer page.
      SectionEnd

;SectionGroupEnd

;--------------------------------
; Functions for control of components selection
; $1 stores the status of group 1
; $2 stores the status of group 2
; Ok, this list is going to become a little different.  We'e not detecting and displaying available options, we'e offeing options
; ( albite if we find one, we mark it as the recommended one. ) but that means the onSelect doesn't really set anything until after the
; next custom page which will properly locate all the files.... )
;SectionGroup /e "Platform Options" GRP_2

      ## ADDINGPLATFORM ## STEP 10  This is very important.  You must add an optional section ( indicated by the /o ) for your new platform.
      ## You need to add it in the placement that you want it to appear in the list.  BUT!!!! IF you insert it in the middle, you have to patch all
      ## ordinal responses for the swithc-case handling code for items below it.  So unless you have a VERY good reason, add it at the end.
      ## The placment order affects which number is returned when the user clicks it.
      ##  i.e.  When a user clicks the option, it will come back with an ordinal say "20" for the ID of the checkbox that triggered the 'event'.
      ##  So at the end of this list, add your new one.
      
      ## ADDINGPLATFORM ## STEP 10B Give it a unique option name that is meaningful.
      ##  For example: gIWDI means [I]mail[W/][D]eclude[I]nstall.  Note that some of them have commented ones to the right like g107 meaning group1option7.
      ##  This became impossible to keep track after five or six options, so clearer names were swapped in.

      ## ADDINGPLATFORM ## STEP 10C pay attention to where in the list you put your new option.
      ## There are more places you need to insert items, and you should insert them in the same place in all the lists.  This will keep things easier later.

      Section /o "Imail w/ Declude Install" gIWDI ; g1o7 Imail w/ Declude Install
              ; This means that we made a fresh SNF folder and we're going to insert the files there.
      ;        MessageBox MB_OK "Selected Imail Declude option."
      SectionEnd

      Section /o "Imail MXGuard Install" gIMXI ; g1oA Imail w/ MXGuard Install
              ; This means that we made a fresh SNF folder and we're going to insert the files there.
              ;MessageBox MB_OK "Selected Imail MXGuard option."
      SectionEnd

      Section /o "Imail w/MINIMI for SNF" gIMMI ; g1o7B Imail MiniMi Install
           ; Nothing happenes here.  This is here to enable it to show up in the sections components viewer page.
      SectionEnd

      Section /o "SmarterMail w/ Declude Install" gSWDI ; g1o8  Smartermail W/ Declude Install
              ; This means that we made a fresh SNF folder and we're going to insert the files there.
              ;MessageBox MB_OK "Selected SmarterMail Declude option."
      SectionEnd

      Section /o "SmarterMail MXGuard Install" gSMXI ; g1oA2 Smartermail W/ MXGuard Install
              ; This means that we made a fresh SNF folder and we're going to insert the files there.
              ;MessageBox MB_OK "Selected Imail MXGuard option."
      SectionEnd
      
      Section /o "Alligate Install" gAWDI ; g1o9 Alligate w/
              ; This means that we made a fresh SNF folder and we're going to insert the files there.
              ;MessageBox MB_OK "Selected Alligate Declude option."
      SectionEnd
SectionGroup /e "IceWarp" gIW
      Section /o "IceWarp in ~A.V.~ position" gIWTI  ; IcewWarp Tie In ( In AntiVirus Position )
         ; this is the tie in to Icewarp via the filter.  It may be expand with the IceWarp .dll tie in.
      SectionEnd
      Section /o "IceWarp As Custom-Filter (y/n) " gIWTICF ; IceWarp Tie In Custom Filter
         ; this is the tie in to Icewarp via the filter.  It may be expand with the IceWarp .dll tie in.
      SectionEnd
      Section /o "IceWarp As Custom-Filter (+5)" gIWTICF2 ; IceWarp Tie In Custom Filter 2
         ; this is the tie in to Icewarp via the filter.  It may be expand with the IceWarp .dll tie in.
      SectionEnd
SectionGroupEnd
      Section /o "MailSite Install" gMSI
         ; this is the tie in to MailSite.
      SectionEnd

      Section /o "Kerio Mail Install" gKMI
         ; this is the tie in to Kerio.
      SectionEnd
      
      Section /o "MDaemon Install" gMDDLL
        ; this section is to tie in and install the dll for the MDaemon Mail Site.
      SectionEnd

      Section /o "Default SNF Install / Sniffer Install" gSNFI ; g1oB
              ; This means that we made a fresh SNF folder and we're going to insert the files there.
              ;MessageBox MB_OK "Selected DefaultSNF option."
      SectionEnd

      Section /o "Unknown Server - Declude Install" gUSWDI ; g1oC
              ; Can't recognize what host is using Declude, but declude is there....
              ; MessageBox MB_OK "Selected DefaultSNF option."
      SectionEnd

      Section /o "Other (custom/unknown combination)" gCUKC ; MDI_mx
      SectionEnd
      


Function InitPlatformFlags
  ; Used to clear the setup flags.
      ## ADDINGPLATFORM ## STEP 11  Add a clear command here so when you want all the init flags to be cleared, they will all clear together.
        StrCpy $isIceWarpInstalled "0"
        StrCpy $isMailSiteInstalled "0"
        StrCpy $isKerioInstalled "0"
        StrCpy $isImailInstalled "0"
        StrCpy $isSmarterMailInstalled "0"
        StrCpy $isAlligateInstalled "0"
        StrCpy $isDecludeInstalled "0"
        StrCpy $isMXGuardInstalled "0"
        StrCpy $isMINIMIInstalled "0"
        StrCpy $isMDaemonInstalled "0"

        StrCpy $SelectedCaseIndexForPlatformScreen "0" ; undetermined.
FunctionEND

Function ResetSectionNames
  ; Used to reset the cleared section flags.

        ## ADDINGPLATFORM ## STEP 12  Add the text that you want to appear for the new platform option.  Should be the same as the text you entered
        ## to define the section in step 10a.  The scripting program makes an option unavailable by clearing this text field.  You need to have
        ## the line in this list, so that if you need to refresh the screen, or go back, etc, the script can get the original values and reset them.

        SectionSetText  ${g1o1} "New Install"
        SectionSetText  ${g1o2} "Install Fresh (Discard local configuration.)"
        SectionSetText  ${g1o3} "Upgrade (Retain existing settings.)"
        SectionSetText  ${g1o4} "Archive Utility"
        SectionSetText  ${g1o5} "Rollback Altered Files"
        SectionSetText  ${g1o6} "Remove Install"
        SectionSetText  ${g1o6B} "Status Viewer"

        SectionSetText ${gIWDI} "Imail w/ Declude Install"  ; g1o7
        SectionSetText ${gIMXI} "Imail MXGuard Install"  ; g1oA
        SectionSetText ${gIMMI} "Imail w/MINIMI for SNF"  ; g1o7B
        SectionSetText ${gSWDI} "SmarterMail w/ Declude Install"  ; g1o8
        SectionSetText ${gSMXI} "SmarterMail MXGuard Install" ; g1oA2
        SectionSetText ${gAWDI} "Alligate Install" ; g1o9
        SectionSetText ${gIW} "IceWarp"  ; g1o7
        SectionSetText ${gIWTI} "IceWarp in ~A.V.~ position" ; g1o9
        SectionSetText ${gIWTICF} "IceWarp as Content-Filter (y/n)"
        SectionSetText ${gIWTICF2} "IceWarp as Content-Filter (+5)"
        ;SectionSetText ${gMSI} "MailSite Install" ; g1o9
        SectionSetText ${gMSI} "" ; g1o9

        SectionSetText ${gKMI} "Kerio Install" ; g1o9

        SectionSetText ${gMDDLL} "MDaemon Install" ; gMDDLL
        SectionSetText ${gSNFI} "" ;SectionSetText ${gSNFI} "Default SNF Install / Sniffer Install"  ; g1oB
        SectionSetText ${gUSWDI} "" ;SectionSetText ${gUSWDI} "Unknown Server - Declude Install"  ; g1oC
        SectionSetText  ${gCUKC} "Other (custom/unknown combination)" ; MDI_mx
FunctionEND

Function .onInit

   ## Test for useable Service wrapper that this installer can hijack and control ( i.e. It was installed with this Installer,
   ## even if its on a differing platform.
        nsExec::Exec /TIMEOUT=1500  "NET STOP SNFService"
        pop $0
        StrCmp $0 "0" 0 NotStoppable  ; needs to return zero to be known and available.....if not, inconclusive...
          ## Service was stoppable.  Not start it.
          nsExec::Exec /TIMEOUT=1500 "NET START SNFService" SH_HIDE
          pop $0
          Goto FineToRunInstaller ; To be clean this needs to return zero also....

        NotStoppable:
        ## Wasn't running (Inconclusive) so we must test for SNFServer.exe and if so... tell them to manually stop the service/server first.
        SetOutPath $Temp
        ifFileExists "$Temp\SNFCLient.exe" +2 0
          File "SNFClient.exe"
        nsExec::Exec /TIMEOUT=1500 "$Temp\SNFClient.exe -status.second" SH_HIDE
          pop $0
          StrCmp $0 "0" 0 +3
            MessageBox MB_OK "SNFServer was detected running on this system.  You must stop the SNFServer in order to run this installer."
            Quit
          Delete "$Temp/SNFClient.exe"
        SetOutPath $INSTDIR
        
        
FineToRunInstaller:
  ; Ensure the utility manager only has one instance running at a time.
  System::Call 'kernel32::CreateMutexA(i 0, i 0, t "Sniffer Untility Mng") i .r1 ?e'
  Pop $R0
  StrCmp $R0 0 +3
  MessageBox MB_OK|MB_ICONEXCLAMATION "The Message Sniffer Utility Manager is already running."
  Abort


  InitPluginsDir  ; this is needed in order to use the plugins dir for the splash pictures.......
  SetOutPath "$PLUGINSDIR" ; set the folder for unpacking the pictures...
  ;  Modal banner sample: show
    File "SnifferSplash.bmp"
    newadvsplash::show 3000 100 500 0x04025C  "$PLUGINSDIR\SnifferSplash.bmp"
    Sleep 1000 ; optional
    Delete "$PLUGINSDIR\SnifferSplash.bmp"
  ; Ok, enough gratuitous logo flashing... get to work....

  ; Reset these vars for the FindApplication screen that may or maynot be used.
  StrCpy $MissingApplicationName "" ; if we use the find page, this is the name of what we're looking for. It'll show up on the title and label.
  StrCpy $FindApplicationMessage "" ; if you want to customize the message you do that here.  Set to blank for default.
  StrCpy $MissingApplicationFolder "" ; if you have a starting point, stick it here... otherwise leave it blank.
  StrCpy $Find_Explanation_INFO ""    ; if you want a verbose instruction put it here.

  
  ; Preset other navigation flow flags.
  StrCpy $ArchivesAvailable "0"  ; Defaulting to no, but will hold if there is an SNFArchives folder....
  StrCpy $ShowRestoreOptionsPage "0"   ; Default is true, unless proven otherwise, by no archives folder.
  StrCpy $HandleUninstallPage "0"      ; Execute the uninstall page is set to no by default, unless user selects the uninstall path on the 2nd Components page.
  StrCpy $ShowTelemetryPage "0"        ; Default is to ignore the status page.
  
  ; Preset installation flags;
  StrCpy $PreviousSnifferInstalled "0" ; Until proven otherwise, there is no previously installed sniffer engine.
  StrCpy $MessageSnifferRestoreDir ""  ; Fresh Install until restore archive is selected.
  StrCpy $OldVersionOfSniffer "0"      ; This is used to flag if we're dealing with the first install after an old sniffer folder.

  StrCpy $currentPlatformSelection "55" ; default the option for the PlatformSelection to the Unknown Server install.
  StrCpy $currentUtilitySelection  "0"  ; default the utility to NEW
  StrCpy $Set_For_MINIMI_INSTALL   "0"  ; default the utilitn to not installing MINIMI
  StrCpy $Set_For_SNF4Alligate_INSTALL   "0"  ; default the utilitn to not installing MINIMI
  ; This will set the flags for what is displayable in the 1st components screen.. ( Platforms... ) Based on what they select there,
  ; the exit function will determine and set the "INSTDIR...." and the Archives flags....
  Call DetermineInstallationPlatforms ; This will determine what installations are available for display.
  ; Obviously not all recognized email platforms will be displayed if they're not installed....
  ; At this point, the above call nas determined
FunctionEnd

############################################
##  This function attempts to make the best guess of the available known platforms, and checks the one on the screen that makes the most sense.
############################################
Function setBestPlatformGuess


FunctionEnd




#########################
## setupPlatforms is called prior to the display of the first custom page. 
## This will check and setup the flags for the available items, and set the selected ones.
## This was important to have in its own function and not in the init because of BACK... it was remembering the selection, and
## not obeying the single selection option handler.  So we had to reinit the page each time before its viewed.
Function setupPlatforms
    ; This gets run if we want to show Install Platforms, not utilities.  We change the title and the image but we use the same components screen.
     SendMessage $HWNDPARENT ${WM_SETTEXT} 0 "STR:Message Sniffer Platform Selection:"
     !insertmacro BIMAGE "SnifferBanner.bmp" ""

     SendMessage $HWNDPARENT ${WM_SETTEXT} 0 "STR:Message Sniffer Server 3.0 Install Utility:"
     !insertmacro BIMAGE "SnifferBanner.bmp" ""


     Call ResetSectionNames ; This puts ALL the names back...

       StrCpy $BaseRadioDefault $currentPlatformSelection ; This sets the platform default and seeds the onSelectChange macro selection.
                                                          ; onInit sets first one to 11 - SNFStandalone
;
        ; Make sure nothing that is being hidden is selected... this creates null-ignored clicks and wierd user interaction.
        ; because of the modality of the radio buttons... ( even though not all options are being displayed, they're all there 1 - 12 of them
        !insertmacro UnselectSection ${g1o1} ; none of the chekcboxes should be checked.
        !insertmacro UnselectSection ${g1o2}
        !insertmacro UnselectSection ${g1o3}
        !insertmacro UnselectSection ${g1o4}
        !insertmacro UnselectSection ${g1o5}
        !insertmacro UnselectSection ${g1o6}

        ; This was added after the order of the rest... and so I'm wondering if its essential to keep it in order for the sake of the
        ; platform references.
        !insertmacro UnselectSection ${g1o6B} ; because this will be index 13..... so it must come after g1oC which is 12....
        
        ;Of course, don't display install options on platform screen
        SectionSetText  ${g1o1} ""
        SectionSetText  ${g1o2} ""
        SectionSetText  ${g1o3} ""
        SectionSetText  ${g1o4} ""
        SectionSetText  ${g1o5} ""
        SectionSetText  ${g1o6} ""
        SectionSetText  ${g1o6B} ""

             StrCmp $SelectedCaseIndexForPlatformScreen "0" 0 LeaveEnabled
             ;if We haven't been to this screen before, the case flag will be zero.  And we leave teh Next button disabled.... otherwise we leave it enabled:
             ; Disable the next button until selection is made.
             Var /GLOBAL NextButton
             GetDlgItem $NextButton $HWNDPARENT 1
             EnableWindow $NextButton "0"
        LeaveEnabled:
        
        #################################################################################
        ; NOTE: THE UNKNOWN DECLUDE OPTION WAS HIDDEN AND DEPRECATED.....
        Var /GLOBAL testUnknownDeclude ; Use this to flag if we intend to use the unknownDeclude option
             StrCpy $testUnknownDeclude "1"  ; The only time we don't-test is if we can identify WHICH declude
             ; So for the first time through....in addition to disabling the next button, we can just breeze through clearly the checkboxes.
             ; First off: Show the platform options.
        #################################################################################

       ## ADDINGPLATFORM ## STEP 15  This is the platforms setup screen.  We need to have the new platform be available for selection, so we do that
       ## by adding it to the UnselectedSection list with the macros.  If you use SectionSetText #NAME "" you are clearing the name, and it won't
       ## show up in the displayed list.  To have it show up as unselected, add the UnselectedSectionLine.  ( You could add it selected too.. but
       ## that gets annoying for a variety of reasons, so we default to everything off. Remember to keep it in the right list order. )
        
       ; We'll always show these options...
       ; the new paradigm is to show, and then attempt to check the intended one, and then alter the paths after the fact.....
        !insertmacro UnselectSection   ${gIWDI} ; g1o7
        !insertmacro UnselectSection   ${gIMXI} ; g1oA
        !insertmacro UnselectSection   ${gIMMI} ; g1o7B
        !insertmacro UnselectSection   ${gSWDI} ; g1o8
        !insertmacro UnselectSection   ${gSMXI} ; g1oA2
        !insertmacro UnselectSection   ${gAWDI} ; g1o9
        SectionSetText ${gSNFI} ""  ; not using this feature yt.
        #!insertmacro UnselectSection   ${gSNFI} ; g1oB
        SectionSetText ${gUSWDI} ""  ; !insertmacro UnselectSection   ${gUSWDI} ; g1oC
        !insertmacro UnselectSection    ${gIWTI}    ; Icewarp AS AV
        !insertmacro UnselectSection    ${gIWTICF}  ; "IceWarp as Content-Filter (y/n)"
        !insertmacro UnselectSection    ${gIWTICF2} ; as Spam Score Contributer
        #!insertmacro UnselectSection    ${gMSI} ; MailSite
        SectionSetText ${gMSI} ""
        #!insertmacro UnselectSection    ${gKMI} ; Kerio Mail Server
        SectionSetText ${gKMI} ""
        !insertmacro UnselectSection    ${gMDDLL} ; MDaemon Dll option.
        !insertmacro UnselectSection    ${gCUKC} ; custom unknown combination
        
  ; NOTE: ALl clears need to go ahead of the switch, cause we exit immediately after we've found a selection that was set.
  ;       - this would indicate a back event... (if $SelectedCaseIndexForPlatformScreen was set).......


       ## ADDINGPLATFORM ## STEP 16  Add your newe platform in this switch statement in order to properly key on a preexisting selection,
       ## if the user moves back a screen in the installer.  Remember to stay in order as a form of habit. Keep the same form.  Change the case text
       ## key as well as the keyname in brackets ${ THIS }

          ; But if we HAVE one selected, we need to case through them, and only clear the ones that aren't selected:

          ${Switch} $SelectedCaseIndexForPlatformScreen
            ${Case} "gIWDI"
                !insertmacro SelectSection   ${gIWDI} ; g1o7
                Return
            ${Case} "gIMXI"
                !insertmacro SelectSection   ${gIMXI} ; g1oA
                Return
            ${Case} "gIMMI"
                !insertmacro SelectSection   ${gIMMI} ; g1o7B
                Return
            ${Case} "gSWDI"
                !insertmacro SelectSection   ${gSWDI} ; g1o8
                Return
            ${Case} "gSMXI"
                !insertmacro SelectSection   ${gSMXI} ; g1oA2
                Return
            ${Case} "gAWDI" 
                !insertmacro SelectSection   ${gAWDI} ; g1o9
                Return
            ${Case} "gIWTI"
                !insertmacro SelectSection   ${gIWTI} ; Icewarp as AV position
                Return
            ${Case} "gIWTICF"
                !insertmacro SelectSection   ${gIWTICF} ; Icewarp as content filter
                Return
            ${Case} "gIWTICF2"
                !insertmacro SelectSection   ${gIWTICF2} ; Icewarp as spam score contributer
                Return
            ${Case} "gMSI"
                #!insertmacro SelectSection   ${gMSI} ; MailSite
                Return
            ${Case} "gKMI"
                !insertmacro SelectSection   ${gKMI} ; Kerio Mail
                Return
            ${Case} "gMDDLL"
                !insertmacro SelectSection   ${gMDDLL} ; MDaemon Mail
                Return
            ${Case} "gSNFI" ; NOT USEING THIS OPTION
                 !insertmacro UnselectSection   ${gSNFI} ; g1o9
                #!insertmacro SelectSection   ${gSNFI} ; g1oB
                Return
            ${Case} "gUSWDI" ; NOT USEING THIS OPTION
                !insertmacro SelectSection   ${gUSWDI} ; g1oC
                Return
            ${Case} "gCUKC"
                !insertmacro SelectSection   ${gCUKC} ; 
                Return
           ${Default}
      ; If we get here, we have an unusual situation that leaks through.  Don't let them through without a selection being defined.
                EnableWindow $NextButton "0"
          ${EndSwitch}
          
           ; IF we were here, then we skipped through the switch, and didn't take.  That means that there wasn't a remembered setting... and we
           ; need to make our best attempt at a guess.
           ; here would be where we  need to have made our best guess as to the install that seems to make the most sense:
           call setBestPlatformGuess

FunctionEnd







#########################
## setupComponents2 is called prior to the display of the components page.  It will setup the empty or the unselected lists.
## This was important to have in its own function and not in the init because of BACK... it was remembering the selection, and
## not obeying the single selection option handler.  So we had to reinit the page each time before its viewed.
Function setupComponents2

     ;Var /GLOBAL NextButton
     SendMessage $HWNDPARENT ${WM_SETTEXT} 0 "STR:Message Sniffer Server 3.0 Install Utility:"
     !insertmacro BIMAGE "SnifferBanner.bmp" ""

     ; Disable the next button until selection is made.
     GetDlgItem $NextButton $HWNDPARENT 1
     EnableWindow $NextButton "0"

     ; We need to set the default radio button for the Utilities component view of the sections options now..
     StrCpy $BaseRadioDefault $currentUtilitySelection ; This sets the platform default onIniti starts it on NEW but we may change that further down.....


     Call ResetSectionNames ; This puts ALL the names back...

        ## ADDINGPLATFORM ## STEP 13 Add your platform here, as an Unselected Section Call.  ( To clear it from being selected. )
        ## There is only one section list, but we screen it differently for the activities vs the platforms.
        ## This is the first time, you see the ordinal commented.  Remember to keep the order,
        ## increment any ordinals below your new one, and notice the point that you need to bump them all down for later, in the case element.

        ; this makes sure there isn't anything selected thats hiding...
        !insertmacro UnselectSection ${g1o1} ; none of the chekcboxes should be checked. 0
        !insertmacro UnselectSection ${g1o2} ; none of the chekcboxes should be checked. 1
        !insertmacro UnselectSection ${g1o3} ; none of the chekcboxes should be checked. 2
        !insertmacro UnselectSection ${g1o4} ; none of the chekcboxes should be checked. 3
        !insertmacro UnselectSection ${g1o5} ; none of the chekcboxes should be checked. 4
        !insertmacro UnselectSection ${g1o6} ; none of the chekcboxes should be checked. 5
        !insertmacro UnselectSection ${g1o6B} ; none of the chekcboxes should be checked. - This is status index 13 6
        !insertmacro UnselectSection   ${gIW}
        !insertmacro UnselectSection   ${gIWDI} ; g1o7 #7 is Imail with Declude
        !insertmacro UnselectSection   ${gIMXI} ; g1oA #8 is Imail with MXGuard
        !insertmacro UnselectSection   ${gIMMI} ; g1o7B #9 is IMail with MINIMI
        !insertmacro UnselectSection   ${gSWDI} ; g1o8  #10 is SmarterMail with Declude
        !insertmacro UnselectSection   ${gSMXI} ; g1oA2 #11 is SmarterMail with MXGuard
        !insertmacro UnselectSection   ${gAWDI} ; g1o9  #12 is Alligate
                                               ; 13 is the SectionGroup
        !insertmacro UnselectSection   ${gIWTI} ; g1o9  #14 is Icewarp as AV position
        !insertmacro UnselectSection   ${gIWTICF} ; g1o9  #15 is Icewarp as content filter
        !insertmacro UnselectSection   ${gIWTICF2} ; g1o9  #16 is Icewarp as Spam Score contributer
        !insertmacro  UnselectSection  ${gMSI} ; g1o9  #18 is MailSite

        !insertmacro UnselectSection   ${gKMI} ; g1o9  #19 is Kerio
        !insertmacro UnselectSection   ${gMDDLL} ; MDaemon Install  #20 is SNF stand alone
        !insertmacro UnselectSection   ${gSNFI} ; g1oB  #21 is SNF stand alone
        !insertmacro UnselectSection   ${gUSWDI} ; g1oC #22 is Unknown Server with Declude
        !insertmacro UnselectSection   ${gCUKC} ;       #23 is Custom Unknown

        ## ADDINGPLATFORM ## STEP 14 Now set it not to display on the activities screen.

       ; First off: Hide the platform options because wer'e only showing components.
        SectionSetText  ${gIWDI} "" ; Imail with declude
        SectionSetText  ${gIMXI} "" ; Imail MXGuard
        SectionSetText  ${gIMMI} "" ; IMail w/ MINIMI
        SectionSetText  ${gSWDI} "" ; SmarterMail with Declude
        SectionSetText  ${gSMXI} "" ; SmarterMail with MXGuard
        SectionSetText  ${gAWDI} "" ; Nonused alligate option
        SectionSetText  ${gIW} ""
        SectionSetText  ${gIWTI} "" ;  is Icewarp in AV position
        SectionSetText  ${gIWTICF} "" ;  is Icewarp as Content Filter
        SectionSetText  ${gIWTICF2} "" ;  is Icewarp as spam score contributer
        SectionSetText  ${gMSI} "" ;  is MailSite
        SectionSetText  ${gKMI} "" ;   is Kerio
        SectionSetText  ${gMDDLL} "" ;   is Kerio
        SectionSetText  ${gSNFI} "" ; Nonused Sniffer standing alone somewhere..
        SectionSetText  ${gUSWDI}  ""  ; Unknown server w/ Declude
        SectionSetText  ${gCUKC} ""    ; Custom unknown

    ; Now we have two situations.  The first was if there was no preexisting sniffer folder Thats easy.
    StrCmp $PreviousSnifferInstalled "0"   RunFreshInstaller RunChoices
    RunFreshInstaller:
        StrCmp $ArchivesAvailable "0" RunFreshNoRestore RunWithRestore
      RunFreshNoRestore:
        ; Setup the settings options for a fresh install:
        !insertmacro UnselectSection ${g1o1} ; none of the chekcboxes should be checked.
        SectionSetText  ${g1o2} ""
        SectionSetText  ${g1o3} ""
        SectionSetText  ${g1o4} ""
        SectionSetText  ${g1o5} ""
        SectionSetText  ${g1o6} ""
        SectionSetText  ${g1o6B} "" ; obviously no status either.
        Return
     RunWithRestore:  ; Now we're restoring to the previous state before EVERY install..... this is moot.
        ; Setup the settings options for a fresh install:
        !insertmacro UnselectSection ${g1o1}
        SectionSetText  ${g1o2} ""
        SectionSetText  ${g1o3} ""
        SectionSetText  ${g1o4} ""
        SectionSetText  ${g1o5} "" ; used to be when you had the option for restore....
        SectionSetText  ${g1o6} ""
        SectionSetText  ${g1o6B} "" ; obviously still no status either.

        Return
   RunChoices:
      ; So we're going to allow the Utility Manager to offer the choices of what sniffer engine to use.
      ; Setup the settings options for a fresh install:
      ;!insertmacro UnselectSection ${another_section_id}
        SectionSetText ${g1o1} ""
        !insertmacro UnselectSection ${g1o2} ; none of the chekcboxes should be checked.
        !insertmacro UnselectSection ${g1o3}
        SectionSetText  ${g1o4} "" ; used to be when you had the option for archive UnselectSection ${g1o4}
        SectionSetText  ${g1o5} "" ; used to be when you had the option for restore....
        !insertmacro UnselectSection ${g1o6}


        #ReadRegStr $0 HKLM "Software\MessageSniffer" "Install_Dir" ; "SRS_RollbackPath"
        #  ifErrors HideUninstaller AllowUninstaller  ; So only on the condition that an installer hasn't run, do we consider blocking.
        #    AllowUninstaller:
        #     !insertmacro UnselectSection ${g1o6}
        ##       Goto NextItem
        #    HideUninstaller:
        #      SectionSetText  ${g1o6} ""

        NextItem:
        !insertmacro UnselectSection ${g1o6B} ; now we can have status

     ; So we DO need to set the default radio button for the Utilities to FRESH not NEW
     StrCpy $BaseRadioDefault "1" ; This sets the platform default to new but we may change that further down.....

  Return
FunctionEnd



Function Components2_Leave
  ; Ok, we need to install MINIMI here, if its a valid installation, but if its just utilities then we don't.
    StrCmp $ShowRestoreOptionsPage "1" 0 +4
      ; Might as well handle this here.  We dont' need another page.
      MessageBox MB_OK "Attempting to Restore.  This code should be stubbed."
      ;ExecWait "Restorer.exe -R"
      Quit
      return ; If 4 was selected, we dont' install
    StrCmp $ShowArchiveOptionsPage "1" 0 +2
      return ; If 4 was selected, we dont' install
    StrCmp $ShowTelemetryPage "1" 0 +2
      return ; If 4 was selected, we dont' install
    StrCmp $HandleUninstallPage "1" 0 +2
      return ; If 4 was selected, we dont' install

  StrCmp $Set_For_MINIMI_INSTALL "1" 0 done
    StrCmp $SelectedCaseIndexForPlatformScreen "gIMMI" 0 done
      call InstallMINIMI
  done:

    StrCmp $Set_For_SNF4Alligate_INSTALL "1" 0 done2
    StrCmp $SelectedCaseIndexForPlatformScreen "gAWDI" 0 done2
      call InstallSNF4Alligate
  done2:

    return
FunctionEnd



Function setupINSTALLDIR
## NOTE This call was moved to the back of the file lookup screen.  that is to say that this is now the validation screen for the
## Find files page...... before you reset and mark all the features.... you need to revalidate the text boxes....
var /Global temp1 ; holds the strings from the lookup text boxes.
var /Global temp2

  ## ADDINGPLATFORM ## STEP 17  This is the biggie.  Here you need to add a complex case block to handle the popups of the specific platfomr,
  ## to find the necessary folders, and to set the install folders for both the platform, as well as where Sniffer is going to be installed.
  ## Remember to keep the order.  The requires customizing the itFileExists test to beable to confirm that the expected dependant file,
  ## is indeed where the installer expects to find it.  If it isn't there, it won't progress until the user locates the proper folder.
  ## These cases start their search where the respective platform install folders are set to look by DetermineXYZPLatform...


${Switch} $SelectedCaseIndexForPlatformScreen

 ${Case} "gIWDI" ; zero indexed array... Imail with Declude gIWDI
   ;; So this becomes a declude test....

   	${NSD_GetText} $SNF_SearchFor_Location $R0
        StrCpy  $temp1 $R0 ; Set the global variable to the new authentication ID.
   ifFileExists "$temp1\global.cfg" +3 0 ; skip or notify then leave....
      MessageBox MB_OK "Please select the location path where decludes global.cfg file exists."
      Goto NoPassFromHere
   ; and make sure the user didn't edit the string....
   ${NSD_GetText} $SNF_SearchFor_LocationB $R0
   StrCpy  $temp2 $R0 ; Set the global variable to the new authentication ID.
   StrCmp $temp2 "" 0 +3 ; skip or notify then leave....
      MessageBox MB_OK "You must define a folder as the install directory."
      Goto NoPassFromHere
   ;ok well override those settings if they're good.....
   ; be sure it exists.
   ifFileExists "$temp2\*.*" +2 0
     CreateDirectory $temp2
   ; set them p.
   StrCpy $SNFServerInstallDir $temp1
   StrCpy $INSTDIR $temp2
   
   Goto ProceedWithInstallDirSetup ;

  ${Case} "gIMXI"
        # Handle MXGuard check...
   	${NSD_GetText} $SNF_SearchFor_Location $R0
        StrCpy  $temp1 $R0 ; Set the global variable to the new authentication ID.
           ifFileExists "$temp1\mxguard.ini" +3 0 ; skip or notify then leave....
              MessageBox MB_OK "Please select the location path where the mxguard.ini file exists."
              Goto NoPassFromHere
           ; and make sure the user didn't edit the string....
           ${NSD_GetText} $SNF_SearchFor_LocationB $R0
           StrCpy  $temp2 $R0 ; Set the global variable to the new authentication ID.
           StrCmp $temp2 "" 0 +3 ; skip or notify then leave....
              MessageBox MB_OK "You must define a folder as the install directory."
              Goto NoPassFromHere
           ; ok well override those settings if they're good.....
           ; be sure it exists.
           ifFileExists "$temp2\*.*" +2 0
             CreateDirectory $temp2
           ; set them p.
           StrCpy $SNFServerInstallDir $temp1
           StrCpy $INSTDIR $temp2

    Goto ProceedWithInstallDirSetup ;

  ${Case} "gIMMI"
        # Handle MINIMI check...
   	${NSD_GetText} $SNF_SearchFor_Location $R0
        StrCpy  $temp1 $R0 ; Set the global variable to the new authentication ID.
           ifFileExists "$temp1\SMTP32.EXE" +3 0 ; skip or notify then leave....
              MessageBox MB_OK "Please select the location path where IMails SMTP32.exe resides."
              Goto NoPassFromHere
           ; and make sure the user didn't edit the string....
           ${NSD_GetText} $SNF_SearchFor_LocationB $R0
           StrCpy  $temp2 $R0 ; Set the global variable to the new authentication ID.
           StrCmp $temp2 "" 0 +3 ; skip or notify then leave....
              MessageBox MB_OK "You must define a folder as the install directory."
              Goto NoPassFromHere
           ; ok well override those settings if they're good.....
           ; be sure it exists.
           ifFileExists "$temp2\*.*" +2 0
             CreateDirectory $temp2
           ; set them p.
           StrCpy $SNFServerInstallDir $temp1
           StrCpy $INSTDIR $temp2

    Goto ProceedWithInstallDirSetup ;

  ${Case} "gSWDI" ; zero indexed array... Smartermail with Declude
   ; So this becomes a declude test....

   	${NSD_GetText} $SNF_SearchFor_Location $R0
        StrCpy  $temp1 $R0 ; Set the global variable to the new authentication ID.
   ifFileExists "$temp1\global.cfg" +3 0 ; skip or notify then leave....
      MessageBox MB_OK "Please select the location path where decludes global.cfg file exists."
      Goto NoPassFromHere
   ; and make sure the user didn't edit the string....
   ${NSD_GetText} $SNF_SearchFor_LocationB $R0
   StrCpy  $temp2 $R0 ; Set the global variable to the new authentication ID.
   StrCmp $temp2 "" 0 +3 ; skip or notify then leave....
      MessageBox MB_OK "You must define a folder as the install directory."
      Goto NoPassFromHere
   ;ok well override those settings if they're good.....
   ; be sure it exists.
   ifFileExists "$temp2\*.*" +2 0
     CreateDirectory $temp2
   ; set them p.
   StrCpy $SNFServerInstallDir $temp1
   StrCpy $INSTDIR $temp2
   
   Goto ProceedWithInstallDirSetup ;

  ${Case} "gSMXI"
      # Handle MXGuard check...
   	${NSD_GetText} $SNF_SearchFor_Location $R0
        StrCpy  $temp1 $R0 ; Set the global variable to the new authentication ID.
           ifFileExists "$temp1\mxguard.ini" +3 0 ; skip or notify then leave....
              MessageBox MB_OK "Please select the location path where the mxguard.ini file exists."
              Goto NoPassFromHere
           ; and make sure the user didn't edit the string....
           ${NSD_GetText} $SNF_SearchFor_LocationB $R0
           StrCpy  $temp2 $R0 ; Set the global variable to the new authentication ID.
           StrCmp $temp2 "" 0 +3 ; skip or notify then leave....
              MessageBox MB_OK "You must define a folder as the install directory."
              Goto NoPassFromHere
           ; ok well override those settings if they're good.....
           ; be sure it exists.
           ifFileExists "$temp2\*.*" +2 0
             CreateDirectory $temp2
           ; set them p.
           StrCpy $SNFServerInstallDir $temp1
           StrCpy $INSTDIR $temp2

      Goto ProceedWithInstallDirSetup ;

  ${Case} "gAWDI"
     # Handle SNF4Alligate check...
   	${NSD_GetText} $SNF_SearchFor_Location $R0
        StrCpy  $temp1 $R0 ; Set the global variable to the new authentication ID.
           ifFileExists "$temp1\AGFiltSvc.exe" +3 0 ; skip or notify then leave....
              MessageBox MB_OK "Please select the location path where Alligates AGFiltSvc.exe resides."
              Goto NoPassFromHere
           ifFileExists "$temp1\Drop" +3 0 ; skip or notify then leave....
              MessageBox MB_OK "There is no Drop folder in your Alligate location."
              Goto NoPassFromHere
           ifFileExists "$temp1\Drop" +3 0 ; skip or notify then leave....
              MessageBox MB_OK "There is no Spool folder in your Alligate location."
              Goto NoPassFromHere

           ; and make sure the user didn't edit the string....
           ${NSD_GetText} $SNF_SearchFor_LocationB $R0
           StrCpy  $temp2 $R0 ; Set the global variable to the new authentication ID.
           StrCmp $temp2 "" 0 +3 ; skip or notify then leave....
              MessageBox MB_OK "You must define a folder as the install directory."
              Goto NoPassFromHere
           ; ok well override those settings if they're good.....
           ; be sure it exists.
           ifFileExists "$temp2\*.*" +2 0
             CreateDirectory $temp2
           ; set them p.
           StrCpy $SNFServerInstallDir $temp1
           StrCpy $INSTDIR $temp2

    Goto ProceedWithInstallDirSetup ;
  ${Case} "gIWTICF"  ; let this drop through
  ${Case} "gIWTICF2" ; let this drop through
  ${Case} "gIWTI"
     # Handle Icewarp check...
   	${NSD_GetText} $SNF_SearchFor_Location $R0
        StrCpy  $temp1 $R0 ; Set the global variable to the new authentication ID.
          ifFileExists "$temp1\config\*.*" 0 NoPassFromHere ; shouldn't happen.. determine Icewarp should fail if not properly installed.
           ifFileExists "$temp1\config\content.xml" +3 0 ; skip or notify then leave....
              MessageBox MB_OK "Please select the location path where IceWarp is installed.  [IceWarpRoot]\config\content.xml couldn't be found."
              Goto NoPassFromHere
           ; and make sure the user didn't edit the string....
           ${NSD_GetText} $SNF_SearchFor_LocationB $R0
           StrCpy  $temp2 $R0 ; Set the global variable to the new authentication ID.
           StrCmp $temp2 "" 0 +3 ; skip or notify then leave....
              MessageBox MB_OK "You must define a folder as the install directory."
              Goto NoPassFromHere
           ; ok well override those settings if they're good.....
           ; be sure it exists.
           ifFileExists "$temp2\*.*" +2 0
             CreateDirectory $temp2
           ; set them p.
           StrCpy $SNFServerInstallDir $temp1
           StrCpy $INSTDIR $temp2

    Goto ProceedWithInstallDirSetup ;
  ${Case} "gMSI"
     ## WONT HAPPEN
  ${Case} "gKMI"
     ## WONT HAPPEN
  ${Case} "gMDDLL"
     # Handle MDaemon check...
   	${NSD_GetText} $SNF_SearchFor_Location $R0
        StrCpy  $temp1 $R0 ; Set the global variable to the new authentication ID.
          ifFileExists "$temp1\App\*.*" 0 NoPassFromHere ; shouldn't happen.. determine Icewarp should fail if not properly installed.
           ifFileExists "$temp1\App\MDaemon.exe" +3 0 ; skip or notify then leave....
              MessageBox MB_OK "Please select the location path where MDaemon is installed.  [MDaemon]\App\MDaemon.exe couldn't be found."
              Goto NoPassFromHere
           ; and make sure the user didn't edit the string....
           ${NSD_GetText} $SNF_SearchFor_LocationB $R0
           StrCpy  $temp2 $R0 ; Set the global variable to the new authentication ID.
           StrCmp $temp2 "" 0 +3 ; skip or notify then leave....
              MessageBox MB_OK "You must define a folder as the install directory."
              Goto NoPassFromHere
           ; ok well override those settings if they're good.....
           ; be sure it exists.
           ifFileExists "$temp2\*.*" +2 0
             CreateDirectory $temp2
           ; set them p.
           StrCpy $SNFServerInstallDir $temp1
           StrCpy $INSTDIR $temp2

    Goto ProceedWithInstallDirSetup ;
     
     
  ${Case} "gSNFI"
     ## WONT HAPPEN
  ${Case} "gUSWDI"
    ## WONT HAPPEN
      ;StrCpy $Find_Explanation_INFO "You have chosen to install Sniffer in an identified Declude install.  You will need to confirm the location of the following items:"
      ;StrCpy $MissingApplicationName "Generic Declude Install"
      ;Goto ProceedWithInstallDirSetup ;

  ${Case} "gCUKC"
           ${NSD_GetText} $SNF_SearchFor_LocationB $R0
           StrCpy  $temp2 $R0 ; Set the global variable to the new authentication ID.
           StrCmp $temp2 "" 0 +3 ; skip or notify then leave....
              MessageBox MB_OK "You must define a folder as the install directory."
              Goto NoPassFromHere
           ; ok well override those settings if they're good.....
           ; be sure it exists.
           ifFileExists "$temp2\*.*" +2 0
             CreateDirectory $temp2
           ; set them p.
           ${GetParent} $temp2 $SNFServerInstallDir ; get the parent of the selected folder and mark it as the master server dir.
           StrCpy $INSTDIR $temp2

      Goto ProceedWithInstallDirSetup ;
  ${Default}
      ; If we get here, we have an unusual situation that leaks through teh event handler.
      ; Though its not possible, you can unclick a radio button that should always have one selected.
      ; and put yourself in the original state of having nothing picked... if so, disable next.
        EnableWindow $NextButton "0"
  ${EndSwitch}

   NoPassFromHere: ; this cancels the next because it didn't validate.
     abort

   ProceedWithInstallDirSetup:
     ; ok we're good... here we have defined the INSDIR and the $SNFServerInstallDir

## NOTE: Even though it would seem that there could be multiple Declude folders because they only use one set of registry keys
##       There can't be multiple FUNCTIONING decludes. So don't get confused even though SNF is going to remain abtracted....
StrCpy $OldVersionOfSniffer "0"
StrCpy $PreviousSnifferInstalled "0"
StrCpy $ArchivesAvailable "0"
  ; So test to see if the message sniffer folder exists.
  IfFileExists "$INSTDIR\identity.xml" SetPreviouslyInstalledFlag 0  ; Test for no folder at proper location.
    StrCpy $PreviousSnifferInstalled "0"                             ; we key off the identity.xml file.
                                                                     ; Set previous flag to false. ( default. , but kept here for clarity. )
    Goto ContinueInit ; Skip setting the previous flag to true.....
  SetPreviouslyInstalledFlag:
    IfFileExists "$INSTDIR\$LicenseID.exe" 0 +2 ; Test for older install file keying off of nomerization of the executable.....
      StrCpy $OldVersionOfSniffer "1"                                        ; ( Declude comes with its own sniffer folder already made....
    StrCpy $PreviousSnifferInstalled "1"         ; Set flag for previously exists.
  ContinueInit:
  
    ## ARCHIVE NOTE:  We are no longer offering archives, so we are hiding this code at the moment.  ARCHIVES ARE NEVER AVAILABLE.
    #IfFileExists "$SNFServerInstallDir\SNFArchive\*.*" 0 +2
      StrCpy $ArchivesAvailable "0"  ; This sets the state for the modified option set to offer restore possibilities....
      ; Lastly, since we don't want to redo all this activity when we finally DO get to the archiver or the installer..... we need to put a local file
      ; in the root directory where the Archiver.exe or the Restorer.exe is going to be to give it a local reference.  We could use a registry key
      ; but that limits us to one controlable archive..... if you turn off one installation and turn another on, this way it should heal itself.

    # This lets the internal installer program utilize all the sorting and sifting we did to determine the actual path of where to put the stuff.
    Call OutputLocalRootInfoFile
  RETURN
FunctionEnd

Function OutputLocalRootInfoFile
   ; Lastly, since we don't want to redo all this activity when we finally DO get to the archiver or the installer..... we need to put a local file
    ; in the root directory where the Archiver.exe or the Restorer.exe is going to be to give it a local reference.  We could use a registry key
    ; but that limits us to one controlable archive..... if you turn off one installation and turn another on, this way it should heal itself.
     SetOutPath $INSTDIR
          Var /GLOBAL myContextFile
          FileOpen $myContextFile "$INSTDIR\LocalRoot.txt" w
          FileWrite $myContextFile "<root>$SNFServerInstallDir</root><cd>$INSTDIR</cd>"
          FileClose $myContextFile
    ; NOTE: THis code is called in the SECTION area for FRESH install as well as ...setupINSTALLDIR because it needs to happen After the removal of the original folder.
    ; i.e. If you install Fresh the localroot.txt file is destroyed... so it needs to be rebuilt.
FunctionEnd





#####################################
## .onSelChange is the callback event handler
## for the components page.
Function .onSelChange
        ; Now Enable the Next Button
        GetDlgItem $NextButton $HWNDPARENT 1
        EnableWindow $NextButton "1"

        ; Radio Button State Checking code. Uncomment and run
        ;Var /GLOBAL TestVar
        ;StrCpy $TestVar ""
        ;SectionGetFlags "${g1o1}" $R0
        ;StrCpy $TestVar "g101:$R0$\n"
        ;SectionGetFlags "${g1o2}" $R0
        ;StrCpy $TestVar "$TestVar g102:$R0$\n"
        ;SectionGetFlags "${g1o3}" $R0
        ;StrCpy $TestVar "$TestVar g103:$R0$\n"
        ;SectionGetFlags "${g1o4}" $R0
        ;StrCpy $TestVar "$TestVar g104:$R0$\n"
        ;SectionGetFlags "${g1o5}" $R0
        ;StrCpy $TestVar "$TestVar g105:$R0$\n"
        ;SectionGetFlags "${g1o6}" $R0
        ;StrCpy $TestVar "$TestVar g106:$R0$\n"
        ;SectionGetFlags "${g1o7}" $R0
        ;StrCpy $TestVar "$TestVar g107:$R0$\n"
        ;SectionGetFlags "${g1o8}" $R0
        ;StrCpy $TestVar "$TestVar g108:$R0$\n"
        ;SectionGetFlags "${g1o9}" $R0
        ;StrCpy $TestVar "$TestVar g109:$R0$\n"
        ;SectionGetFlags "${g1oA}" $R0
        ;StrCpy $TestVar "$TestVar g10A:$R0$\n"
        ;SectionGetFlags "${g1oA2}" $R0
        ;StrCpy $TestVar "$TestVar g10A2:$R0$\n"
        ;SectionGetFlags "${g1oB}" $R0
        ;StrCpy $TestVar "$TestVar g10B:$R0$\n"
        ;SectionGetFlags "${g1oC}" $R0
        ;StrCpy $TestVar "$TestVar g10C:$R0$\n"
        ;MessageBox MB_OK $TestVar

        ; init $1
        ;MessageBox MB_OK "Current setting: $1 / $BaseRadioDefault"
        
        ; Problem:  When a group is present, clicking the group creates the abstract effect ( when using the RadioButton macros. ) that
        ;           the last item in the group that wasn't highlighted becomes checked.  Abberrant behavior.  So to counteract that we
        ;           screen for the effect of the user clicking on the group header, and clear all boxes prior to the rest of the analysis.
        ; This is going to flag if the group was selected by the user clickin on the header of the IceWarp Group.  We will then preempt that
        ; by clearing all the settings....
        Var /Global TheAddition
        Var /Global Report
        StrCpy $Report ""
        SectionGetFlags ${gIWTI} $TheAddition
        StrCpy $Report $Report$TheAddition
        SectionGetFlags ${gIWTICF} $TheAddition
        StrCpy $Report $Report$TheAddition
        SectionGetFlags ${gIWTICF2} $TheAddition
        StrCpy $Report $Report$TheAddition
        StrCmp $Report "111" 0 ContineButtonAnalysis
          !insertmacro UnselectSection ${gIWTI}
          !insertmacro UnselectSection ${gIWTICF}
          !insertmacro UnselectSection ${gIWTICF2}
        ContineButtonAnalysis:
        ; This concludes the manual clearing/correcting of the group state.
        
        ## ADDINGPLATFORM ## STEP 18 You must add the radiobutton detection code in here to detect the event and handle it.
        ## Add it in the proper place in order.  Increment the ordinal comments on everything below your entry.
        
        StrCpy $1 $BaseRadioDefault
          !insertmacro StartRadioButtons $1 ; Each of these is a macro that inserts handling code for the section named in ${g1o1}
            ; These are the components
            !insertmacro RadioButton ${g1o1} ; new
            !insertmacro RadioButton ${g1o2} ; fresh
            !insertmacro RadioButton ${g1o3} ; update
            !insertmacro RadioButton ${g1o4} ; archive
            !insertmacro RadioButton ${g1o5} ; restore
            !insertmacro RadioButton ${g1o6} ; uninstall
            !insertmacro RadioButton ${g1o6B}  ; status...
                                               ; and we add them in the order we're writing the code, not the display order ( handled in by the order we define the sections order )$\r$\n \
                ; these are teh platforms.
                !insertmacro RadioButton   ${gIWDI} ; g1o7 #7 is Imail with Declude
                !insertmacro RadioButton   ${gIMXI} ; g1oA #8 is Imail with MXGuard
                !insertmacro RadioButton   ${gIMMI} ; g1o7B #9 is IMail with MINIMI
                !insertmacro RadioButton   ${gSWDI} ; g1o8  #10 is SmarterMail with Declude
                !insertmacro RadioButton   ${gSMXI} ; g1oA2 #11 is SmarterMail with MXGuard
                !insertmacro RadioButton   ${gAWDI} ; g1o9  #12 is Alligate
                                              ; 13 is the Section Group
                ;MessageBox MB_OK "$1"
                !insertmacro RadioButton   ${gIWTI} ; g1o9  #14 is Icewarp
                ;MessageBox MB_OK "$1"
                !insertmacro RadioButton   ${gIWTICF} ; g1o9  #15 is Icewarp as content filter.
                ;MessageBox MB_OK "$1"
                !insertmacro RadioButton   ${gIWTICF2} ; g1o9  #16 is Icewarp as spam contributer.
                ;MessageBox MB_OK "$1"
                !insertmacro RadioButton   ${gMSI} ; g1o9  #18 is MailSite
                !insertmacro RadioButton   ${gKMI} ; g1o9  #19 is Kerio
                !insertmacro RadioButton   ${gMDDLL} ; g1o9  #20 is MDaemon
                !insertmacro RadioButton   ${gSNFI} ; g1oB  #21 is SNF stand alone
                !insertmacro RadioButton   ${gUSWDI} ; g1oC #22 is Unknown Server with Declude
                !insertmacro RadioButton   ${gCUKC} ;       #23 is Custom Unknown

            ; On inspecting the flag state for all options under a group, the result for when you select the group is
            ; 35 1 1 1 1 but when you select just a single option it is 98 0 0 0 1 for example....
            ;Var /Global TheState
            ;Var /Global TheAddition
            ;SectionGetFlags ${MDI} $TheAddition      ; but selecting it, mathematically selects ALL the options underneith... and that's not right.
            ;StrCpy $TheState "$TheState$\r$\n$TheAddition"
            ;SectionGetFlags ${MDI_mx} $TheAddition      ; but selecting it, mathematically selects ALL the options underneith... and that's not right.
            ;StrCpy $TheState "$TheState$\r$\n$TheAddition"
            ;SectionGetFlags ${MDI_dc} $TheAddition      ; but selecting it, mathematically selects ALL the options underneith... and that's not right.
            ;StrCpy $TheState "$TheState$\r$\n$TheAddition"
            ;SectionGetFlags ${MDI_mm} $TheAddition      ; but selecting it, mathematically selects ALL the options underneith... and that's not right.
            ;StrCpy $TheState "$TheState$\r$\n$TheAddition"
            ;SectionGetFlags ${MDI_sa} $TheAddition      ; but selecting it, mathematically selects ALL the options underneith... and that's not right.
            ;StrCpy $TheState "$TheState$\r$\n$TheAddition"
            ;MessageBox MB_OK "$TheState"

            ;!insertmacro RadioButton ${MDI}    ;"Manually Detect Installation" This is the group header.
            ;  StrCmp $1 "15" 0 NextRadioButton ; it needs to be in the list for presentation
            ; OK we're removing it from the list of Radiobutton macros cause we dont' ever want to have the group header be 'SET'
            ; but we need to trap and undo the selection of all its members.... so we check to see if its flag is set to 35 or 98.
            ; 98 indicates that something underneith it was selected, not the group header itself.  See SectionSetFlags for the bit values
            ; of the flags themselves..... but uncommentint the above code will popup the flag states at this point in the marco list....

            ; This was for handling a group... but we're not doing that... so we don't care...
            ; This setting checks, and if its 35 ( clicked it directly ) it will unset all its subcomponents, because they're mutually exclusive...
            ;SectionGetFlags ${MDI} $TempRadioButtonFlagsVar      ; but selecting it, mathematically selects ALL the options underneith... and that's not right.
            ;StrCmp $TempRadioButtonFlagsVar "35" 0 NextRadioButton
            ;  MessageBox MB_OK "Please click on the platform you'd like to manually locate:"
            ;  IntOp $TempRadioButtonFlagsVar $TempRadioButtonFlagsVar & ${SECTION_OFF} ; so even thoug we have it here, we have to UNdo the errant click on this option.
            ;  SectionSetFlags ${MDI} $TempRadioButtonFlagsVar
            ;NextRadioButton:
            ;MessageBox MB_OK "The value for 1 after the group header is : $1"
            ; EndTrappingButtons

       !insertmacro EndRadioButtons
    ; The Above code leaves var $1 holding the index of the radio button that was clicked.
       ;DEBUG MessageBox MB_OK "Now setting: $1 / $BaseRadioDefault"


    ## ADDINGPLATFORM ## STEP 19 You must add the command to clear all checkboxes.  We need to do this in order to manually control what gets displayed.
    ## the above code, saved the ordinal of what came back from the click event.  But when you have sub-elements, it requires manual handling of
    ## which option to activate in order to have the proper item or subitem show the check.  SO ENTER IN YOUR CLEAR LINE with your proper section name.
    ## Increment the ordinal in the comments for everything below your entry....

        ; Even though we've got the above macro... because we're using this list for two screens
        ; ( Forced on us because this function gets called from both pages on a select-Change event)
        ; We need to Case-control the display on entry to the first page based on a flag we store...
        ; because of that, the above macro isn't behaving nicely on the first click, so we need to
        ; manually control final state... so here we clear them all, and then we reselect the one
        ; that is notified as being clicked upon from the above code..... 
        !insertmacro UnselectSection ${g1o1} ; none of the chekcboxes should be checked. 0
        !insertmacro UnselectSection ${g1o2} ; none of the chekcboxes should be checked. 1
        !insertmacro UnselectSection ${g1o3} ; none of the chekcboxes should be checked. 2
        !insertmacro UnselectSection ${g1o4} ; none of the chekcboxes should be checked. 3
        !insertmacro UnselectSection ${g1o5} ; none of the chekcboxes should be checked. 4
        !insertmacro UnselectSection ${g1o6} ; none of the chekcboxes should be checked. 5
        !insertmacro UnselectSection ${g1o6B} ; none of the chekcboxes should be checked. - This is status index

        !insertmacro UnselectSection   ${gIWDI} ; g1o7 #7 is Imail with Declude
        !insertmacro UnselectSection   ${gIMXI} ; g1oA #8 is Imail with MXGuard
        !insertmacro UnselectSection   ${gIMMI} ; g1o7B #9 is IMail with MINIMI
        !insertmacro UnselectSection   ${gSWDI} ; g1o8  #10 is SmarterMail with Declude
        !insertmacro UnselectSection   ${gSMXI} ; g1oA2 #11 is SmarterMail with MXGuard
        !insertmacro UnselectSection   ${gAWDI} ; gAWDI  #12 is Alligate
                                           ; 13 is the Section Group.
        !insertmacro UnselectSection   ${gIWTI} ; gIWTI  #14 is Icewarp
        !insertmacro UnselectSection   ${gIWTICF} ; gIWTICF  #15 is Icewarp
        !insertmacro UnselectSection   ${gIWTICF2} ; gIWTICF2  #16 is Icewarp
        !insertmacro UnselectSection   ${gMSI} ; gMSI  #18 is MailSite
        !insertmacro UnselectSection   ${gKMI} ; gKMI  #19 is Kerio
        !insertmacro UnselectSection   ${gMDDLL} ; MDaemon  #20 is MDaemon
        !insertmacro UnselectSection   ${gSNFI} ; g1oB  #21 is SNF stand alone
        !insertmacro UnselectSection   ${gUSWDI} ; g1oC #22 is Unknown Server with Declude
        !insertmacro UnselectSection   ${gCUKC} ;       #23 is Custom Unknown

;MessageBox MB_OK "$1"
StrCpy $BaseRadioDefault $1 ; set this so that the next time through the click-handler it knows what to start with.
  ;MessageBox MB_OK "Click result is:$1"
  
  
    ## ADDINGPLATFORM ## STEP 20   OK!  This is the doosey!  Here is where the ordinal matters.  Cause the code above, grabbed the event, and it will
    ## comeback with master ordinal.  ( Not the ordinal of what was SHOWN in the list.) So even if you only displayed six items, the ordinal could come
    ## back with a 18.  The Switch below, is ENTIRELY BASED ON THAT ORDINAL... which is why, if don't bump all the case elements BELOW YOUR ENTRY
    ## you will end up with VERY STRANGE Event handling behavior.
    ## Insert a new case element, custom code the effect you desire, and then increment every number below your entry.
    ## Ignore the fact that 1 through 6 are at the very end, ( They are the returns for the activities.  New, Fresh, Update, Remove etc. )
    ## IF your install requires a custom call back you call that here.
    ## Do not remove the StrCy $currentPlatformSelection $1 line.  ( $1 is the register that returns the currently selected checkbox, and if you come back
    ## to this screen, the screen remember what was selected based on the value contained by $currentPlatformSelection
  
  ; Now based on the clicked selection mark it shown, and setup the proper flags.
  ${Switch} $1
    ${Case} "7" ; zero indexed array... Imail with Declude gIWDI
    StrCpy $SelectedCaseIndexForPlatformScreen "gIWDI"   ; Which is the first platform option....
    !insertmacro SelectSection ${gIWDI} ; check Declude with Imail.
    Call SetInstallForDeclude ; Set the install folder to put MessageSniffer in based on the Declude settings.
                              ; If Its declude, then its whatever declude is setup for.... i.e. Declude can't be both
                              ; IMail and Smartermail at the same time.... it will be one or the other.
                              ; StrCpy $INSTDIR
    StrCpy $currentPlatformSelection $1 ; set this so that the next time through the click-handler it knows what to start with.
     return ;
  ${Case} "8"
    StrCpy $SelectedCaseIndexForPlatformScreen "gIMXI"
    !insertmacro SelectSection ${gIMXI} ; MXGuard with Imail
    Call SetInstallForMXGuard
    StrCpy $currentPlatformSelection $1
    return
    
  ${Case} "9"
    StrCpy $SelectedCaseIndexForPlatformScreen "gIMMI" ; this marker is for the presetting the platforms screen on back event
    !insertmacro SelectSection ${gIMMI} ; MINIMI with IMAIL
    Call SetInstallForMINIMI
    StrCpy $currentPlatformSelection $1 ; this marker is for remembering what was checked....
    return

  ${Case} "10"
    StrCpy $SelectedCaseIndexForPlatformScreen "gSWDI"
    !insertmacro SelectSection ${gSWDI} ; check Declude with Smartermail
    Call SetInstallForDeclude ; Set the install folder to put MessageSniffer in based on the Declude settings.
                              ; If Its declude, then its whatever declude is setup for.... i.e. Declude can't be both
                              ; IMail and Smartermail at the same time.... it will be one or the other.
    StrCpy $currentPlatformSelection $1
    return
  ${Case} "11"
    StrCpy $SelectedCaseIndexForPlatformScreen "gSMXI"
    !insertmacro SelectSection ${gSMXI} ; MXGuard with SmarterMail
    Call SetInstallForMXGuard
    StrCpy $currentPlatformSelection $1
    return

  ${Case} "12" 
    StrCpy $SelectedCaseIndexForPlatformScreen "gAWDI"
    !insertmacro SelectSection ${gAWDI} ; Alligate
    Call SetInstallForSNF4Alligate ; Set the install folder to put MessageSniffer in based on the non-existant Alligate settings...
    StrCpy $currentPlatformSelection $1 ; set this so that the next time through the click-handler it knows what to start with.
    return ;

  ${Case} "13"
  ${Case} "14"
    WriteRegStr    HKLM "SOFTWARE\MessageSniffer" "IceWarpType" "AV" ; tells the Installer script to insert in AV position. Script will consume flag;
    StrCpy $SelectedCaseIndexForPlatformScreen "gIWTI"
    !insertmacro SelectSection ${gIWTI} ; IceWarp TieIn.
    ;Call SetInstallForIceWarp 
    StrCpy $currentPlatformSelection $1 ; set this so that the next time through the click-handler it knows what to start with.
    return ;
  ${Case} "15"
    WriteRegStr    HKLM "SOFTWARE\MessageSniffer" "IceWarpType" "CF" ; tells the Installer script to insert in dominant filter position. Script will consume flag;
    StrCpy $SelectedCaseIndexForPlatformScreen "gIWTICF"
    !insertmacro SelectSection ${gIWTICF} ; IceWarp TieIn.
    ;Call SetInstallForIceWarp
    StrCpy $currentPlatformSelection $1 ; set this so that the next time through the click-handler it knows what to start with.
    return ;
   ${Case} "16"
    WriteRegStr    HKLM "SOFTWARE\MessageSniffer" "IceWarpType" "SS" ; tells the Installer script to insert with SpamScore contribution. Script will consume flag;
    StrCpy $SelectedCaseIndexForPlatformScreen "gIWTICF2"
    !insertmacro SelectSection ${gIWTICF2} ; IceWarp TieIn.
    ;Call SetInstallForIceWarp 
    StrCpy $currentPlatformSelection $1 ; set this so that the next time through the click-handler it knows what to start with.
    return ;
  ${Case} "18"
    StrCpy $SelectedCaseIndexForPlatformScreen "gMSI"
    !insertmacro SelectSection ${gMSI} ; MailStop
    ;Call SetInstallForMailSite ; Set the install folder to put MessageSniffer in based on the non-existant Alligate settings...
    StrCpy $currentPlatformSelection $1 ; set this so that the next time through the click-handler it knows what to start with.
    return ;

  ${Case} "19"
    StrCpy $SelectedCaseIndexForPlatformScreen "gKMI"
    !insertmacro SelectSection ${gKMI} ; Kerio
    ;Call SetInstallForKerio ; Set the install folder to put MessageSniffer in based on the non-existant Alligate settings...
    StrCpy $currentPlatformSelection $1 ; set this so that the next time through the click-handler it knows what to start with.
    return ;

  ${Case} "20"
    StrCpy $SelectedCaseIndexForPlatformScreen "gMDDLL"
    !insertmacro SelectSection ${gMDDLL} ; Kerio
    ;Call SetInstallForMDaemon ; Set callback for the MDaemon install code
    StrCpy $currentPlatformSelection $1 ; set this so that the next time through the click-handler it knows what to start with.
    return ;
    
  ${Case} "21" ## WON'T HAPPEN
    StrCpy $SelectedCaseIndexForPlatformScreen "gSNFI"
    !insertmacro SelectSection ${gSNFI} ; SnifferStandalone
    # These vars are used by the page that looks for missing folders.
    ;StrCpy $MissingApplicationName "Stand Alone Sniffer installation" ; This is used to identify the abstracted application name.
    ; MissingApplicationFolder ; This is used to identify the abstracted application folder to start the search from
    ;StrCpy $FindApplicationMessage "Please choose the folder where the $MissingApplicationName should reside." ; This is used to abstract the search page.
    ;Call LocatePlatformScreen
    ;StrCpy $SNFServerInstallDir $MissingApplicationFolder ; This will get the \SNF and the \SNFArchive folders built inside.....
    ;StrCpy $INSTDIR "$SNFServerInstallDir\SNF"
    ;StrCpy $currentPlatformSelection $1
    return


  ${Case} "22"
    StrCpy $SelectedCaseIndexForPlatformScreen "gUSWDI"
    !insertmacro SelectSection ${gUSWDI} ; Unknown Declude
    ; Can't call this until you select the folders...Call SetInstallForDeclude ; No guarantees.... just install it in decludes folder.
    StrCpy $currentPlatformSelection $1
    return

  ${Case} "23"
    StrCpy $SelectedCaseIndexForPlatformScreen "gCUKC" ; this Custom unknown
    ; doesn't matter where the folder is.. user will set it on the next screen.
    !insertmacro SelectSection ${gCUKC} ; 
    return

  #  END THE Case elements for the Platforms OnSelectChange handling....
  #  These bottom ones are shown on the second components page.....

  ${Case} "6" ; Handling the request to see the status page.
    StrCpy $ShowRestoreOptionsPage "0" ; don't show restore utilities.
    StrCpy $ShowArchiveOptionsPage "0" ; don't show archive utilities.
    StrCpy $ShowTelemetryPage "1" ; don't show status utilities.
    StrCpy $HandleUninstallPage "0" ; don't show uninstall screen.
    !insertmacro SelectSection ${g1o6B} ; INSTALL NEW chekcboxes should be checked.
    StrCpy $currentUtilitySelection $1
    Return
    
  ${Case} "5" ; if 5 was selected we jump with no play to the uninstaller.
     StrCpy $HandleUninstallPage "1" ; don't show uninstall screen.
     StrCpy $ShowArchiveOptionsPage "0" ; don't show utilities.
     StrCpy $ShowTelemetryPage "0" ; don't show status utilities.
    StrCpy $ShowRestoreOptionsPage "0" ; don't show restore utility.
     !insertmacro SelectSection ${g1o6} ; Just Uninstall should be checked.
     StrCpy $currentUtilitySelection $1
    Return
  ${Case} "4"
    StrCpy $ShowRestoreOptionsPage "1" ; If 4 was selected, we show the restore utility
    StrCpy $ShowArchiveOptionsPage "0" ; don't show utilities.
    StrCpy $ShowTelemetryPage "0" ; don't show status utilities.
    StrCpy $HandleUninstallPage "0" ; don't show uninstall screen.
    !insertmacro SelectSection ${g1o5} ; Just RESTORE should be checked.
     StrCpy $currentUtilitySelection $1
    Return
  ${Case} "3"
    StrCpy $ShowArchiveOptionsPage "1" ; If 3 was selected, we show the archive utility
    StrCpy $ShowRestoreOptionsPage "0" ; don't show restore utility.
    StrCpy $ShowTelemetryPage "0" ; don't show status utilities.
    StrCpy $HandleUninstallPage "0" ; don't show uninstall screen.
    !insertmacro SelectSection ${g1o4} ; JUST THE ARCHIVE chekcboxes should be checked.
     StrCpy $currentUtilitySelection $1
    Return
  ${Case} "2"
    StrCpy $ShowRestoreOptionsPage "0" ; don't show restore utilities.
    StrCpy $ShowTelemetryPage "0" ; don't show status utilities.
    StrCpy $ShowArchiveOptionsPage "0" ; don't show archive utilities.
    StrCpy $HandleUninstallPage "0" ; don't show uninstall screen.
    !insertmacro SelectSection ${g1o3} ; INSTALL WITH SETTINGS chekcboxes should be checked.
    StrCpy $currentUtilitySelection $1
    Return
  ${Case} "1"
    StrCpy $ShowRestoreOptionsPage "0" ; don't show restore utilities.
    StrCpy $ShowArchiveOptionsPage "0" ; don't show archive utilities.
    StrCpy $ShowTelemetryPage "0" ; don't show statsu utilities.
    StrCpy $HandleUninstallPage "0" ; don't show uninstall screen.
    !insertmacro SelectSection ${g1o2} ; INSTALL FRESH chekcboxes should be checked.
    StrCpy $currentUtilitySelection $1
    Return
  ${Case} "0" ; Handling the 0 ( the expected result ) from clicking the NEW INSTALL button, ( but only when the Restore option is presented...)
    StrCpy $ShowRestoreOptionsPage "0" ; don't show restore utilities.
    StrCpy $ShowArchiveOptionsPage "0" ; don't show archive utilities.
    StrCpy $ShowTelemetryPage "0" ; don't show status utilities.
    StrCpy $HandleUninstallPage "0" ; don't show uninstall screen.
    !insertmacro SelectSection ${g1o1} ; INSTALL NEW chekcboxes should be checked.
    StrCpy $currentUtilitySelection $1
    Return
  ${Case} "\" ; When NEW INSTALL is by itself...or some reason the subroutine is returning slash as the result of clicking the NEW button when its the only option.
    StrCpy $ShowRestoreOptionsPage "0" ; don't show restore utilities.
    StrCpy $ShowArchiveOptionsPage "0" ; don't show archive utilities.
    StrCpy $ShowTelemetryPage "0" ; don't show status utilities.
    StrCpy $HandleUninstallPage "0" ; don't show uninstall screen.
    !insertmacro SelectSection ${g1o1} ; INSTALL NEW chekcboxes should be checked.
    StrCpy $currentUtilitySelection "0"
    Return
  ${Default}
      ; If we get here, we have an unusual situation that leaks through teh event handler.
      ; Though its not possible, you can unclick a radio button that should always have one selected.
      ; and put yourself in the original state of having nothing picked... if so, disable next.
        EnableWindow $NextButton "0"
  ${EndSwitch}
FunctionEnd
; Ending Functions for control of components selection
;-----------------------------------

Function nsDialogHandleUninstall
  ; This page never shows.  It will always complete and then return to the main components page. ( Or play through if $HandleUninstallPage= 0
  StrCmp $HandleUninstallPage "1" 0 exit_nsDialogsUninstall

  SetOutPath $INSTDIR
  ifFileExists "$INSTDIR\uninstall.exe" 0 NotifyFind
    SetOutPath $SNFServerInstallDir ; Reset this to enable the descturction of working directories.. THIS WAS THE CULPRET THAT HELD THE LOCK ON THE FOLDER!!!
    ExecWait "$INSTDIR\uninstall.exe"
    StrCpy $R9 "-4" ;Relative page number. See below.
    Call RelGotoPage ; take me back to main screen
    return ;
NotifyFind:
    MessageBox MB_OK "Message Sniffer Utility is unable to locate the Uninstaller in the proper directory.  Please search for the uninstall.exe in the proper directory."
    StrCpy $R9 "-4" ;Relative page number. See below.
    Call RelGotoPage ; take me back to main screen
    
exit_nsDialogsUninstall:
  return ;
FunctionEND

Function nsDialogsTelemetryShow
 StrCmp $ShowTelemetryPage "1" 0 exit_nsDialogsTelemetry
 !insertmacro BIMAGE "SnifferBannerArchive.bmp" ""

  GetDlgItem $0 $HWNDPARENT 1
  SendMessage $0 ${WM_SETTEXT} 0 "STR:Exit Status" ; set the next button text:

  SendMessage $HWNDPARENT ${WM_SETTEXT} 0 "STR:Message Sniffer Server 3.0  Status Viewer:" ; set the window text.

  Var /GLOBAL TEXTBOX_Telemetry
  Var /GLOBAL TelemetryData
  Var /GLOBAL TelemetryGo

    nsDialogs::Create /NOUNLOAD 1018
    Pop $0
    ${NSD_CreateLabel} 0 0 100% 90 "Greetings.  This is the quick status checking screen.  You may press the test buttons to manually reload the status and rulebase authentication validation."
    Pop $0

      	${NSD_CreateLabel} 0 30 100% 80u "Press to load status...." ; Default text goes in the quotes if you want something in the text box initially.;
  	Pop $TEXTBOX_Telemetry

        ${NSD_CreateButton} 0 180 30% 14u "Retest Status"
	Pop $TelemetryGo
	GetFunctionAddress $0 reloadTelemetry
	nsDialogs::OnClick /NOUNLOAD $TelemetryGo $0

    nsDialogs::Show
 exit_nsDialogsTelemetry:

FunctionEnd

Function reloadTelemetry

  ${GetBetween} "licenseid='" "'" "$INSTDIR\identity.xml" $LicenseID ; This makes it not brittly dependant on the default value. i.e. It would
    ${GetBetween} "authentication='" "'" "$INSTDIR\identity.xml" $Authentication

        StrCpy $TelemetryData "" "Starting Status Test.$\r$\n"
        StrCpy $TelemetryData "" "$TelemetryData $\r$\nLicense = $LicenseID  Authentication = $Authentication"
    
        nsExec::ExecToStack 'NET START SNFService'
	Pop $0 # return value/error/timeout
	StrCpy $TelemetryData "$TelemetryData$\r$\n NET START Return Code: $0"
	Pop $1 # printed text, up to ${NSIS_MAX_STRLEN}
        StrCpy $TelemetryData "$TelemetryData$\r$\n $1"

        nsExec::ExecToStack '$INSTDIR\SNFService'
	Pop $0 # return value/error/timeout
	Pop $1 # printed text, up to ${NSIS_MAX_STRLEN}
        StrCpy $TelemetryData "$TelemetryData$\r$\n $1"
	
        ; but first test for valid status
        nsExec::ExecToStack '"$INSTDIR\snf2check.exe" "$INSTDIR\$LicenseID.snf" "$Authentication"'
	Pop $0 # return value/error/timeout
	StrCpy $TelemetryData "$TelemetryData$\r$\n snf2check return code: $0"
	Pop $1 # printed text, up to ${NSIS_MAX_STRLEN}
        StrCpy $TelemetryData "$TelemetryData$\r$\n $1"

        ;Sleep 5000
        ;MessageBox MB_OK "$INSTDIR"
        nsExec::ExecToStack '$INSTDIR\SNFClient -status.second'
	Pop $0 # return value/error/timeout
	StrCpy $TelemetryData "$TelemetryData$\r$\n SNFClient return code: $0"
	Pop $1 # printed text, up to ${NSIS_MAX_STRLEN}
        StrCpy $TelemetryData "$TelemetryData$\r$\n $1"
        MessageBox MB_OK "$1"


        SendMessage $TEXTBOX_Telemetry ${WM_SETTEXT} 0 "STR:$TelemetryData"
        
FunctionEND



Function nsDialogsTelemetryLeave
  StrCpy $R9 "-1" ;Relative page number. See below.
  Call RelGotoPage
FunctionEND




Function nsDialogInstall
  SendMessage $HWNDPARENT ${WM_SETTEXT} 0 "STR:Install Utility Unpacking Components:"  ; change text screen.
  !insertmacro BIMAGE "SnifferBanner2.bmp" ""  ; change banner image.
FunctionEND





Function .onUserAbort
  ; If this happenes we don't want to leave a folder hanging there.
  SetOutPath "$SNFServerInstallDir"
  ;IfFileExists "$SNFServerInstallDir\SNF\mingwm10.dll" +2 0 ; If the dll exists, presume a decent install.  If not... presume its screwed and delete it.
  ;RMDir /r "$SNFServerInstallDir\SNF"
FunctionEnd

Function check_CompoundEnable
  VAR /GLOBAL Compound_Enable1  ; a value to ensure enabling.
  VAR /GLOBAL Compound_Enable2 ; another value that must be enabled to enable the next.

  EnableWindow $NextButton "0" ; presume no.

  StrCmp $Compound_Enable1 "0" 0 +2
    return
  StrCmp $Compound_Enable2 "0" 0 +2
    return
  #StrCmp $Compound_Enable3 "0" 0 +2
  #  return
  EnableWindow $NextButton "1" ; presume no.
  return
FunctionEnd


Function FindApplicationPath

  Var /Global windowHandle
      nsDialogs::Create /NOUNLOAD 1018
      Pop $windowHandle

        SendMessage $HWNDPARENT ${WM_SETTEXT} 0 "STR:Please locate the $MissingApplicationName folders."
        !insertmacro BIMAGE "SnifferBanner.bmp" ""

       ; Disable the next button until selection is made.
       GetDlgItem $NextButton $HWNDPARENT 1
       EnableWindow $NextButton "0"




#############################################################################
## These variables hold the list of platforms for which we MAY install SNF.
## There may be one, more or many.
##VAR /GLOBAL isIceWarpInstalled
##VAR /GLOBAL isMailSiteInstalled
##VAR /GLOBAL isKerioInstalled
##VAR /GLOBAL isImailInstalled
##VAR /GLOBAL isSmarterMailInstalled
##VAR /GLOBAL isAlligateInstalled
##VAR /GLOBAL isDecludeInstalled
#VAR /GLOBAL isMXGuardInstalled
#VAR /GLOBAL isMINIMIInstalled
#VAR /GLOBAL Set_For_MINIMI_INSTALL ; may or may not be set, depending of if the user wants to re-install MINIMI

#VAR /GLOBAL SelectedCaseIndexForPlatformScreen ; This is the var for controlling the case display on the platform screen.  Indxed top to bottom.
## Now define the variables to hold the locations of WHERE we install SNF
## in the event we select any of these options.
#VAR /GLOBAL IceWarpInstallFolder
#VAR /GLOBAL MailSiteInstallFolder
#VAR /GLOBAL KerioInstallFolder
#VAR /GLOBAL ImailInstallFolder
#VAR /GLOBAL SmarterMailInstallFolder
#VAR /GLOBAL AlligateInstallFolder
#VAR /GLOBAL DecludeInstallFolder
#VAR /GLOBAL MXGuardInstallFolder
#VAR /GLOBAL MINIMIInstallFolder


Var /Global HowToFindMessage ; var for holding the popped winhandle for the message control...
Var /Global SNF_StartLookingHere
StrCpy $SNF_StartLookingHere "C:\Program Files\SNF"
StrCpy $Compound_Enable1 "0"    ; the default is you must declare at least the Sniffer directory....
StrCpy $Compound_Enable2 "0"   ; but maybe the declude dir?


## ADDINGPLATFORM ## Step 21
## Ok, here is the validation screens.  This sub is called after you've selected the platform in the installer.
## It calls a switch on what platform, and based on that switch, it displays and runs tests on the folders it can find, or knows about.
## If it finds the expected files, then its all rosy and it enables the <NEXT> button.  If not, it will force the user to lookup the target
## and redisplay this page to test if the new locaton has the expected files.  If it can't find the expected files, it won't let the installer
## proceed, and it won't install.  The case is driven off of the short name of the SECTION, so is NOT ordinal based, but its just nice to
## keep it in the same order that you saw it in the list.
## Steps to add this case block are:
## Copy block. Alter DetermineXYZ call to test for specific platform.
## Convert the file testing, adjust the user display responses.
## If necessary, add NOPLATFORM block after Switch block.
## Alter the default folder to display in the text block with SendMessage to hold the XYZInstallDir
## Alter the paths in the ifFileExists tests, to reflect the platform desired.
## Be sure to complete step 22, us the name that you unter as the callback in the NSD_OnClick button handler. i.e. LocateXYZFolder.
## Fix the compound enable test to be happy if the proper files are where they should be.

${Switch} $SelectedCaseIndexForPlatformScreen
    ${Case} "gIWDI" ; zero indexed array... Imail with Declude gIWDI

      StrCpy $Find_Explanation_INFO "You have chosen to install Sniffer under Declude with an Imail configuration.  You will need to confirm the location of the following items:"
      
      ## Handle the definition of the page for Imail and Declude
      Call DetermineImail
      StrCmp $IsImailInstalled "1" 0 NoImailFound
        Call DetermineDeclude
        StrCmp $IsDecludeInstalled "1" 0 NoDecludeFound
          StrCpy $FindApplicationMessage "Imail was found.  Please confirm the folder for Declude's global.cfg file.  "
          Goto +2
        NoDecludeFound:
          StrCpy $FindApplicationMessage "Imail was found.  Declude was not. Please find Declude's global.cfg file."

                ${NSD_CreateDirRequest} 0 55% 75% 12u ""  ; instructions
                Pop $SNF_SearchFor_Location              ; handle
                SendMessage $SNF_SearchFor_Location ${WM_SETTEXT} 0 "STR:$SNFServerInstallDir" ; yes, the var comes from the registry with an apended '/'... it stupid... This is the look up for the global.cfg
                                                                          ; For Declude, you need to add \declude to the end of the DecludeInstalationFolder......
                ${NSD_CreateBrowseButton} 340 55% 8% 12u "..."
                Pop $SNF_SearchFor_Location_Button
                ${NSD_OnClick} $SNF_SearchFor_Location_Button LocateDecludeFolder

                ifFileExists "$SNFServerInstallDir\global.cfg" 0 +3 ; if the file exists then both folders could be ok... offer the next.
                  StrCpy $Compound_Enable2 "1"  ; clear for double ok.
                  ;EnableWindow $NextButton "1" ; enable button, cause if you have 1 you have SOMETHING for the other...
                  Call check_CompoundEnable
                  
                  StrCpy $SNF_StartLookingHere "$SNFServerInstallDir\SNF" ; store the starting path here for looking.
Goto EndDisplayChoices

  ${Case} "gIMXI"
      StrCpy $Find_Explanation_INFO "You have chosen to install Sniffer under MXGuard with an Imail configuration.  You will need to confirm the location of the following items:"
      StrCpy $MissingApplicationName "Imail w/ MXGuard"

      ## Handle the definition of the page for Imail and MINIMI
      Call DetermineImail
      StrCmp $IsImailInstalled "1" 0 NoImailFound
        Call DetermineMXGuard
        StrCmp $IsMXGuardInstalled "1" 0 NoMXGuardFound
          StrCpy $FindApplicationMessage "Imail was found.  Please confirm the folder for MXGuard.  "
          Goto +2
        NoMXGuardFound:
          StrCpy $FindApplicationMessage "Imail was found.  MXGuard was not. Please find MXGuards/ install directory."

                ${NSD_CreateDirRequest} 0 55% 75% 12u ""  ; instructions
                Pop $SNF_SearchFor_Location              ; handle
                SendMessage $SNF_SearchFor_Location ${WM_SETTEXT} 0 "STR:$MXGuardInstallFolder" ; yes, the var comes from the registry with an apended '/'... it stupid... This is the look up for the global.cfg

                ${NSD_CreateBrowseButton} 340 55% 8% 12u "..."
                Pop $SNF_SearchFor_Location_Button
                ${NSD_OnClick} $SNF_SearchFor_Location_Button LocateMXGuardFolder

                ifFileExists "$MXGuardInstallFolder\mxguard.ini" 0 +3 ; if the file exists then both folders could be ok... offer the next.
                  StrCpy $Compound_Enable2 "1"  ; clear for double ok.
                  ;EnableWindow $NextButton "1" ; enable button, cause if you have 1 you have SOMETHING for the other...
                  Call check_CompoundEnable ; this will enable or hold based on multiple flags....

                StrCpy $SNF_StartLookingHere "$MXGuardInstallFolder\SNF" ; store the starting path here for looking.
Goto EndDisplayChoices ;

  ${Case} "gIMMI"
      StrCpy $Find_Explanation_INFO "You have chosen to install Sniffer with MINIMI for the Imail server.  You will need to confirm the location of the following items:"
      StrCpy $MissingApplicationName "Imail w/ MINIMI"

      ## Handle the definition of the page for Imail and MINIMI
      Call DetermineImail
      StrCmp $IsImailInstalled "1" 0 NoImailFound
        Call DetermineMINIMI
        StrCmp $IsMINIMIInstalled "1" 0 NoMINIMIFound
          StrCpy $FindApplicationMessage "Imail was found.  Please confirm the folder for MINIMI to be installed in $\nby finding Imail's location for smtp32.  "
          Goto +2
        NoMINIMIFound:
          StrCpy $FindApplicationMessage "Imail was found.  MINIMI was not. Please confirm the location for MINIMI.$\n(Imail's location for smtp32.)"

                ${NSD_CreateDirRequest} 0 55% 75% 12u ""  ; instructions
                Pop $SNF_SearchFor_Location              ; handle
                SendMessage $SNF_SearchFor_Location ${WM_SETTEXT} 0 "STR:$MINIMIInstallFolder" ; yes, the var comes from the registry with an apended '/'... it stupid... This is the look up for the global.cfg

                ${NSD_CreateBrowseButton} 340 55% 8% 12u "..."
                Pop $SNF_SearchFor_Location_Button
                ${NSD_OnClick} $SNF_SearchFor_Location_Button LocateMINIMIFolder

                ifFileExists "$MINIMIInstallFolder\SMTP32.exe" 0 +3 ; if the file exists then both folders could be ok... offer the next.
                  StrCpy $Compound_Enable2 "1"  ; clear for double ok.
                  ;EnableWindow $NextButton "1" ; enable button, cause if you have 1 you have SOMETHING for the other...
                  Call check_CompoundEnable ; this will enable or hold based on multiple flags....

                  StrCpy $SNF_StartLookingHere "$MINIMIInstallFolder\SNF" ; store the starting path here for looking.
                  
    Goto EndDisplayChoices ;

  ${Case} "gSWDI"
  
      StrCpy $Find_Explanation_INFO "You have chosen to install Sniffer with Declude under SmarterMail.  You will need to confirm the location of the following items:"
      StrCpy $MissingApplicationName "Smartermail w/ Declude"

      ## Handle the definition of the page for Imail and Declude
      Call DetermineSmarterMail
      StrCmp $IsSmarterMailInstalled "1" 0 NoSmarterMail
        Call DetermineDeclude ; handles both conditions.....
        StrCmp $IsDecludeInstalled "1" 0 NoDeclude_Found
          StrCpy $FindApplicationMessage "SmarterMail was found.  Please confirm the folder for Declude's global.cfg file.  "
          Goto +2
        NoDeclude_Found:
          StrCpy $FindApplicationMessage "SmarterMail was found.  Declude was not. Please find Declude's global.cfg file."

                ${NSD_CreateDirRequest} 0 55% 75% 12u ""  ; instructions
                Pop $SNF_SearchFor_Location              ; handle
                SendMessage $SNF_SearchFor_Location ${WM_SETTEXT} 0 "STR:$SNFServerInstallDir" ; yes, the var comes from the registry with an apended '/'... it stupid... This is the look up for the global.cfg

                ${NSD_CreateBrowseButton} 340 55% 8% 12u "..."
                Pop $SNF_SearchFor_Location_Button
                ${NSD_OnClick} $SNF_SearchFor_Location_Button LocateDecludeFolder

                ifFileExists "$SNFServerInstallDir\global.cfg" 0 +3 ; if the file exists then both folders could be ok... offer the next.
                  StrCpy $Compound_Enable2 "1"  ; clear for double ok.
                  ;EnableWindow $NextButton "1" ; enable button, cause if you have 1 you have SOMETHING for the other...
                  Call check_CompoundEnable


                StrCpy $SNF_StartLookingHere "$SNFServerInstallDir\SNF" ; store the starting path here for looking.
      Goto EndDisplayChoices ;
      
  ${Case} "gSMXI"
      StrCpy $Find_Explanation_INFO "You have chosen to install Sniffer with MXGuard under SmarterMail.  You will need to confirm the location of the following items:"
      StrCpy $MissingApplicationName "Smartermail w/ MXGuard"

      ## Handle the definition of the page for Smartermail and  and MXGuard
      Call DetermineSmarterMail
      StrCmp $IsSmarterMailInstalled "1" 0 NoSmarterMail
        Call DetermineMXGuard
        StrCmp $IsMXGuardInstalled "1" 0 NoSMMXGuardFound
          StrCpy $FindApplicationMessage "SmarterMail was found.  Please confirm the folder for MXGuard.  "
          Goto +2
        NoSMMXGuardFound:
          StrCpy $FindApplicationMessage "SmarterMail was found.  MXGuard was not. Please find MXGuards mxguard.ini file.  $\nTypical locations would be in: [root]\Program Files\dgSoft Internet Services\mxGuard for Mail Servers."

          StrCmp $MXGuardInstallFolder "" 0 +2  ; If Its not empty then use what DetermineMXGuard found.... otherwise... use guess...
            StrCpy $MXGuardInstallFolder "C:\Program Files\dgSoft Internet Services\mxGuard for Mail Servers"
            
                ${NSD_CreateDirRequest} 0 55% 75% 12u ""  ; instructions
                Pop $SNF_SearchFor_Location              ; handle
                SendMessage $SNF_SearchFor_Location ${WM_SETTEXT} 0 "STR:$MXGuardInstallFolder" ; yes, the var comes from the registry with an apended '/'... it stupid... This is the look up for the global.cfg

                ${NSD_CreateBrowseButton} 340 55% 8% 12u "..."
                Pop $SNF_SearchFor_Location_Button
                ${NSD_OnClick} $SNF_SearchFor_Location_Button LocateMXGuardFolder

                ifFileExists "$MXGuardInstallFolder\mxguard.ini" 0 +3 ; if the file exists then both folders could be ok... offer the next.
                  StrCpy $Compound_Enable2 "1"  ; clear for double ok.
                  ;EnableWindow $NextButton "1" ; enable button, cause if you have 1 you have SOMETHING for the other...
                  Call check_CompoundEnable ; this will enable or hold based on multiple flags....

                StrCpy $SNF_StartLookingHere "$MXGuardInstallFolder\SNF" ; store the starting path here for looking.

#C:\Program Files\dgSoft Internet Services\mxGuard for Mail Servers

      Goto EndDisplayChoices ;

  ${Case} "gAWDI"
      StrCpy $Find_Explanation_INFO "You have chosen to install Sniffer with Alligate.  You will need to confirm the location of the following items:"
      StrCpy $MissingApplicationName "Alligate"

      ## Handle the definition of the page for Imail and MINIMI
      Call DetermineAlligate
      StrCmp $IsAlligateInstalled "1" 0 NoAlligateFound
        Call DetermineSNF4Alligate
        StrCmp  "1" 0 NoSNF4AlligateFound
          StrCpy $FindApplicationMessage "Alligate was found.  Please confirm the folder for SNF4Alligate to be installed in $\nby confirming Alligates install location for AGFiltSVC.exe  "
          Goto +2
        NoSNF4AlligateFound:
          StrCpy $FindApplicationMessage "Alligate was found.  SNF4Alligate was not. Please confirm the location for SNF4Alligate \n(Same as Alligate's location for AGFiltSVC.exe)"

                ${NSD_CreateDirRequest} 0 55% 75% 12u ""  ; instructions
                Pop $SNF_SearchFor_Location              ; handle
                SendMessage $SNF_SearchFor_Location ${WM_SETTEXT} 0 "STR:$AlligateInstallFolder" ; yes, the var comes from the registry with an apended '/'... it stupid... This is the look up for the global.cfg

                ${NSD_CreateBrowseButton} 340 55% 8% 12u "..."
                Pop $SNF_SearchFor_Location_Button
                ${NSD_OnClick} $SNF_SearchFor_Location_Button LocateSNF4AlligateFolder

                StrCpy $SNF4AlligateInstallFolder $AlligateInstallFolder
                ifFileExists "$AlligateInstallFolder\AGFiltSvc.exe" 0 +3 ; if the file exists then both folders could be ok... offer the next.
                  StrCpy $Compound_Enable2 "1"  ; clear for double ok.
                  ;EnableWindow $NextButton "1" ; enable button, cause if you have 1 you have SOMETHING for the other...
                  Call check_CompoundEnable ; this will enable or hold based on multiple flags....

                  StrCpy $SNF_StartLookingHere "$AlligateInstallFolder\SNF" ; store the starting path here for looking.

    Goto EndDisplayChoices ;
  ${Case} "gIWTICF"
  ${Case} "gIWTICF2"
  ${Case} "gIWTI"
      StrCpy $Find_Explanation_INFO "You have chosen to install Sniffer with Icewarp  You will need to confirm the location of the following items:"
      StrCpy $MissingApplicationName "Icewarp"

      ## Handle the definition of the page for Imail and MINIMI
      Call DetermineIceWarp
      StrCmp $IsIceWarpInstalled "1" 0 NoIceWarpFound
        IfFileExists "$IceWarpInstallFolder\config\content.xml" 0 NoContentXMLFound
          StrCpy $FindApplicationMessage "IceWarp was found.  Please confirm Icewarp's install location."
          Goto +2
        NoContentXMLFound:
          StrCpy $FindApplicationMessage "IceWarp was found.  Its content.xml was not. Please confirm the location of the [config] folder holding Merak\config\content.xml"

                ${NSD_CreateDirRequest} 0 55% 75% 12u ""  ; instructions
                Pop $SNF_SearchFor_Location              ; handle
                SendMessage $SNF_SearchFor_Location ${WM_SETTEXT} 0 "STR:$IceWarpInstallFolder" ; yes, the var comes from the registry with an apended '/'... it stupid... This is the look up for the global.cfg

                ${NSD_CreateBrowseButton} 340 55% 8% 12u "..."
                Pop $SNF_SearchFor_Location_Button
                ${NSD_OnClick} $SNF_SearchFor_Location_Button LocateIceWarpFolder

                ifFileExists "$IceWarpInstallFolder\config\content.xml" 0 +3 ; if the file exists then both folders could be ok... offer the next.
                  StrCpy $Compound_Enable2 "1"  ; clear for double ok.
                  ;EnableWindow $NextButton "1" ; enable button, cause if you have 1 you have SOMETHING for the other...
                  Call check_CompoundEnable ; this will enable or hold based on multiple flags....

                  StrCpy $SNF_StartLookingHere "$IceWarpInstallFolder\SNF" ; store the starting path here for looking.

    Goto EndDisplayChoices ;
    
    ${Case} "gMSI"
      StrCpy $Find_Explanation_INFO "MailSite isn't fully supported yet."
      StrCpy $MissingApplicationName "MailSite"

          StrCpy $FindApplicationMessage "MailSite was not found."

                ${NSD_CreateDirRequest} 0 55% 75% 12u ""  ; instructions
                Pop $SNF_SearchFor_Location              ; handle
                SendMessage $SNF_SearchFor_Location ${WM_SETTEXT} 0 "STR:$MailSiteInstallFolder" ; yes, the var comes from the registry with an apended '/'... it stupid... This is the look up for the global.cfg

                ${NSD_CreateBrowseButton} 340 55% 8% 12u "..."
                Pop $SNF_SearchFor_Location_Button
                ${NSD_OnClick} $SNF_SearchFor_Location_Button LocateMailSiteFolder

                ifFileExists "$MailSiteInstallFolder\*.*" 0 +3 ; if the file exists then both folders could be ok... offer the next.
                  StrCpy $Compound_Enable2 "1"  ; clear for double ok.
                  ;EnableWindow $NextButton "1" ; enable button, cause if you have 1 you have SOMETHING for the other...
                  Call check_CompoundEnable ; this will enable or hold based on multiple flags....

                  StrCpy $SNF_StartLookingHere "$MailSiteInstallFolder\SNF" ; store the starting path here for looking.

    Goto EndDisplayChoices ;
    
    ${Case} "gKMI"
      StrCpy $Find_Explanation_INFO "Kerio isn't fully supported yet."
      StrCpy $MissingApplicationName "Kerio"

          StrCpy $FindApplicationMessage "Kerio was not found."

                ${NSD_CreateDirRequest} 0 55% 75% 12u ""  ; instructions
                Pop $SNF_SearchFor_Location              ; handle
                SendMessage $SNF_SearchFor_Location ${WM_SETTEXT} 0 "STR:$KerioInstallFolder" ; yes, the var comes from the registry with an apended '/'... it stupid... This is the look up for the global.cfg

                ${NSD_CreateBrowseButton} 340 55% 8% 12u "..."
                Pop $SNF_SearchFor_Location_Button
                ${NSD_OnClick} $SNF_SearchFor_Location_Button LocateKerioFolder

                ifFileExists "$KerioInstallFolder\*.*" 0 +3 ; if the file exists then both folders could be ok... offer the next.
                  StrCpy $Compound_Enable2 "1"  ; clear for double ok.
                  ;EnableWindow $NextButton "1" ; enable button, cause if you have 1 you have SOMETHING for the other...
                  Call check_CompoundEnable ; this will enable or hold based on multiple flags....

                  StrCpy $SNF_StartLookingHere "$KerioInstallFolder\SNF" ; store the starting path here for looking.

    Goto EndDisplayChoices ;
    
      ${Case} "gMDDLL"
      StrCpy $Find_Explanation_INFO "You have chosen to install Sniffer with MDaemon You will need to confirm the location of the following items:"
      StrCpy $MissingApplicationName "MDaemon"

      ## Handle the determination of MDaemon.
      Call DetermineMDaemon
      StrCmp $IsMDaemonInstalled "1" 0 NoMDaemon
        StrCpy $FindApplicationMessage "MDaemon was found.  Please confirm where SNF should reside:"
        ifFileExists "$MDaemonInstallFolder\App\*.*" +2 0
        StrCpy $FindApplicationMessage "MDaemons App folder was not found.  Please confirm the MDaemon and SNF locations:"

                ${NSD_CreateDirRequest} 0 55% 75% 12u ""  ; instructions
                Pop $SNF_SearchFor_Location              ; handle
                SendMessage $SNF_SearchFor_Location ${WM_SETTEXT} 0 "STR:$MDaemonInstallFolder" ; yes, the var comes from the registry with an apended '/'... it stupid... This is the look up for the global.cfg

                ${NSD_CreateBrowseButton} 340 55% 8% 12u "..."
                Pop $SNF_SearchFor_Location_Button
                ${NSD_OnClick} $SNF_SearchFor_Location_Button LocateMDaemonFolder

                ifFileExists "$MDaemonInstallFolder\*.*" 0 +3 ; if the file exists then both folders could be ok... offer the next.
                  StrCpy $Compound_Enable2 "1"  ; clear for double ok.
                  ;EnableWindow $NextButton "1" ; enable button, cause if you have 1 you have SOMETHING for the other...
                  Call check_CompoundEnable ; this will enable or hold based on multiple flags....

                  StrCpy $SNF_StartLookingHere "$MDaemonInstallFolder\SNF" ; store the starting path here for looking.

    Goto EndDisplayChoices ;
    
  ${Case} "gSNFI"
      StrCpy $Find_Explanation_INFO "You have chosen to install Sniffer in a stand alone.  You will need to confirm the location of the install directory."
      StrCpy $MissingApplicationName "Stand Alone Sniffer"

      Goto EndDisplayChoices ;

  ${Case} "gUSWDI"
      StrCpy $Find_Explanation_INFO "You have chosen to install Sniffer in an unidentified Declude install.  You will need to confirm the location of the following items:"
      StrCpy $MissingApplicationName "Generic Declude Install"

      ## Handle the definition of the page for Imail and Declude
     Call DetermineDeclude ; handles both conditions.....
        StrCmp $IsDecludeInstalled "1" 0 NoDeclude_Found
          StrCpy $FindApplicationMessage "No supporting mail server was recognized.  Please locate the folder holding Declude's global.cfg file.  "
                ${NSD_CreateDirRequest} 0 55% 75% 12u ""  ; instructions
                Pop $SNF_SearchFor_Location              ; handle
                SendMessage $SNF_SearchFor_Location ${WM_SETTEXT} 0 "STR:$SNFServerInstallDir" ; yes, the var comes from the registry with an apended '/'... it stupid... This is the look up for the global.cfg

                ${NSD_CreateBrowseButton} 340 55% 8% 12u "..."
                Pop $SNF_SearchFor_Location_Button
                ${NSD_OnClick} $SNF_SearchFor_Location_Button LocateDecludeFolder

                ifFileExists "$SNFServerInstallDir\global.cfg" 0 +3 ; if the file exists then both folders could be ok... offer the next.
                  StrCpy $Compound_Enable2 "1"  ; clear for double ok.
                  ;EnableWindow $NextButton "1" ; enable button, cause if you have 1 you have SOMETHING for the other...
                  Call check_CompoundEnable

                StrCpy $SNF_StartLookingHere "$SNFServerInstallDir\SNF" ; store the starting path here for looking.
      Goto EndDisplayChoices ;


  ${Case} "gCUKC"
      StrCpy $Find_Explanation_INFO "You have chosen to install Sniffer in a stand alone.  You will need to confirm the location of the install directory."
      StrCpy $MissingApplicationName "Custom / Unknown" ;
      StrCpy $FindApplicationMessage ""
          StrCpy $Compound_Enable2 "1"  ; clear for double ok.
         Call check_CompoundEnable

      Goto EndDisplayChoices ;
  ${Default}
      ; If we get here, we have an unusual situation that leaks through teh event handler.
      ; Though its not possible, you can unclick a radio button that should always have one selected.
      ; and put yourself in the original state of having nothing picked... if so, disable next.
        EnableWindow $NextButton "0"
  ${EndSwitch}
EndDisplayChoices:
    Var /GLOBAL FindINSTDIRMessage
    StrCpy $FindINSTDIRMessage "Please locate the directory where you wish to install Message Sniffer. "

    ; put in the header handlers.
                ${NSD_CreateLabel} 0 0 75% 25% "$Find_Explanation_INFO"
                Pop $0

                ${NSD_CreateLabel} 0 25% 100% 30% "$FindApplicationMessage"
                Pop $HowToFindMessage
   ; Now put in the controls for handling the Sniffer Path.....

                ${NSD_CreateLabel} 0 70% 100% 15 "Please confirm/locate the folder you wish Message Sniffer to be installed in."
                Pop $HowToFindMessage

                ${NSD_CreateDirRequest} 0 80% 75% 12u ""
                Pop $SNF_SearchFor_LocationB
                SendMessage $SNF_SearchFor_LocationB ${WM_SETTEXT} 0 "STR:$SNF_StartLookingHere" ; This is the look up for the SNIFFER Location....

                ${NSD_CreateBrowseButton} 340 80% 8% 12u "..."
                Pop $SNF_SearchFor_Location_ButtonB
                ${NSD_OnClick} $SNF_SearchFor_Location_ButtonB LocateSNFInstallFolder

                StrCmp $SNF_StartLookingHere "" +3 0
                  StrCpy $Compound_Enable1 "1"  ; clear for double ok.
                  ;EnableWindow $NextButton "1" ; enable button, cause if you have 1 you have SOMETHING for the other...
                  Call check_CompoundEnable ; this will enable or hold based on multiple flags....


                nsDialogs::Show
                return

; error handling
          NoIceWarpFound:
                ${NSD_CreateLabel} 0 40 100% 80 "IceWarp was not reliably installed. Either the registry keys do not exist, or The Content.XML file does not exist in the Merak\config\ folder."
                Pop $0
                nsDialogs::Show
                return

          NoAlligateFound:
                ${NSD_CreateLabel} 0 40 100% 80 "Alligate was not reliably installed.  Registry keys do not exist.  Please go back and select another install option."
                Pop $0
                nsDialogs::Show
                return

          NoImailFound:
                ${NSD_CreateLabel} 0 40 100% 80 "IMail was not reliably installed.  Registry keys do not exist.  Please go back and select another install option."
                Pop $0
                nsDialogs::Show
                return
                
          NoSmarterMail:
                ${NSD_CreateLabel} 0 40 100% 80 "Smartermail was not reliably installed.  Registry keys do not exist.  Please go back and select another install option."
                Pop $0
                nsDialogs::Show
                return
          NoMDaemon:
                ${NSD_CreateLabel} 0 40 100% 80 "MDaemon was not reliably installed or registry keys do not exist.  Please go back and select another install option."
                Pop $0
                nsDialogs::Show
                return


FunctionEnd


## ADDINGPLATFORM ## Step 21 These are the specific ( and somewhat redundant ) subs for validating each specific location.  You can alter them
## in order to satisfy the condition that all necessary files/folder exist.  Otherwise, fail the compound enable variable, call check_CompoundEnable, and exit.


Function LocateIceWarpFolder

 nsDialogs::SelectFolderDialog /NOUNLOAD $FindApplicationMessage $R0
        Pop $R0

        ${If} $R0 != error
                # NISIS 2.36
                # ${NSD_SetText} $DIGI.DestinationLocations.DirRequest1 "$R0"
                SendMessage $SNF_SearchFor_Location ${WM_SETTEXT} 0 "STR:$R0"  ; set the text box on the previous screen
        ${EndIf}

        ifFileExists "$R0\config\content.xml" enableNext 0
          MessageBox MB_OK "Unable to locate 'config\content.xml' in this selected folder. Please select the folder where [folder]\config\content.xml will resolve."
          StrCpy $Compound_Enable2 "0"   ; but maybe the declude dir?
          call check_CompoundEnable ; unenable.....
          return
  enableNext:
       StrCpy $IceWarpInstallFolder $R0 

       ; but we can work with that either way.....
       StrCpy $Compound_Enable2 "1"
       call check_CompoundEnable ; unenable.....
    return
FunctionEnd  ;LocateIceWarpInstallFolder

Function LocateKerioFolder
    SendMessage $SNF_SearchFor_Location ${WM_SETTEXT} 0 "STR:Kerio Not Supported yet."
    MessageBox MB_OK "Kerio is not yet supported."
FunctionEnd

Function LocateMailSiteFolder
    SendMessage $SNF_SearchFor_Location ${WM_SETTEXT} 0 "STR:MailSite Not Supported yet."
    MessageBox MB_OK "MailSite is not yet supported."
FunctionEnd

Function LocateSNFInstallFolder
    nsDialogs::SelectFolderDialog /NOUNLOAD $FindINSTDIRMessage $R0
        Pop $R0

        ${If} $R0 != error
           # NISIS 2.36
           # ${NSD_SetText} $DIGI.DestinationLocations.DirRequest1 "$R0"
           SendMessage $SNF_SearchFor_LocationB ${WM_SETTEXT} 0 "STR:$R0"  ; set the text box on the previous screen
        ${EndIf}

        StrCmp $R0 "" 0 testNext    ; Refuse to enable if not completed.... ( will need to have complete code for all folders.... i.e. validation screen)
         EnableWindow $NextButton "0"
         StrCpy $Compound_Enable1 "0"    ; the default is you must declare at least the Sniffer directory....
         return
  testNext:
  
        ; Here we have a challenge.  The user can select the folder IN WHICH the SNF resides.../ will reside... or they can select the SNF folder itself.
        ifFileExists "$R0\SNFClient.exe" 0 testForOldSniffer ; if true, this means it exists... and the user selected the Sniffer directory.
          StrCpy $INSTDIR $R0 ; Store install folder.....
          Goto enableNext
        testForOldSniffer:
        ifFileExists "$R0\snf2check.exe" 0 useThisFolder ; if true, this means it exists... and the user selected an older Sniffer directory.
          StrCpy $INSTDIR $R0 ; Store install folder.....
          Goto enableNext
        useThisFolder:
          ; ok, but we need to determine if the SNF folder was already created here...
          ${GetParent} $R0 $R1 ; put the parent of the selected folder a the SNFServerInstallDir.... and leave the archiver to deal....
          ifFileExists "$R1\SNF\*.*" 0 +3
            StrCpy $INSTDIR $R0  ; User selected the SNF directory...
            Goto EnableNext ; But for our install directory.....
          ifFileExists "$R1\Sniffer\*.*" 0 +3
            StrCpy $INSTDIR $R0  ; User selected the sniffer directory...
            Goto EnableNext ; But for our install directory.....
            
          ; Ok well can't find any normal files, so we'll presume we mean make it here....
          StrCpy $INSTDIR "$R0\SNF" ; Store install folder.....
            CreateDirectory $INSTDIR  ; If its not here, then we'll create it, and set it to SNF...
            
  enableNext:
       SendMessage $SNF_SearchFor_LocationB ${WM_SETTEXT} 0 "STR:$INSTDIR" ; This is the look up for the SNIFFER Location....

       StrCpy $Compound_Enable1 "1"    ; the default is you must declare at least the Sniffer directory....
       Call check_CompoundEnable
           ; This gets called in checkCompoundEnable if all the components agree.....;EnableWindow $NextButton "1"
       return
FunctionEnd  ;LocateSNFInstallFolder

Function LocateSNF4AlligateFolder
 nsDialogs::SelectFolderDialog /NOUNLOAD $FindApplicationMessage $R0
        Pop $R0

        ${If} $R0 != error
                # NISIS 2.36
                # ${NSD_SetText} $DIGI.DestinationLocations.DirRequest1 "$R0"
                SendMessage $SNF_SearchFor_Location ${WM_SETTEXT} 0 "STR:$R0"  ; set the text box on the previous screen
        ${EndIf}

        ifFileExists "$R0\AGFiltSvc.exe" enableNext 0
          MessageBox MB_OK "Unable to locate 'AGFiltSvc.exe' in the selected folder. Please select the folder where Alligate's AGFiltSvc.exe exists."
          StrCpy $Compound_Enable2 "0"   ; but maybe the declude dir?
          call check_CompoundEnable ; unenable.....
          return
  enableNext:
       StrCpy $SNF4AlligateInstallFolder $R0 ; Store declude folder.....
       ifFileExists "$SNF4AlligateInstallFolder\SNF4Alligate.exe" 0 +2
         StrCpy $IsMINIMIInstalled "1"

       ; but we can work with that either way.....
       StrCpy $Compound_Enable2 "1"   ; but maybe the declude dir?
       call check_CompoundEnable ; unenable.....
    return
FunctionEnd

Function LocateMINIMIFolder
 nsDialogs::SelectFolderDialog /NOUNLOAD $FindApplicationMessage $R0
        Pop $R0

        ${If} $R0 != error
                # NISIS 2.36
                # ${NSD_SetText} $DIGI.DestinationLocations.DirRequest1 "$R0"
                SendMessage $SNF_SearchFor_Location ${WM_SETTEXT} 0 "STR:$R0"  ; set the text box on the previous screen
        ${EndIf}

        ifFileExists "$R0\SMTP32.exe" enableNext 0
          MessageBox MB_OK "Unable to locate 'SMTP32.exe' in the selected folder. Please select the folder where IMails SMTP32.exe exists."
          StrCpy $Compound_Enable2 "0"   ; but maybe the declude dir?
          call check_CompoundEnable ; unenable.....
          return
  enableNext:
       StrCpy $MINIMIInstallFolder $R0 ; Store declude folder.....
       ifFileExists "$MINIMIInstallFolder\SNFIMailShim.exe" 0 +2
         StrCpy $IsMINIMIInstalled "1"
         
       ; but we can work with that either way.....
       StrCpy $Compound_Enable2 "1"   ; but maybe the declude dir?
       call check_CompoundEnable ; unenable.....
    return
FunctionEnd

##
Function LocateMDaemonFolder
  nsDialogs::SelectFolderDialog /NOUNLOAD $FindApplicationMessage $R0
        Pop $R0

        ${If} $R0 != error
                # NISIS 2.36
                # ${NSD_SetText} $DIGI.DestinationLocations.DirRequest1 "$R0"
                SendMessage $SNF_SearchFor_Location ${WM_SETTEXT} 0 "STR:$R0"  ; set the text box on the previous screen
        ${EndIf}

        ifFileExists "$R0\SpamAssassin\rules\*.*" nextTest 0
          MessageBox MB_OK "Unable to locate the Spam Assassin rules folder in the chosen MDaemon install location.  Please select the root MDaemon Folder."
          StrCpy $Compound_Enable2 "0"   ; but maybe the declude dir?
          call check_CompoundEnable ; unenable.....
          return
  nextTest:
         ifFileExists "$R0\app\MDaemon.exe" enableNext 0
          MessageBox MB_OK "Unable to locate the [Root]\App\MDaemon.exe folder in the chosen MDaemon install location.  Please select the root MDaemon Folder."
          StrCpy $Compound_Enable2 "0"   ; but maybe the declude dir?
          call check_CompoundEnable ; unenable.....
          return
  
  enableNext:
       StrCpy $MXGuardInstallFolder $R0 ; Store declude folder.....
       StrCpy $IsMXGuardInstalled "1"
       StrCpy $Compound_Enable2 "1"   ; but maybe the declude dir?
       call check_CompoundEnable ; unenable.....
    return
FunctionEnd


Function LocateMXGuardFolder
  nsDialogs::SelectFolderDialog /NOUNLOAD $FindApplicationMessage $R0
        Pop $R0

        ${If} $R0 != error
                # NISIS 2.36
                # ${NSD_SetText} $DIGI.DestinationLocations.DirRequest1 "$R0"
                SendMessage $SNF_SearchFor_Location ${WM_SETTEXT} 0 "STR:$R0"  ; set the text box on the previous screen
        ${EndIf}

        ifFileExists "$R0\mxguard.ini" enableNext 0
          MessageBox MB_OK "Unable to locate 'mxguard.ini' in the selected folder. Please select the folder where MXGuards .ini file resides."
          StrCpy $Compound_Enable2 "0"   ; but maybe the declude dir?
          call check_CompoundEnable ; unenable.....
          return
  enableNext:
       StrCpy $MXGuardInstallFolder $R0 ; Store declude folder.....
       StrCpy $IsMXGuardInstalled "1"
       StrCpy $Compound_Enable2 "1"   ; but maybe the declude dir?
       call check_CompoundEnable ; unenable.....
    return
FunctionEnd




Function LocateDecludeFolder
    nsDialogs::SelectFolderDialog /NOUNLOAD $FindApplicationMessage $R0
        Pop $R0

        ${If} $R0 != error
                # NISIS 2.36
                # ${NSD_SetText} $DIGI.DestinationLocations.DirRequest1 "$R0"
                SendMessage $SNF_SearchFor_Location ${WM_SETTEXT} 0 "STR:$R0"  ; set the text box on the previous screen
        ${EndIf}

        ifFileExists "$R0\global.cfg" enableNext 0
          MessageBox MB_OK "Unable to locate 'global.cfg' in the selected folder. Please select the folder where Decludes global.cfg resides."
          StrCpy $Compound_Enable2 "0"   ; but maybe the declude dir?
          call check_CompoundEnable ; unenable.....
          return
  enableNext:
       StrCpy $DecludeInstallFolder $R0 ; Store declude folder.....
       StrCpy $IsDecludeInstalled "1"
       StrCpy $Compound_Enable2 "1"   ; but maybe the declude dir?
       call check_CompoundEnable ; unenable.....
    return
FunctionEnd


Function LocateSmarterMailFolder
    nsDialogs::SelectFolderDialog /NOUNLOAD $FindApplicationMessage $R0
        Pop $R0

        ${If} $R0 != error
                # NISIS 2.36
                # ${NSD_SetText} $DIGI.DestinationLocations.DirRequest1 "$R0"
                SendMessage $SNF_SearchFor_Location ${WM_SETTEXT} 0 "STR:$R0"  ; set the text box on the previous screen
        ${EndIf}

        ifFileExists "$R0\global.cfg" enableNext 0
          MessageBox MB_OK "Unable to locate 'global.cfg' in the selected folder. Please select the folder where Decludes global.cfg resides."
          StrCpy $Compound_Enable2 "0"   ; but maybe the declude dir?
          call check_CompoundEnable ; unenable.....
          return
  enableNext:
       StrCpy $DecludeInstallFolder $R0 ; Store declude folder.....
       StrCpy $IsDecludeInstalled "1"
       StrCpy $Compound_Enable2 "1"   ; but maybe the declude dir?
       call check_CompoundEnable ; unenable.....
    return

FunctionEnd

## ADDINGPLATFORM ## Step 22
## Open the Restorer executable, and add all the file adjustment code there.  ( Don't forget to use the rollback features to preserve any files that you
## are touching, for the one time rollback.  ( Continue the same keyword thread in that file, in order to complete this process. GL.
##


