rendered paste body; ---------------------
; WinVer.nsh
; ---------------------
;
; LogicLib extensions for handling Windows versions.
;
; IsNT checks if the installer is running on Windows NT family (NT4, 2000, XP, etc.)
;
; ${If} ${IsNT}
; DetailPrint "Running on NT. Installing Unicode enabled application."
; ${Else}
; DetailPrint "Not running on NT. Installing ANSI application."
; ${EndIf}
;
; AtLeastWin<version> checks if the installer is running on Windows version at least as specified.
; IsWin<version> checks if the installer is running on Windows version exactly as specified.
; AtMostWin<version> checks if the installer is running on Windows version at most as specified.
;
; <version> can be replaced with the following values:
;
; 95
; 98
; 98SE
; ME
;
; NT4
; 2000
; 2000Srv
; XP
; XP64
; 2003
; Vista
; 2008
;
; Usage examples:
;
; ${If} ${IsNT}
; DetailPrint "Running on NT family."
; DetailPrint "Surely not running on 95, 98 or ME."
; ${AndIf} ${AtLeastWinNT4}
; DetailPrint "Running on NT4 or better. Could even be 2003."
; ${EndIf}
;
; ${If} ${AtLeastWinXP}
; DetailPrint "Running on XP or better."
; ${EndIf}
;
; ${If} ${IsWin2000}
; DetailPrint "Running on 2000."
; ${EndIf}
;
; ${If} ${AtMostWinXP}
; DetailPrint "Running on XP or older. Surely not running on Vista. Maybe 98, or even 95."
; ${EndIf}
;
; Warning:
;
; Windows 95 and NT both use the same version number. To avoid getting NT4 misidentified
; as Windows 95 and vice-versa or 98 as a version higher than NT4, always use IsNT to
; check if running on the NT family.
;
; ${If} ${AtLeastWin95}
; ${And} ${AtMostWinME}
; DetailPrint "Running 95, 98 or ME."
; DetailPrint "Actually, maybe it's NT4?"
; ${If} ${IsNT}
; DetailPrint "Yes, it's NT4! oops..."
; ${Else}
; DetailPrint "Nope, not NT4. phew..."
; ${EndIf}
; ${EndIf}
!verbose push
!verbose 3
!ifndef ___WINVER__NSH___
!define ___WINVER__NSH___
!include LogicLib.nsh
!define _WINVER_NTBIT 0x00000001
!define _WINVER_NTSRVBIT 0x00000002
!ifdef WINVER_USEBUILDNUMBERS
!define _WINVER_VERMASK 0xFFFFFFFE ;Packed version with everything except the NT bit
!define _WINVER_VEROLDMASK ${_WINVER_VERMASK}
!else
!define _WINVER_VERMASK 0xFFFF0002 ;No build numbers, emulates old WinVer.h (except for the new server tests)
!define _WINVER_VEROLDMASK 0xFFFF0000
!endif
!define /math WINVER_95 0x4000ED8 & ${_WINVER_VEROLDMASK} ;4.00.0950
!define /math WINVER_98 0x40A1F38 & ${_WINVER_VEROLDMASK} ;4.10.1998
!define /math WINVER_98SE 0x40A22B8 & ${_WINVER_VERMASK} ;4.10.2222
!define /math WINVER_ME 0x45A2EE0 & ${_WINVER_VEROLDMASK} ;4.90.3000
;define /math WINVER_NT3d51 0x3331084 & ${_WINVER_VERMASK} ;3.51.1057 ;Why bother?
!define /math WINVER_NT4 0x4001594 & ${_WINVER_VEROLDMASK} ;4.00.1381
;define /math WINVER_NT4Srv 0x4001596 & ${_WINVER_VERMASK} ;TODO: On <NT4SP6 you need to check the registry
!define /math WINVER_2000 0x500224C & ${_WINVER_VEROLDMASK} ;5.00.2195
!define /math WINVER_2000Srv 0x500224E & ${_WINVER_VERMASK}
!define /math WINVER_XP 0x50128A0 & ${_WINVER_VEROLDMASK} ;5.01.2600
!define /math WINVER_XP64 0x5023B38 & ${_WINVER_VERMASK} ;5.02.3790
!define /math WINVER_2003 0x5023B3A & ${_WINVER_VEROLDMASK} ;5.02.3790
!define /math WINVER_VISTA 0x6005DC0 & ${_WINVER_VEROLDMASK} ;6.00.6000
!define /math WINVER_VISTASP1 0x6005DC4 & ${_WINVER_VERMASK} ;6.00.6001 ;First SP ever to change the build number?
!define /math WINVER_2008 0x6005DC6 & ${_WINVER_VERMASK} ;6.00.6001
!ifndef __WINVER_VARS__
!define __WINVER_VARS__
var /Global __WINVERV ; 0xMmmBBBX, where M=major, mm=minor, BBB(and top 6 bits of X)=build
var /Global __WINVERSP ; TODO: Store oviex.wSuiteMask here aswell?
!endif
!macro __WinVer_InitVars
!ifndef __WinVer_InitVars
!define __WinVer_InitVars
!define _WINVER_PARSEVER_OLDSP _WINVER_LblInitVars${__LINE__}
!define _WINVER_PARSEVER_NT4SP _WINVER_LblInitVars${__LINE__}
!define _WINVER_PARSEVER_SPDONE _WINVER_LblInitVars${__LINE__}
!insertmacro _LOGICLIB_TEMP
Push $0
Push $1
System::Call /NoUnload '*(i 156,i,i,i,i,&t128,&i2,&i2,&i2,&i1,&i1)i.r1'
System::Call /NoUnload kernel32::GetVersionEx(ir1).r0
StrCmp $0 0 0 +3
System::Call /NoUnload '*$1(i 148)' ; < NT4SP6 or Win9x, call again with smaller struct
System::Call /NoUnload kernel32::GetVersionEx(ir1)
System::Call /NoUnload '*$1(i.s,i.r0,i.s,i.s,i.s,&t128.s,&i2.s,&i2,&i2,&i1.s,&i1)'
System::Free $1
pop $_LOGICLIB_TEMP ;store size of struct so we know how to detect the service pack
; VerMajor
IntOp $__WINVERV $0 << 24
; VerMinor
pop $0
IntOp $0 $0 << 16
IntOp $__WINVERV $__WINVERV | $0
; VerBuild & Platform
pop $0 ;dwBuildNumber
pop $1 ;PlatformID
StrCmp $1 2 0 +3 ;NT?
IntOp $__WINVERV $__WINVERV | ${_WINVER_NTBIT}
goto +2
IntOp $0 $0 & 0xFFFF ;Stupid Win9x has major and minor version info in the high word of dwBuildNumber (Yes, really!)
IntOp $0 $0 << 2
IntOp $__WINVERV $__WINVERV | $0
; Service pack
pop $1 ;ovi.szCSDVersion
pop $0 ;oviex.wServicePackMajor
StrCmp 148 $_LOGICLIB_TEMP ${_WINVER_PARSEVER_OLDSP}
StrCpy $__WINVERSP $0
goto ${_WINVER_PARSEVER_SPDONE}
${_WINVER_PARSEVER_OLDSP}:
StrCpy $__WINVERSP 0
StrCpy $0 $1 1
StrCmp $0 "S" ${_WINVER_PARSEVER_NT4SP} ;"Service Pack X"
StrCmp $0 "A" 0 +2
StrCpy $__WINVERSP 1
StrCmp $0 "B" 0 +2
StrCpy $__WINVERSP 2
StrCmp $0 "C" 0 +2
StrCpy $__WINVERSP 3
goto ${_WINVER_PARSEVER_SPDONE}
${_WINVER_PARSEVER_NT4SP}:
StrCpy $__WINVERSP $1 1 13
${_WINVER_PARSEVER_SPDONE}:
; NT Server?
pop $0
IntCmp $0 1 +2 +2 ;oviex.wProductType > VER_NT_WORKSTATION
IntOp $__WINVERV $__WINVERV | ${_WINVER_NTSRVBIT}
pop $1
pop $0
!undef _WINVER_PARSEVER_OLDSP
!undef _WINVER_PARSEVER_NT4SP
!undef _WINVER_PARSEVER_SPDONE
!endif
!macroend
!macro __WinVer_GetPackedVer
!insertmacro __WinVer_InitVars
IntOp $_LOGICLIB_TEMP $__WINVERV & ${_WINVER_VERMASK}
!macroend
!macro _WinVerAtLeast _a _b _t _f
!insertmacro __WinVer_GetPackedVer
!insertmacro _>= $_LOGICLIB_TEMP `${_b}` `${_t}` `${_f}`
!macroend
!macro _WinVerIs _a _b _t _f
!insertmacro __WinVer_GetPackedVer
!insertmacro _= $_LOGICLIB_TEMP `${_b}` `${_t}` `${_f}`
!macroend
!macro _WinVerAtMost _a _b _t _f
!insertmacro __WinVer_GetPackedVer
!insertmacro _<= $_LOGICLIB_TEMP `${_b}` `${_t}` `${_f}`
!macroend
!macro __WinVer_DefineOSTest Test OS
!define ${Test}Win${OS} `"" WinVer${Test} ${WINVER_${OS}}`
!macroend
!macro __WinVer_DefineOSTests Test
!insertmacro __WinVer_DefineOSTest ${Test} 95
!insertmacro __WinVer_DefineOSTest ${Test} 98
!insertmacro __WinVer_DefineOSTest ${Test} 98SE
!insertmacro __WinVer_DefineOSTest ${Test} ME
!insertmacro __WinVer_DefineOSTest ${Test} NT4
!insertmacro __WinVer_DefineOSTest ${Test} 2000
!insertmacro __WinVer_DefineOSTest ${Test} 2000Srv
!insertmacro __WinVer_DefineOSTest ${Test} XP
!insertmacro __WinVer_DefineOSTest ${Test} XP64
!insertmacro __WinVer_DefineOSTest ${Test} 2003
!insertmacro __WinVer_DefineOSTest ${Test} VISTA
!insertmacro __WinVer_DefineOSTest ${Test} VISTASP1
!insertmacro __WinVer_DefineOSTest ${Test} 2008
!macroend
!insertmacro __WinVer_DefineOSTests AtLeast
!insertmacro __WinVer_DefineOSTests Is
!insertmacro __WinVer_DefineOSTests AtMost
!macro _IsNT _a _b _t _f
!insertmacro __WinVer_InitVars
IntOp $_LOGICLIB_TEMP $__WINVERV & ${_WINVER_NTBIT}
!insertmacro _!= $_LOGICLIB_TEMP 0 `${_t}` `${_f}`
!macroend
!define IsNT `"" IsNT ""`
!macro _IsServerOS _a _b _t _f
!insertmacro __WinVer_InitVars
IntOp $_LOGICLIB_TEMP $__WINVERV & ${_WINVER_NTSRVBIT}
!insertmacro _!= $_LOGICLIB_TEMP 0 `${_t}` `${_f}`
!macroend
!define IsServerOS `"" IsServerOS ""`
!macro _WinVer_SysMetricCheck m _b _t _f
!insertmacro _LOGICLIB_TEMP
System::Call user32::GetSystemMetrics(i${m})i.s
pop $_LOGICLIB_TEMP
!insertmacro _!= $_LOGICLIB_TEMP 0 `${_t}` `${_f}`
!macroend
!define IsWin2003R2 `89 WinVer_SysMetricCheck ""`
!define IsStarterEdition `88 WinVer_SysMetricCheck ""`
!define OSHasMediaCenter `87 WinVer_SysMetricCheck ""`
!define OSHasTabletSupport `86 WinVer_SysMetricCheck ""`
!macro __WinVer_GetVer shift mask outvar
!insertmacro __WinVer_InitVars
IntOp ${outvar} $__WINVERV >> ${shift}
!if "${mask}" != ""
IntOp ${outvar} ${outvar} & ${mask}
!endif
!macroend
!define GetWinVerMajor '!insertmacro __WinVer_GetVer 24 "" ' ;when windows 127 comes out, you might need to start thinking about adding a mask here unless we have UintOp by then ;)
!define GetWinVerMinor '!insertmacro __WinVer_GetVer 16 0xFF '
!define GetWinVerBuild '!insertmacro __WinVer_GetVer 2 0x3FFF '
!endif # !___WINVER__NSH___
!verbose pop
###################################################################################################
###################################################################################################
###################################################################################################
## EOF # EOF # EOF # EOF # EOF # EOF # EOF # EOF # EOF # EOF # EOF # EOF # EOF # EOF # EOF # EOF ##
###################################################################################################
###################################################################################################
###################################################################################################
outfile WinVerTest.exe
page instfiles "" s
showinstdetails show
;!include WinVer.nsh
!macro StrAtleast v len
push $R9
StrLen $R9 ${v}
IntOp $R9 ${len} - $R9
${DoWhile} $R9 > 0
IntOp $R9 $R9 - 1
StrCpy ${v} "${v} "
${Loop}
pop $R9
!macroend
!macro test3 os def
StrCpy $0 "${os}: "
!insertmacro StrAtleast $0 13
${IfThen} ${AtMost${os}} ${|} StrCpy $0 "$0<=" ${|}
!insertmacro StrAtleast $0 16
${IfThen} ${Is${os}} ${|} StrCpy $0 "$0==" ${|}
!insertmacro StrAtleast $0 19
${IfThen} ${AtLeast${os}} ${|} StrCpy $0 "$0>=" ${|}
!if "${def}" != ""
!insertmacro StrAtleast $0 21
IntFmt $1 "0x%X" $_LOGICLIB_TEMP
IntFmt $2 "0x%X" ${${def}}
StrCpy $0 "$0|$2=$1|${def}"
!endif
DetailPrint $0
!macroend
Section
${GetWinVerMajor} $0
${GetWinVerMinor} $1
${GetWinVerBuild} $2
IntFmt $9 "0x%X" $__WINVERV
IntFmt $8 "0x%X" $__WINVERSP
${IfThen} ${IsServerOS} ${|} StrCpy $8 "$8|NTSRV" ${|}
${IfThen} ${IsWin2003R2} ${|} StrCpy $8 "$8|Win2k3R2" ${|}
${IfThen} ${IsStarterEdition} ${|} StrCpy $8 "$8|START" ${|}
${IfThen} ${OSHasMediaCenter} ${|} StrCpy $8 "$8|MCE" ${|}
${IfThen} ${OSHasTabletSupport} ${|} StrCpy $8 "$8|TABLET" ${|}
StrCpy $3 "9x"
${IfThen} ${IsNT} ${|} StrCpy $3 "NT" ${|}
DetailPrint "Win$3 $0.$1.$2 |$9 SP=$8"
DetailPrint " "
!insertmacro test3 Win95 WINVER_95
!insertmacro test3 Win98 WINVER_98
!insertmacro test3 Win98SE WINVER_98SE
!insertmacro test3 WinME WINVER_ME
!insertmacro test3 WinNT4 WINVER_NT4
!insertmacro test3 Win2000 WINVER_2000
!insertmacro test3 Win2000Srv WINVER_2000Srv
!insertmacro test3 WinXP WINVER_XP
!insertmacro test3 WinXP64 WINVER_XP64
!insertmacro test3 Win2003 WINVER_2003
!insertmacro test3 WinVista WINVER_VISTA
!insertmacro test3 WinVistaSP1 WINVER_VISTASP1
!insertmacro test3 Win2008 WINVER_2008
SectionEnd
Function s
!include WinMessages.nsh
FindWindow $0 "#32770" "" $HWNDPARENT
GetDlgItem $0 $0 0x3F8
CreateFont $1 "Courier" 8 0
SendMessage $0 ${WM_SETFONT} $1 1
FunctionEnd