; Some useful functions based on System plugin਍ഀ ; ਍ഀ ; (c) brainsucker, 2002਍ഀ ; (r) BSForce਍ഀ ਍ഀ ; Check for double includes਍ഀ !ifndef SysFunc.NSH.Included਍ഀ !define SysFunc.NSH.Included਍ഀ ਍ഀ !include "${NSISDIR}\Examples\System\System.nsh"਍ഀ ਍ഀ !verbose 3 ; For WinMessages especially਍ഀ !include "WinMessages.nsh"਍ഀ !verbose 4਍ഀ ਍ഀ ; ================= GetInstallerExeName implementation =================਍ഀ ਍ഀ ; Adopted Get Parameter function -> now it gets full installer.exe path਍ഀ ; input - nothing, output -> full path at the top of the stack਍ഀ Function GetInstallerExeName਍ഀ Push $R0਍ഀ Push $R1਍ഀ Push $R2਍ഀ StrCpy $R0 $CMDLINE 1਍ഀ StrCpy $R1 '"'਍ഀ StrCpy $R2 1਍ഀ StrCmp $R0 '"' loop਍ഀ StrCpy $R1 ' ' ; we're scanning for a space instead of a quote਍ഀ loop:਍ഀ StrCpy $R0 $CMDLINE 1 $R2਍ഀ StrCmp $R0 $R1 loop2਍ഀ StrCmp $R0 "" loop2਍ഀ IntOp $R2 $R2 + 1਍ഀ Goto loop਍ഀ loop2:਍ഀ ਍ഀ ; Ok, have we found last exename character or string end?਍ഀ StrCmp $R0 "" "" +2਍ഀ IntOp $R2 $R2 - 1 ; last exename char਍ഀ StrCmp $R1 ' ' +3 ; was first character the '"', or something other?਍ഀ StrCpy $R1 1 ; it was quote਍ഀ Goto +2਍ഀ StrCpy $R1 0 ਍ഀ IntOp $R2 $R2 - $R1਍ഀ StrCpy $R0 $CMDLINE $R2 $R1 ਍ഀ ਍ഀ SearchPath $R0 $R0 ; expand file name to full path਍ഀ ਍ഀ Pop $R2਍ഀ Pop $R1਍ഀ Exch $R0਍ഀ FunctionEnd਍ഀ ਍ഀ ; ================= systemGetFileSysTime implementation =================਍ഀ ਍ഀ !macro smGetFileSysTime FILENAME਍ഀ Push ${FILENAME}਍ഀ Call systemGetFileSysTime਍ഀ Pop $R0਍ഀ !macroend਍ഀ ਍ഀ ; -----------------------------------------------------------------਍ഀ ; systemGetFileSysTime (params on stack):਍ഀ ; FILENAME - name of file to get file time਍ഀ ; returns to stack (SYSTEMTIME struct addr)਍ഀ ; -----------------------------------------------------------------਍ഀ ਍ഀ ; uses original method from NSIS਍ഀ Function systemGetFileSysTime਍ഀ System::Store "s r1"਍ഀ ਍ഀ StrCpy $R0 0 ਍ഀ ਍ഀ ; create WIN32_FIND_DATA struct਍ഀ System::Call '*${stWIN32_FIND_DATA} .r2'਍ഀ ਍ഀ ; Find file info਍ഀ System::Call '${sysFindFirstFile}(r1, r2) .r3'਍ഀ ਍ഀ ; ok?਍ഀ IntCmp $3 ${INVALID_HANDLE_VALUE} sgfst_exit਍ഀ ਍ഀ ; close file search਍ഀ System::Call '${sysFindClose}(r3)'਍ഀ ਍ഀ ; Create systemtime struct for local time਍ഀ System::Call '*${stSYSTEMTIME} .R0'਍ഀ ਍ഀ ; Get File time਍ഀ System::Call '*$2${stWIN32_FIND_DATA} (,,, .r3)'਍ഀ ਍ഀ ; Convert file time (UTC) to local file time਍ഀ System::Call '${sysFileTimeToLocalFileTime}(r3, .r1)'਍ഀ ਍ഀ ; Convert file time to system time਍ഀ System::Call '${sysFileTimeToSystemTime}(r1, R0)'਍ഀ ਍ഀ sgfst_exit:਍ഀ ; free used memory for WIN32_FIND_DATA struct਍ഀ System::Free $2 ਍ഀ ਍ഀ System::Store "P0 l"਍ഀ FunctionEnd਍ഀ ਍ഀ ; ================= systemMessageBox implementation =================਍ഀ ਍ഀ ; return to $R0਍ഀ !macro smMessageBox MODULE MSG CAPTION STYLE ICON਍ഀ Push "${ICON}"਍ഀ Push "${STYLE}"਍ഀ Push "${CAPTION}"਍ഀ Push "${MSG}"਍ഀ Push "${MODULE}"਍ഀ Call systemMessageBox਍ഀ Pop $R0਍ഀ !macroend਍ഀ ਍ഀ ; -----------------------------------------------------------------਍ഀ ; systemMessageBox (params on stack):਍ഀ ; Module: either handle ("i HANDLE", HANDLE could be 0) or "modulename" ਍ഀ ; Msg: text of message਍ഀ ; Caption: caption of message box window਍ഀ ; Style: style, buttons etc਍ഀ ; Icon: either icon handle ("i HANDLE") or resource name ਍ഀ ; returns to stack਍ഀ ; -----------------------------------------------------------------਍ഀ Function systemMessageBox਍ഀ System::Store "s r2r3r4r5r6"਍ഀ ਍ഀ ; may be Module is module handle?਍ഀ StrCpy $1 $2਍ഀ IntCmp $1 0 0 smbnext smbnext਍ഀ ਍ഀ ; Get module handle਍ഀ System::Call '${sysGetModuleHandle}($2) .r1'਍ഀ IntCmp $1 0 loadlib libnotloaded libnotloaded਍ഀ ਍ഀ loadlib:਍ഀ ; Load module and get handle਍ഀ System::Call '${sysLoadLibrary}($2) .r1'਍ഀ IntCmp $1 0 0 smbnext smbnext਍ഀ ਍ഀ libnotloaded:਍ഀ ; Indicate that LoadLibrary wasn't used਍ഀ StrCpy $2 1਍ഀ ਍ഀ smbnext:਍ഀ ; Create MSGBOXPARAMS structure਍ഀ System::Call '*${stMSGBOXPARAMS}(, $HWNDPARENT, r1, r3, r4, "$5|${MB_USERICON}", $6, _) .r0'਍ഀ ; call MessageBoxIndirect਍ഀ System::Call '${sysMessageBoxIndirect}(r0) .R0'਍ഀ ; free MSGBOXPARAMS structure਍ഀ ਍ഀ System::Free $0਍ഀ ਍ഀ ; have we used load library at start?਍ഀ IntCmp $2 0 0 smbskipfree smbskipfree਍ഀ ; No, then free the module਍ഀ System::Call '${sysFreeLibrary}(r1)'਍ഀ ਍ഀ smbskipfree:਍ഀ System::Store "P0 l" ਍ഀ FunctionEnd਍ഀ ਍ഀ ; ================= systemSplash implementation =================਍ഀ ਍ഀ ; returns to $R0਍ഀ !macro smSystemSplash DELAY FILE਍ഀ Push ${FILE}਍ഀ Push ${DELAY}਍ഀ call systemSplash਍ഀ Pop $R0 ਍ഀ !macroend਍ഀ ਍ഀ ; -----------------------------------------------------------------਍ഀ ; systemSplash (params on stack):਍ഀ ; Delay - time in ms to show the splash਍ഀ ; File - bitmap (& audio) file name (without extension)਍ഀ ; returns to stack਍ഀ ; -----------------------------------------------------------------਍ഀ ਍ഀ Function _systemSplashWndCB਍ഀ ; Callback receives 4 values਍ഀ System::Store "s r2r5r7r9"਍ഀ ਍ഀ ; Message branching਍ഀ IntCmp $5 ${WM_CLOSE} m_Close਍ഀ IntCmp $5 ${WM_TIMER} m_Timer਍ഀ IntCmp $5 ${WM_LBUTTONDOWN} m_Lbtn਍ഀ IntCmp $5 ${WM_CREATE} m_Create਍ഀ IntCmp $5 ${WM_PAINT} m_Paint਍ഀ goto default਍ഀ ਍ഀ m_Create:਍ഀ ; Create structures਍ഀ System::Call "*${stRECT} (_) .R8"਍ഀ System::Call "*${stBITMAP} (_, &l0 .R7) .R9"਍ഀ ਍ഀ ; Get bitmap info਍ഀ System::Call "${sysGetObject} (r6, R7, R9)" ਍ഀ ਍ഀ ; Get desktop info਍ഀ System::Call "${sysSystemParametersInfo} (${SPI_GETWORKAREA}, 0, R8, 0)" ਍ഀ ਍ഀ ; Style (callbacked)਍ഀ System::Call "${sysSetWindowLong} (r2, ${GWL_STYLE}, 0) .s" ਍ഀ !insertmacro SINGLE_CALLBACK 5 $R7 1 _systemSplashWndCB਍ഀ ਍ഀ ; Calculate and set window pos਍ഀ ਍ഀ ; Get bmWidth(R2) and bmHeight(R3)਍ഀ System::Call "*$R9${stBITMAP} (,.R2,.R3)"਍ഀ ; Get left(R4), top(R5), right(R6), bottom(R7)਍ഀ System::Call "*$R8${stRECT} (.R4,.R5,.R6,.R7)"਍ഀ ਍ഀ ; Left pos਍ഀ IntOp $R0 $R6 - $R4਍ഀ IntOp $R0 $R0 - $R2਍ഀ IntOp $R0 $R0 / 2਍ഀ IntOp $R0 $R0 + $R4਍ഀ ਍ഀ ; Top pos਍ഀ IntOp $R1 $R7 - $R5਍ഀ IntOp $R1 $R1 - $R3਍ഀ IntOp $R1 $R1 / 2਍ഀ IntOp $R1 $R1 + $R5਍ഀ ਍ഀ System::Call "${sysSetWindowPos} (r2, 0, R0, R1, R2, R3, ${SWP_NOZORDER}) .s" ਍ഀ !insertmacro SINGLE_CALLBACK 6 $R7 1 _systemSplashWndCB਍ഀ ਍ഀ ; Show window਍ഀ System::Call "${sysShowWindow} (r2, ${SW_SHOW}) .s" ਍ഀ !insertmacro SINGLE_CALLBACK 7 $R7 1 _systemSplashWndCB਍ഀ ਍ഀ ; Set Timer਍ഀ System::Call "${sysSetTimer} (r2, 1, r8,)"਍ഀ ਍ഀ ; Free used memory਍ഀ System::Free $R8਍ഀ System::Free $R9਍ഀ ਍ഀ StrCpy $R0 0਍ഀ goto exit਍ഀ ਍ഀ m_Paint:਍ഀ ; Create structures਍ഀ System::Call "*${stRECT} (_) .R8"਍ഀ System::Call "*${stPAINTSTRUCT} (_) .R9"਍ഀ ਍ഀ ; Begin Paint਍ഀ System::Call "${sysBeginPaint} (r2, R9) .R7"਍ഀ ਍ഀ ; CreateCompatibleDC਍ഀ System::Call "${sysCreateCompatibleDC} (R7) .R6"਍ഀ ਍ഀ ; GetClientRect਍ഀ System::Call "${sysGetClientRect} (r2, R8)"਍ഀ ਍ഀ ; Select new bitmap਍ഀ System::Call "${sysSelectObject} (R6, r6) .R5"਍ഀ ਍ഀ ; Get left(R0), top(R1), right(R2), bottom(R3)਍ഀ System::Call "*$R8${stRECT} (.R0,.R1,.R2,.R3)"਍ഀ ਍ഀ ; width=right-left ਍ഀ IntOp $R2 $R2 - $R0਍ഀ ; height=bottom-top਍ഀ IntOp $R3 $R3 - $R1਍ഀ ਍ഀ System::Call "${sysBitBlt} (R7, R0, R1, R2, R3, R6, 0, 0, ${SRCCOPY})" ਍ഀ ਍ഀ ; Select old bitmap਍ഀ System::Call "${sysSelectObject} (R6, R5)"਍ഀ ਍ഀ ; Delete compatible DC਍ഀ System::Call "${sysDeleteDC} (R6)"਍ഀ ਍ഀ ; End Paint਍ഀ System::Call "${sysEndPaint} (r2, R9)"਍ഀ ਍ഀ ; Free used memory਍ഀ System::Free $R8਍ഀ System::Free $R9਍ഀ ਍ഀ StrCpy $R0 0਍ഀ goto exit਍ഀ ਍ഀ m_Timer:਍ഀ m_Lbtn:਍ഀ StrCpy $4 0਍ഀ IntCmp $5 ${WM_TIMER} destroy਍ഀ StrCpy $4 1਍ഀ ਍ഀ destroy:਍ഀ System::Call "${sysDestroyWindow} (r2) .s"਍ഀ !insertmacro SINGLE_CALLBACK 12 $R4 1 _systemSplashWndCB਍ഀ ਍ഀ default:਍ഀ ; Default਍ഀ System::Call "${sysDefWindowProc} (r2, r5, r7, r9) .s"਍ഀ !insertmacro SINGLE_CALLBACK 14 $R0 1 _systemSplashWndCB਍ഀ goto exit਍ഀ ਍ഀ m_Close:਍ഀ StrCpy $R0 0਍ഀ goto exit਍ഀ ਍ഀ exit:਍ഀ ; Restore਍ഀ System::Store "p4P0 l R0r4"਍ഀ ਍ഀ ; Return from callback਍ഀ System::Call "$3" $R0਍ഀ FunctionEnd਍ഀ ਍ഀ Function systemSplash਍ഀ ਍ഀ ; Save registers and get input ਍ഀ System::Store "s r8r9"਍ഀ ਍ഀ ; Get module instance਍ഀ System::Call "${sysGetModuleHandle} (i) .r7"਍ഀ ਍ഀ ; Get arrow cursor਍ഀ System::Call "${sysLoadCursor} (0, i ${IDC_ARROW}) .R9" ਍ഀ ਍ഀ ; Get callback਍ഀ System::Get "${sysWNDPROC}"਍ഀ Pop $3਍ഀ ਍ഀ ; Create window class਍ഀ System::Call "*${stWNDCLASS} (0,r3,0,0,r7,0,R9,0,i 0,'_sp') .R9"਍ഀ ਍ഀ ; Register window class਍ഀ System::Call "${sysRegisterClass} (R9) .R9"਍ഀ IntCmp $R9 0 errorexit ; Class registered ok?਍ഀ ਍ഀ ; Load Image (LR_CREATEDIBSECTION|LR_LOADFROMFILE = 0x2010)਍ഀ System::Call '${sysLoadImage} (, s, ${IMAGE_BITMAP}, 0, 0, ${LR_CREATEDIBSECTION}|${LR_LOADFROMFILE}) .r6' "$9.bmp"਍ഀ IntCmp $6 0 errorexit ; Image loaded ok?਍ഀ ਍ഀ ; Start the sound (SND_ASYNC|SND_FILENAME|SND_NODEFAULT = 0x20003)਍ഀ System::Call "${sysPlaySound} (s,,${SND_ASYNC}|${SND_FILENAME}|${SND_NODEFAULT})" "$9.wav" ਍ഀ ਍ഀ ; Create window਍ഀ System::Call "${sysCreateWindowEx} (${WS_EX_TOOLWINDOW}, s, s,,,,,, $HWNDPARENT,,r7,) .s" "_sp" "_sp" ਍ഀ !insertmacro SINGLE_CALLBACK 1 $5 1 _systemSplashWndCB਍ഀ ਍ഀ ; Create MSG struct਍ഀ System::Call "*${stMSG} (_) i.R9"਍ഀ ਍ഀ ; -------------------------਍ഀ repeat:਍ഀ ; Check for window਍ഀ System::Call "${sysIsWindow} (r5) .s"਍ഀ !insertmacro SINGLE_CALLBACK 2 $R8 1 _systemSplashWndCB਍ഀ IntCmp $R8 0 finish਍ഀ ਍ഀ ; Get message਍ഀ System::Call "${sysGetMessage} (R9, r5,_) .s"਍ഀ !insertmacro SINGLE_CALLBACK 3 $R8 1 _systemSplashWndCB਍ഀ IntCmp $R8 0 finish਍ഀ ਍ഀ ; Dispatch message਍ഀ System::Call "${sysDispatchMessage} (R9) .s"਍ഀ !insertmacro SINGLE_CALLBACK 4 $R8 1 _systemSplashWndCB਍ഀ ਍ഀ ; Repeat dispatch cycle਍ഀ goto repeat਍ഀ ; -------------------------਍ഀ ਍ഀ finish:਍ഀ ; Stop the sound਍ഀ System::Call "${sysPlaySound} (i 0, i 0, i 0)"਍ഀ ਍ഀ ; Delete bitmap object਍ഀ System::Call "${sysDeleteObject} (r6)"਍ഀ ਍ഀ ; Delete the callback queue਍ഀ System::Free $3਍ഀ ਍ഀ ; Dialog return਍ഀ StrCpy $R0 $4਍ഀ goto exit਍ഀ ਍ഀ ; Exit in case of error਍ഀ errorexit:਍ഀ StrCpy $R0 -1਍ഀ goto exit਍ഀ ਍ഀ exit:਍ഀ ; Restore register and put output਍ഀ System::Store "P0 l"਍ഀ FunctionEnd਍ഀ ਍ഀ !verbose 4਍ഀ ਍ഀ !endif