1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
|
; Licensed under the zlib/libpng license (same as NSIS)
!ifndef CPIO_INCLUDED
!define CPIO_INCLUDED
!include include\stdmacros.nsh
!include LogicLib.nsh
!include Win\WinError.nsh
!define CPIO_PREFIX "CPIO_"
!define CPIO_UNFUNC "un."
!ifndef CPIO_BUFFER_SIZE
!define CPIO_BUFFER_SIZE 262144
!endif
!define CPIO_BY_HANDLE_FILEINFO_SIZE 52
!define CPIO_MODE_REGULAR_FILE 0x8000
!define CPIO_MODE_USER_WRITE 0x0080
!define CPIO_MODE_USER_READ 0x0100
!define CPIO_MODE_GROUP_WRITE 0x0010
!define CPIO_MODE_GROUP_READ 0x0020
!define CPIO_MODE_OTHER_WRITE 0x0002
!define CPIO_MODE_OTHER_READ 0x0004
!define /math CPIO_MODE_DEFAULT_FILE ${CPIO_MODE_REGULAR_FILE} + ${CPIO_MODE_USER_WRITE}
!define /redef /math CPIO_MODE_DEFAULT_FILE ${CPIO_MODE_DEFAULT_FILE} + ${CPIO_MODE_USER_READ}
!define /redef /math CPIO_MODE_DEFAULT_FILE ${CPIO_MODE_DEFAULT_FILE} + ${CPIO_MODE_GROUP_READ}
!define /redef /math CPIO_MODE_DEFAULT_FILE ${CPIO_MODE_DEFAULT_FILE} + ${CPIO_MODE_OTHER_READ}
!define CPIO_NEWC_MAGIC "070701"
!define CPIO_FILETIME_TICKS_PER_SEC 10000000
!define CPIO_SEC_TO_UNIX_EPOCH 11644473600
!define CPIO_FUNCDEF \
`!insertmacro STDMACROS_FUNCDEF ${CPIO_PREFIX}`
!define CPIO_FUNCINC \
`!insertmacro STDMACROS_FUNCINC ${CPIO_PREFIX}`
!define CPIO_FUNCPROLOG \
`!insertmacro STDMACROS_FUNCPROLOG ${CPIO_PREFIX}`
!macro CPIO_Padding BUFFER COUNT
IntOp ${COUNT} ${COUNT} & 3
System::Call "*${BUFFER}(&i${COUNT} 0)"
!macroend
; ${CPIO_Header} fileinfo filemode filesize namesize result
${CPIO_FUNCDEF} Header
!macro CPIO_Header_Call UN FILEINFO FILEMODE FILESIZE NAMESIZE RESULT
Push ${FILEINFO}
Push ${FILEMODE}
Push ${FILESIZE}
Push ${NAMESIZE}
Call `${UN}${CPIO_PREFIX}Header`
Pop ${RESULT}
!macroend
; ${CPIO_Filter} filehandle buffer len result
${CPIO_FUNCDEF} Filter
!macro CPIO_Filter_Call UN FILEHANDLE BUFFER LEN RESULT
Push ${FILEHANDLE}
Push ${BUFFER}
Push ${LEN}
Call `${UN}${CPIO_PREFIX}Filter`
Pop ${RESULT}
!macroend
; ${CPIO_Write_Filter} filehandle filename filter result
${CPIO_FUNCDEF} Write_Filter
!macro CPIO_Write_Filter_Call UN FILEHANDLE FILENAME RESULT
Push ${FILEHANDLE}
Push "${FILENAME}"
Push ${FILTER}
Call `${UN}${CPIO_PREFIX}Write_Filter`
Pop ${RESULT}
!macroend
; ${CPIO_Write} filehandle filename result
${CPIO_FUNCDEF} Write
!macro CPIO_Write_Call UN FILEHANDLE FILENAME RESULT
Push ${FILEHANDLE}
Push "${FILENAME}"
Call `${UN}${CPIO_PREFIX}Write`
Pop ${RESULT}
!macroend
!macro CPIO_Header UN
; Create CPIO header
; Parameters:
; fileinfo - file information obtained via GetFileInformationByHandle
; filemode - file mode definition
; filesize - size of file in bytes
; namesize - size of file name including terminating zero
; Return value:
; CPIO header
${CPIO_FUNCPROLOG} "${UN}" Header
System::Store 'S'
Pop $5
Pop $4
Pop $3
Pop $2
StrCpy $0 "${CPIO_NEWC_MAGIC}"
; Use nFileIndexLow as inode
System::Call "*$2(&v48,&i4 .r1)"
IntFmt $0 "$0%08X" $1
; File mode
IntFmt $0 "$0%08X" $3
; User identifier
IntFmt $1 "%08X" 0
StrCpy $0 "$0$1"
; Group identifier
StrCpy $0 "$0$1"
; Number of links
System::Call "*$2(&v40,&i4 .r1)"
IntFmt $0 "$0%08X" $1
; Last modified time
${If} $3 != 0
System::Call "*$2(&v20,l .r1)"
; Convert file to unix time
System::Int64Op $1 / ${CPIO_FILETIME_TICKS_PER_SEC}
Pop $1
System::Int64Op $1 - ${CPIO_SEC_TO_UNIX_EPOCH}
Pop $1
${Else}
StrCpy $1 0
${EndIf}
IntFmt $0 "$0%08X" $1
; Size of file
IntFmt $0 "$0%08X" $4
; Device major and minor identifier
System::Call "*$2(&v28,&i4 .r1)"
Push $1
IntOp $1 $1 & 0xFF
IntFmt $0 "$0%08X" $1
Pop $1
IntOp $1 $1 >>> 8
IntFmt $0 "$0%08X" $1
; Special device major and minor identifier
IntFmt $1 "%08X" 0
StrCpy $0 "$0$1"
StrCpy $0 "$0$1"
; Size of name
IntFmt $0 "$0%08X" $5
; Check
IntFmt $0 "$0%08X" 0
Push $0
System::Store 'L'
FunctionEnd
!macroend ; CPIO_Header
!macro CPIO_Filter UN
; Write buffer to file
; Parameters:
; filehandle - writable file handle
; buffer - buffer to be written
; len - size of buffer in bytes
; Return value:
; Non zero value if successful
${CPIO_FUNCPROLOG} "${UN}" Filter
Push $0
Exch 3
Exch $1
Exch 2
Exch $2
Exch
Exch $3
System::Call "kernel32::WriteFile(p r1, p r2, i r3, *i .r3, p 0) i.r0"
Pop $3
Pop $2
Pop $1
Exch $0
FunctionEnd
!macroend ; CPIO_Filter
!macro CPIO_Run_Filter FUNCTION FILEHANDLE BUFFER LEN RESULT
Push ${FILEHANDLE}
Push ${BUFFER}
Push ${LEN}
Call ${FUNCTION}
Pop ${RESULT}
!macroend
!macro CPIO_Write_Filter UN
${CPIO_FUNCINC} "${UN}" Header
; Write CPIO entry of given file name to file handle via filter function
; Parameters:
; filehandle - writable file handle
; filename - name of file to be added
; filter - output filter function
; Return value:
; 0 if successful otherwise error code
${CPIO_FUNCPROLOG} "${UN}" Write_Filter
System::Store 'S'
Pop $R0
Pop $4
Pop $1
StrCpy $0 ${ERROR_OUTOFMEMORY}
System::Alloc ${CPIO_BY_HANDLE_FILEINFO_SIZE}
Pop $3
${If} $3 P<> 0
StrCpy $0 0
${If} $4 != ""
ClearErrors
FileOpen $2 "$4" r
${If} ${Errors}
StrCpy $0 ${ERROR_FILE_NOT_FOUND}
${Else}
System::Call "kernel32::GetFileSize(p r2, p 0) i.r6"
System::Call "kernel32::GetFileInformationByHandle(p r2, p r3) i.r5"
${If} $5 != 0
StrCpy $0 0
StrCpy $5 ${CPIO_MODE_DEFAULT_FILE}
${Else}
System::Call "kernel32::GetLastError() i.r0"
${EndIf}
${EndIf}
${Else}
StrCpy $2 ""
StrCpy $4 "TRAILER!!!"
StrCpy $5 0
StrCpy $6 0
${EndIf}
${If} $0 == 0
StrLen $7 $4
IntOp $7 $7 + 1
!insertmacro CPIO_Header_Call "${UN}" $3 $5 $6 $7 $5
${EndIf}
System::Free $3
${EndIf}
${If} $0 == 0
StrCpy $9 ${CPIO_BUFFER_SIZE}
System::Alloc $9
Pop $3
${If} $3 P<> 0
StrLen $8 $5
System::Call "*$3(&m$8 r5)"
!insertmacro CPIO_Run_Filter $R0 $1 $3 $8 $5
${If} $5 != 0
; Name of file
StrCpy $8 $7
System::Call "*$3(&m$8 r4)"
!insertmacro CPIO_Run_Filter $R0 $1 $3 $8 $5
${If} $5 != 0
; Padding
IntOp $8 2 - $7
!insertmacro CPIO_Padding $3 $8
!insertmacro CPIO_Run_Filter $R0 $1 $3 $8 $5
${EndIf}
${EndIf}
${If} $2 != ""
${DoWhile} $5 != 0
System::Call "kernel32::ReadFile(p r2, p r3, i r9, *i .r8, p 0) i.r5"
${If} $5 != 0
!insertmacro CPIO_Run_Filter $R0 $1 $3 $8 $5
${If} $8 < $9
${ExitDo}
${EndIf}
${Else}
${ExitDo}
${EndIf}
${Loop}
${If} $5 != 0
; Padding
IntOp $8 4 - $6
!insertmacro CPIO_Padding $3 $8
!insertmacro CPIO_Run_Filter $R0 $1 $3 $8 $5
${EndIf}
${If} $5 != 0
StrCpy $0 0
${Else}
StrCpy $0 ${ERROR_WRITE_FAULT}
${EndIf}
FileClose $2
${EndIf}
System::Free $3
${Else}
StrCpy $0 ${ERROR_OUTOFMEMORY}
${EndIf}
${EndIf}
Push $0
System::Store 'L'
FunctionEnd
!macroend ; CPIO_Write_Filter
!macro CPIO_Write UN
; Write CPIO entry of given file name to file handle
; Parameters:
; filehandle - writable file handle
; filename - name of file to be added
; Return value:
; 0 if successful otherwise error code
${CPIO_FUNCINC} "${UN}" Filter
${CPIO_FUNCINC} "${UN}" Write_Filter
${CPIO_FUNCPROLOG} "${UN}" Write
Push $0
GetFunctionAddress $0 `${UN}${CPIO_PREFIX}Filter`
Exch $0
Call `${UN}${CPIO_PREFIX}Write_Filter`
FunctionEnd
!macroend ; CPIO_Write
!endif ; CPIO_INCLUDED
|