All pastes #1048713 Raw Edit

WinVer 2008 #2

public text v1 · immutable
#1048713 ·published 2008-06-17 03:47 UTC
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