SysFunc.nsh 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. ; Some useful functions based on System plugin
  2. ;
  3. ; (c) brainsucker, 2002
  4. ; (r) BSForce
  5. ; Check for double includes
  6. !ifndef SysFunc.NSH.Included
  7. !define SysFunc.NSH.Included
  8. !include "${NSISDIR}\Examples\System\System.nsh"
  9. !verbose 3 ; For WinMessages especially
  10. !include "WinMessages.nsh"
  11. !verbose 4
  12. ; ================= GetInstallerExeName implementation =================
  13. ; Adopted Get Parameter function -> now it gets full installer.exe path
  14. ; input - nothing, output -> full path at the top of the stack
  15. Function GetInstallerExeName
  16. Push $R0
  17. Push $R1
  18. Push $R2
  19. StrCpy $R0 $CMDLINE 1
  20. StrCpy $R1 '"'
  21. StrCpy $R2 1
  22. StrCmp $R0 '"' loop
  23. StrCpy $R1 ' ' ; we're scanning for a space instead of a quote
  24. loop:
  25. StrCpy $R0 $CMDLINE 1 $R2
  26. StrCmp $R0 $R1 loop2
  27. StrCmp $R0 "" loop2
  28. IntOp $R2 $R2 + 1
  29. Goto loop
  30. loop2:
  31. ; Ok, have we found last exename character or string end?
  32. StrCmp $R0 "" "" +2
  33. IntOp $R2 $R2 - 1 ; last exename char
  34. StrCmp $R1 ' ' +3 ; was first character the '"', or something other?
  35. StrCpy $R1 1 ; it was quote
  36. Goto +2
  37. StrCpy $R1 0
  38. IntOp $R2 $R2 - $R1
  39. StrCpy $R0 $CMDLINE $R2 $R1
  40. SearchPath $R0 $R0 ; expand file name to full path
  41. Pop $R2
  42. Pop $R1
  43. Exch $R0
  44. FunctionEnd
  45. ; ================= systemGetFileSysTime implementation =================
  46. !macro smGetFileSysTime FILENAME
  47. Push ${FILENAME}
  48. Call systemGetFileSysTime
  49. Pop $R0
  50. !macroend
  51. ; -----------------------------------------------------------------
  52. ; systemGetFileSysTime (params on stack):
  53. ; FILENAME - name of file to get file time
  54. ; returns to stack (SYSTEMTIME struct addr)
  55. ; -----------------------------------------------------------------
  56. ; uses original method from NSIS
  57. Function systemGetFileSysTime
  58. System::Store "s r1"
  59. StrCpy $R0 0
  60. ; create WIN32_FIND_DATA struct
  61. System::Call '*${stWIN32_FIND_DATA} .r2'
  62. ; Find file info
  63. System::Call '${sysFindFirstFile}(r1, r2) .r3'
  64. ; ok?
  65. IntCmp $3 ${INVALID_HANDLE_VALUE} sgfst_exit
  66. ; close file search
  67. System::Call '${sysFindClose}(r3)'
  68. ; Create systemtime struct for local time
  69. System::Call '*${stSYSTEMTIME} .R0'
  70. ; Get File time
  71. System::Call '*$2${stWIN32_FIND_DATA} (,,, .r3)'
  72. ; Convert file time (UTC) to local file time
  73. System::Call '${sysFileTimeToLocalFileTime}(r3, .r1)'
  74. ; Convert file time to system time
  75. System::Call '${sysFileTimeToSystemTime}(r1, R0)'
  76. sgfst_exit:
  77. ; free used memory for WIN32_FIND_DATA struct
  78. System::Free $2
  79. System::Store "P0 l"
  80. FunctionEnd
  81. ; ================= systemMessageBox implementation =================
  82. ; return to $R0
  83. !macro smMessageBox MODULE MSG CAPTION STYLE ICON
  84. Push "${ICON}"
  85. Push "${STYLE}"
  86. Push "${CAPTION}"
  87. Push "${MSG}"
  88. Push "${MODULE}"
  89. Call systemMessageBox
  90. Pop $R0
  91. !macroend
  92. ; -----------------------------------------------------------------
  93. ; systemMessageBox (params on stack):
  94. ; Module: either handle ("i HANDLE", HANDLE could be 0) or "modulename"
  95. ; Msg: text of message
  96. ; Caption: caption of message box window
  97. ; Style: style, buttons etc
  98. ; Icon: either icon handle ("i HANDLE") or resource name
  99. ; returns to stack
  100. ; -----------------------------------------------------------------
  101. Function systemMessageBox
  102. System::Store "s r2r3r4r5r6"
  103. ; may be Module is module handle?
  104. StrCpy $1 $2
  105. IntCmp $1 0 0 smbnext smbnext
  106. ; Get module handle
  107. System::Call '${sysGetModuleHandle}($2) .r1'
  108. IntCmp $1 0 loadlib libnotloaded libnotloaded
  109. loadlib:
  110. ; Load module and get handle
  111. System::Call '${sysLoadLibrary}($2) .r1'
  112. IntCmp $1 0 0 smbnext smbnext
  113. libnotloaded:
  114. ; Indicate that LoadLibrary wasn't used
  115. StrCpy $2 1
  116. smbnext:
  117. ; Create MSGBOXPARAMS structure
  118. System::Call '*${stMSGBOXPARAMS}(, $HWNDPARENT, r1, r3, r4, "$5|${MB_USERICON}", $6, _) .r0'
  119. ; call MessageBoxIndirect
  120. System::Call '${sysMessageBoxIndirect}(r0) .R0'
  121. ; free MSGBOXPARAMS structure
  122. System::Free $0
  123. ; have we used load library at start?
  124. IntCmp $2 0 0 smbskipfree smbskipfree
  125. ; No, then free the module
  126. System::Call '${sysFreeLibrary}(r1)'
  127. smbskipfree:
  128. System::Store "P0 l"
  129. FunctionEnd
  130. ; ================= systemSplash implementation =================
  131. ; returns to $R0
  132. !macro smSystemSplash DELAY FILE
  133. Push ${FILE}
  134. Push ${DELAY}
  135. call systemSplash
  136. Pop $R0
  137. !macroend
  138. ; -----------------------------------------------------------------
  139. ; systemSplash (params on stack):
  140. ; Delay - time in ms to show the splash
  141. ; File - bitmap (& audio) file name (without extension)
  142. ; returns to stack
  143. ; -----------------------------------------------------------------
  144. Function _systemSplashWndCB
  145. ; Callback receives 4 values
  146. System::Store "s r2r5r7r9"
  147. ; Message branching
  148. IntCmp $5 ${WM_CLOSE} m_Close
  149. IntCmp $5 ${WM_TIMER} m_Timer
  150. IntCmp $5 ${WM_LBUTTONDOWN} m_Lbtn
  151. IntCmp $5 ${WM_CREATE} m_Create
  152. IntCmp $5 ${WM_PAINT} m_Paint
  153. goto default
  154. m_Create:
  155. ; Create structures
  156. System::Call "*${stRECT} (_) .R8"
  157. System::Call "*${stBITMAP} (_, &l0 .R7) .R9"
  158. ; Get bitmap info
  159. System::Call "${sysGetObject} (r6, R7, R9)"
  160. ; Get desktop info
  161. System::Call "${sysSystemParametersInfo} (${SPI_GETWORKAREA}, 0, R8, 0)"
  162. ; Style (callbacked)
  163. System::Call "${sysSetWindowLong} (r2, ${GWL_STYLE}, 0) .s"
  164. !insertmacro SINGLE_CALLBACK 5 $R7 1 _systemSplashWndCB
  165. ; Calculate and set window pos
  166. ; Get bmWidth(R2) and bmHeight(R3)
  167. System::Call "*$R9${stBITMAP} (,.R2,.R3)"
  168. ; Get left(R4), top(R5), right(R6), bottom(R7)
  169. System::Call "*$R8${stRECT} (.R4,.R5,.R6,.R7)"
  170. ; Left pos
  171. IntOp $R0 $R6 - $R4
  172. IntOp $R0 $R0 - $R2
  173. IntOp $R0 $R0 / 2
  174. IntOp $R0 $R0 + $R4
  175. ; Top pos
  176. IntOp $R1 $R7 - $R5
  177. IntOp $R1 $R1 - $R3
  178. IntOp $R1 $R1 / 2
  179. IntOp $R1 $R1 + $R5
  180. System::Call "${sysSetWindowPos} (r2, 0, R0, R1, R2, R3, ${SWP_NOZORDER}) .s"
  181. !insertmacro SINGLE_CALLBACK 6 $R7 1 _systemSplashWndCB
  182. ; Show window
  183. System::Call "${sysShowWindow} (r2, ${SW_SHOW}) .s"
  184. !insertmacro SINGLE_CALLBACK 7 $R7 1 _systemSplashWndCB
  185. ; Set Timer
  186. System::Call "${sysSetTimer} (r2, 1, r8,)"
  187. ; Free used memory
  188. System::Free $R8
  189. System::Free $R9
  190. StrCpy $R0 0
  191. goto exit
  192. m_Paint:
  193. ; Create structures
  194. System::Call "*${stRECT} (_) .R8"
  195. System::Call "*${stPAINTSTRUCT} (_) .R9"
  196. ; Begin Paint
  197. System::Call "${sysBeginPaint} (r2, R9) .R7"
  198. ; CreateCompatibleDC
  199. System::Call "${sysCreateCompatibleDC} (R7) .R6"
  200. ; GetClientRect
  201. System::Call "${sysGetClientRect} (r2, R8)"
  202. ; Select new bitmap
  203. System::Call "${sysSelectObject} (R6, r6) .R5"
  204. ; Get left(R0), top(R1), right(R2), bottom(R3)
  205. System::Call "*$R8${stRECT} (.R0,.R1,.R2,.R3)"
  206. ; width=right-left
  207. IntOp $R2 $R2 - $R0
  208. ; height=bottom-top
  209. IntOp $R3 $R3 - $R1
  210. System::Call "${sysBitBlt} (R7, R0, R1, R2, R3, R6, 0, 0, ${SRCCOPY})"
  211. ; Select old bitmap
  212. System::Call "${sysSelectObject} (R6, R5)"
  213. ; Delete compatible DC
  214. System::Call "${sysDeleteDC} (R6)"
  215. ; End Paint
  216. System::Call "${sysEndPaint} (r2, R9)"
  217. ; Free used memory
  218. System::Free $R8
  219. System::Free $R9
  220. StrCpy $R0 0
  221. goto exit
  222. m_Timer:
  223. m_Lbtn:
  224. StrCpy $4 0
  225. IntCmp $5 ${WM_TIMER} destroy
  226. StrCpy $4 1
  227. destroy:
  228. System::Call "${sysDestroyWindow} (r2) .s"
  229. !insertmacro SINGLE_CALLBACK 12 $R4 1 _systemSplashWndCB
  230. default:
  231. ; Default
  232. System::Call "${sysDefWindowProc} (r2, r5, r7, r9) .s"
  233. !insertmacro SINGLE_CALLBACK 14 $R0 1 _systemSplashWndCB
  234. goto exit
  235. m_Close:
  236. StrCpy $R0 0
  237. goto exit
  238. exit:
  239. ; Restore
  240. System::Store "p4P0 l R0r4"
  241. ; Return from callback
  242. System::Call "$3" $R0
  243. FunctionEnd
  244. Function systemSplash
  245. ; Save registers and get input
  246. System::Store "s r8r9"
  247. ; Get module instance
  248. System::Call "${sysGetModuleHandle} (i) .r7"
  249. ; Get arrow cursor
  250. System::Call "${sysLoadCursor} (0, i ${IDC_ARROW}) .R9"
  251. ; Get callback
  252. System::Get "${sysWNDPROC}"
  253. Pop $3
  254. ; Create window class
  255. System::Call "*${stWNDCLASS} (0,r3,0,0,r7,0,R9,0,i 0,'_sp') .R9"
  256. ; Register window class
  257. System::Call "${sysRegisterClass} (R9) .R9"
  258. IntCmp $R9 0 errorexit ; Class registered ok?
  259. ; Load Image (LR_CREATEDIBSECTION|LR_LOADFROMFILE = 0x2010)
  260. System::Call '${sysLoadImage} (, s, ${IMAGE_BITMAP}, 0, 0, ${LR_CREATEDIBSECTION}|${LR_LOADFROMFILE}) .r6' "$9.bmp"
  261. IntCmp $6 0 errorexit ; Image loaded ok?
  262. ; Start the sound (SND_ASYNC|SND_FILENAME|SND_NODEFAULT = 0x20003)
  263. System::Call "${sysPlaySound} (s,,${SND_ASYNC}|${SND_FILENAME}|${SND_NODEFAULT})" "$9.wav"
  264. ; Create window
  265. System::Call "${sysCreateWindowEx} (${WS_EX_TOOLWINDOW}, s, s,,,,,, $HWNDPARENT,,r7,) .s" "_sp" "_sp"
  266. !insertmacro SINGLE_CALLBACK 1 $5 1 _systemSplashWndCB
  267. ; Create MSG struct
  268. System::Call "*${stMSG} (_) i.R9"
  269. ; -------------------------
  270. repeat:
  271. ; Check for window
  272. System::Call "${sysIsWindow} (r5) .s"
  273. !insertmacro SINGLE_CALLBACK 2 $R8 1 _systemSplashWndCB
  274. IntCmp $R8 0 finish
  275. ; Get message
  276. System::Call "${sysGetMessage} (R9, r5,_) .s"
  277. !insertmacro SINGLE_CALLBACK 3 $R8 1 _systemSplashWndCB
  278. IntCmp $R8 0 finish
  279. ; Dispatch message
  280. System::Call "${sysDispatchMessage} (R9) .s"
  281. !insertmacro SINGLE_CALLBACK 4 $R8 1 _systemSplashWndCB
  282. ; Repeat dispatch cycle
  283. goto repeat
  284. ; -------------------------
  285. finish:
  286. ; Stop the sound
  287. System::Call "${sysPlaySound} (i 0, i 0, i 0)"
  288. ; Delete bitmap object
  289. System::Call "${sysDeleteObject} (r6)"
  290. ; Delete the callback queue
  291. System::Free $3
  292. ; Dialog return
  293. StrCpy $R0 $4
  294. goto exit
  295. ; Exit in case of error
  296. errorexit:
  297. StrCpy $R0 -1
  298. goto exit
  299. exit:
  300. ; Restore register and put output
  301. System::Store "P0 l"
  302. FunctionEnd
  303. !verbose 4
  304. !endif