odoo/setup/windows/contrib.nsh

329 lines
7.6 KiB
Plaintext

# Source: http://nsis.sourceforge.net/CharToASCII
!include LogicLib.nsh
!ifndef CHAR_TO_ASCII_NSH
!define CharToASCII "!insertmacro CharToASCII"
!macro CharToASCII AsciiCode Character
Push "${Character}"
Call CharToASCII
Pop "${AsciiCode}"
!macroend
Function CharToASCII
Exch $0 ; given character
Push $1 ; current character
Push $2 ; current Ascii Code
StrCpy $2 1 ; right from start
Loop:
IntFmt $1 %c $2 ; Get character from current ASCII code
${If} $1 S== $0 ; case sensitive string comparison
StrCpy $0 $2
Goto Done
${EndIf}
IntOp $2 $2 + 1
StrCmp $2 255 0 Loop ; ascii from 1 to 255
StrCpy $0 0 ; ASCII code wasn't found -> return 0
Done:
Pop $2
Pop $1
Exch $0
FunctionEnd
!endif ; CHAR_TO_ASCII_NSH
# Source: http://nsis.sourceforge.net/Base64
!ifndef BASE64_NSH
!define BASE64_NSH
!define BASE64_ENCODINGTABLE "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
!define BASE64_ENCODINGTABLEURL "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
!define BASE64_PADDING "="
VAR OCTETVALUE
VAR BASE64TEMP
!define Base64_Encode "!insertmacro Base64_Encode"
!define Base64_URLEncode "!insertmacro Base64_URLEncode"
!macro Base64_Encode _cleartext
push $R0
push $R1
push $R2
push $0
push $1
push $2
push $3
push $4
push $5
push $6
push $7
push `${_cleartext}`
push `${BASE64_ENCODINGTABLE}`
Call Base64_Encode
Pop $BASE64TEMP
Pop $7
Pop $6
Pop $5
Pop $4
Pop $3
Pop $2
Pop $1
Pop $0
pop $R2
pop $R1
pop $R0
Push $BASE64TEMP
!macroend
!macro Base64_URLEncode _cleartext
push $R0
push $R1
push $R2
push $0
push $1
push $2
push $3
push $4
push $5
push $6
push $7
push `${_cleartext}`
push `${BASE64_ENCODINGTABLEURL}`
Call Base64_Encode
Pop $BASE64TEMP
Pop $7
Pop $6
Pop $5
Pop $4
Pop $3
Pop $2
Pop $1
Pop $0
pop $R2
pop $R1
pop $R0
Push $BASE64TEMP
!macroend
Function Base64_Encode
pop $R2 ; Encoding table
pop $R0 ; Clear Text
StrCpy "$R1" "" # The result
StrLen $1 "$R0"
StrCpy $0 0
${WHILE} $0 < $1
# Copy 3 characters, and for each character push their value.
StrCpy $OCTETVALUE 0
StrCpy $5 $0
StrCpy $4 "$R0" 1 $5
${CharToASCII} $4 "$4"
IntOp $OCTETVALUE $4 << 16
IntOp $5 $5 + 1
${IF} $5 < $1
StrCpy $4 "$R0" 1 $5
${CharToASCII} $4 "$4"
IntOp $4 $4 << 8
IntOp $OCTETVALUE $OCTETVALUE + $4
IntOp $5 $5 + 1
${IF} $5 < $1
StrCpy $4 "$R0" 1 $5
${CharToASCII} $4 "$4"
IntOp $OCTETVALUE $OCTETVALUE + $4
${ENDIF}
${ENDIF}
# Now take the 4 indexes from the encoding table, based on 6bits each of the octet's value.
IntOp $4 $OCTETVALUE >> 18
IntOp $4 $4 & 63
StrCpy $5 "$R2" 1 $4
StrCpy $R1 "$R1$5"
IntOp $4 $OCTETVALUE >> 12
IntOp $4 $4 & 63
StrCpy $5 "$R2" 1 $4
StrCpy $R1 "$R1$5"
StrCpy $6 $0
StrCpy $7 2
IntOp $6 $6 + 1
${IF} $6 < $1
IntOp $4 $OCTETVALUE >> 6
IntOp $4 $4 & 63
StrCpy $5 "$R2" 1 $4
StrCpy $R1 "$R1$5"
IntOp $7 $7 - 1
${ENDIF}
IntOp $6 $6 + 1
${IF} $6 < $1
IntOp $4 $OCTETVALUE & 63
StrCpy $5 "$R2" 1 $4
StrCpy $R1 "$R1$5"
IntOp $7 $7 - 1
${ENDIF}
# If there is any padding required, we now write that here.
${IF} $7 > 0
${WHILE} $7 > 0
StrCpy $R1 "$R1${BASE64_PADDING}"
IntOp $7 $7 - 1
${ENDWHILE}
${ENDIF}
IntOp $0 $0 + 3
${ENDWHILE}
Push "$R1"
FunctionEnd
!define Base64_Decode "!insertmacro Base64_Decode"
!define Base64_URLDecode "!insertmacro Base64_URLDecode"
!macro Base64_Decode _encodedtext
push `${_encodedtext}`
push `${BASE64_ENCODINGTABLE}`
Call Base64_Decode
!macroend
!macro Base64_URLDecode _encodedtext
push `${_encodedtext}`
push `${BASE64_ENCODINGTABLEURL}`
Call Base64_Decode
!macroend
Function base64_Decode
; Stack: strBase64table strEncoded
Push $9 ; Stack: $9 strBase64table strEncoded ; $9 = strDecoded
Exch 2 ; Stack: strEncoded strBase64table $9
Exch ; Stack: strBase64table strEncoded $9
Exch $0 ; Stack: $0 strEncoded $9 ; $0 = strBase64table
Exch ; Stack: strEncoded $0 $9
Exch $1 ; Stack: $1 $0 $9 ; $1 = strEncoded
Push $2 ; strBase64table.length
Push $3 ; strEncoded.length
Push $4 ; strBase64table.counter
Push $5 ; strEncoded.counter
Push $6 ; strBase64table.char
Push $7 ; strEncoded.char
Push $R0 ; 6bit-group.counter
Push $R1 ; 6bit-group.a
Push $R2 ; 6bit-group.b
Push $R3 ; 6bit-group.c
Push $R4 ; 6bit-group.d
Push $R5 ; bit-group.tempVar.a
Push $R6 ; bit-group.tempVar.b
Push $R7 ; 8bit-group.A
Push $R8 ; 8bit-group.B
Push $R9 ; 8bit-group.C
StrCpy $9 "" ; Result string
StrLen $2 "$0" ; Get the length of the base64 table into $2
StrLen $3 "$1" ; Get the length of the encoded text into $3
IntOp $3 $3 - 1 ; Subtract one as the StrCpy offset is zero-based
StrCpy $R0 4 ; Initialize the 6bit-group.counter
${ForEach} $5 0 $3 + 1 ; Loop over the encoded string
StrCpy $7 $1 1 $5 ; Grab the character at the loop counter's index
${If} $7 == "${BASE64_PADDING}" ; If it's the padding char
Push 0 ; Push value 0 (no impact on decoded string)
${Else} ; Otherwise
${ForEach} $4 0 $2 + 1 ; Loop over the base64 lookup table
StrCpy $6 $0 1 $4 ; Grab the character at this loop counter's index
${If} $6 S== $7 ; If that character matches the encoded string character
${ExitFor} ; Exit this loop early
${EndIf}
${Next}
Push $4 ; Push the lookup's index to the stack
${EndIf}
IntOp $R0 $R0 - 1 ; Decrease the 6bit-group counter
${If} $R0 = 0 ; If that counter reaches zero
; Pop the index values off the stack to variables
Pop $R4
Pop $R3
Pop $R2
Pop $R1
; The way the base64 decoding works is like this...
; Normal ASCII has 8 bits, base64 has 6 bits.
; Those 8 bits need to be presented as 6 bits somehow
; Turns out you can easily do that by taking their common multiple: 24
; This results in 3 8bit characters per each 4 6bit characters:
; AAAAAAAA BBBBBBBB CCCCCCCC
; aaaaaabb bbbbcccc ccdddddd
; So to go back to AAAAAAAA, you need:
; aaaaaa shifted two bits to the left
; the two left-most bits of bbbbbb,
; which you can do by shifting it four bits to the right
IntOp $R5 $R1 << 2
IntOp $R6 $R2 >> 4
IntOp $R5 $R5 | $R6
IntFmt $R7 "%c" $R5 ; IntFmt turns the resulting 8bit value to a character
; For BBBBBBBB, you need:
; the four least significant bits of bbbbbb
; which you can get by binary OR'ing with 2^4-1 = 15
; the four most significant bits of cccccc
; which you can get by just shifting it two bits to the right
IntOp $R5 $R2 & 15
InTop $R5 $R5 << 4
IntOp $R6 $R3 >> 2
IntOp $R5 $R5 | $R6
IntFmt $R8 "%c" $R5
; For CCCCCCCC, the procedure is entirely similar.
IntOp $R5 $R3 & 3
IntOp $R5 $R5 << 6
IntOp $R5 $R5 | $R4
IntFmt $R9 "%c" $R5
StrCpy $9 "$9$R7$R8$R9" ; Tack it all onto the result
StrCpy $R0 4 ; Reset the 6bit-group counter
${EndIf}
${Next}
; Done. Now let's restore the user's variables
Pop $R9
Pop $R8
Pop $R7
Pop $R6
Pop $R5
Pop $R4
Pop $R3
Pop $R2
Pop $R1
Pop $R0
Pop $7
Pop $6
Pop $5
Pop $4
Pop $3
Pop $2
Pop $1
Pop $0
Exch $9 ; Stack: strDecoded
FunctionEnd
!endif ;BASE64_NSH