From 74ea2dc585fa08312043c63d8e0f6b009e706649 Mon Sep 17 00:00:00 2001 From: kichik Date: Thu, 4 Sep 2003 18:25:57 +0000 Subject: [PATCH] * PageEx - every page can be used everywhere and as many times as needed * DirVar - easy way to add another dir page * default strings in the language file (Page directory is enough, no need for DirText) * strings from the language file are now LangStrings that can be used in the script * no more /LANG - one string for all languages * any lang strings can be used everywhere, installer or uninstaller (no un.) * no more unprocessed strings - variables can be used almost everywhere (except in licenseData and InstallDirRegKey) * DirText parm for browse dialog text * SetBkColor -> SetCtlColors - can now set text color too * fixed SetOutPath and File /r bug * fixed File /a /oname bug * added $_CLICK for pages * added quotes support in lang files (patch #752620) * extraction progress * separate RTL dialogs for RTL langs (improved RTL too) * InstallOptions RTL * StartMenu RTL * fixed RegDLL? * added IfSilent and SetSilent (SetSilent only works from .onInit) * fixed verify window (it never showed) (bug #792494) * fixed ifnewer readonly file problem (patch #783782) * fixed wininit.ini manipulation when there is another section after [rename] * fixed some ClearType issues * fixed a minor bug in the resource editor * fixed !ifdef/!endif stuff, rewritten * lots of code and comments clean ups * got rid of some useless exceptions handling and STL classes (still much more to go) * lots of optimizations, of course ;) * updated system.dll with support for GUID, WCHAR, and fast VTable calling (i.e. COM ready) * minor bug fixes git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@2823 212acab6-be3b-0410-9dea-997c60f758d6 --- Contrib/InstallOptions/InstallerOptions.cpp | 123 +- Contrib/InstallOptions/Readme.html | 10 +- Contrib/Language files/Arabic.nlf | 8 +- Contrib/Language files/Bulgarian.nlf | 8 +- Contrib/Language files/Catalan.nlf | 8 +- Contrib/Language files/Croatian.nlf | 8 +- Contrib/Language files/Czech.nlf | 8 +- Contrib/Language files/Danish.nlf | 8 +- Contrib/Language files/Dutch.nlf | 8 +- Contrib/Language files/English.nlf | 179 +- Contrib/Language files/Estonian.nlf | 6 +- Contrib/Language files/Finnish.nlf | 8 +- Contrib/Language files/French.nlf | 8 +- Contrib/Language files/German.nlf | 8 +- Contrib/Language files/Greek.nlf | 8 +- Contrib/Language files/Hebrew.nlf | 30 +- Contrib/Language files/Hungarian.nlf | 8 +- Contrib/Language files/Italian.nlf | 8 +- Contrib/Language files/Japanese.nlf | 8 +- Contrib/Language files/Korean.nlf | 8 +- Contrib/Language files/Lithuanian.nlf | 8 +- Contrib/Language files/Macedonian.nlf | 8 +- Contrib/Language files/Polish.nlf | 8 +- Contrib/Language files/Portuguese.nlf | 8 +- Contrib/Language files/PortugueseBR.nlf | 8 +- Contrib/Language files/Romanian.nlf | 8 +- Contrib/Language files/Russian.nlf | 8 +- Contrib/Language files/Serbian.nlf | 8 +- Contrib/Language files/SimpChinese.nlf | 8 +- Contrib/Language files/Slovak.nlf | 8 +- Contrib/Language files/Slovenian.nlf | 8 +- Contrib/Language files/Spanish.nlf | 8 +- Contrib/Language files/Swedish.nlf | 8 +- Contrib/Language files/Thai.nlf | 8 +- Contrib/Language files/TradChinese.nlf | 8 +- Contrib/Language files/Turkish.nlf | 8 +- Contrib/Language files/Ukrainian.nlf | 8 +- Contrib/StartMenu/Readme.txt | 17 +- Contrib/StartMenu/StartMenu.c | 84 +- Contrib/StartMenu/StartMenu.dsp | 2 +- Contrib/System/Source/System.c | 114 +- Contrib/System/Source/System.h | 7 +- Contrib/System/Source/System.sln | 10 +- Contrib/System/Source/System.vcproj | 50 +- Contrib/System/System.nsh | 4 + Contrib/System/System.txt | 14 +- Contrib/UIs/UI Holder/resource.h | 31 +- Contrib/UIs/UI Holder/resource.rc | 152 +- Contrib/UIs/default.exe | Bin 5632 -> 6144 bytes Contrib/UIs/sdbarker_tiny.exe | Bin 5632 -> 6144 bytes Docs/src/attributes.but | 48 +- Docs/src/callback.but | 3 +- Docs/src/flowcontrol.but | 6 + Docs/src/history.but | 28 +- Docs/src/langs.but | 67 +- Docs/src/pages.but | 102 +- Docs/src/tutorial.but | 19 +- Docs/src/ui.but | 14 +- Plugins/InstallOptions.dll | Bin 13824 -> 13824 bytes Plugins/StartMenu.dll | Bin 6656 -> 7168 bytes Plugins/System.dll | Bin 9728 -> 10240 bytes Source/DialogTemplate.cpp | 33 +- Source/DialogTemplate.h | 2 +- Source/ResourceEditor.cpp | 2 +- Source/build.cpp | 1752 +++++++++------- Source/build.h | 129 +- Source/exedata.cpp | 13 +- Source/exehead/Main.c | 15 +- Source/exehead/Ui.c | 715 +++---- Source/exehead/bgbg.c | 8 +- Source/exehead/config.h | 26 +- Source/exehead/exec.c | 554 ++--- Source/exehead/exec.h | 2 +- Source/exehead/fileform.c | 146 +- Source/exehead/fileform.h | 367 ++-- Source/exehead/lang.h | 130 +- Source/exehead/resource.h | 4 +- Source/exehead/resource.rc | 140 +- Source/exehead/state.h | 35 +- Source/exehead/ui.h | 22 +- Source/exehead/util.c | 132 +- Source/exehead/util.h | 10 +- Source/lang.cpp | 1263 ++++++------ Source/lang.h | 249 ++- Source/makenssi.cpp | 2 +- Source/makenssi.dsp | 3 +- Source/script.cpp | 2013 ++++++++++--------- Source/strlist.h | 4 +- Source/tokens.cpp | 68 +- Source/tokens.h | 28 +- TODO.txt | 38 +- 91 files changed, 5180 insertions(+), 4101 deletions(-) diff --git a/Contrib/InstallOptions/InstallerOptions.cpp b/Contrib/InstallOptions/InstallerOptions.cpp index aac2948b..c22cb006 100644 --- a/Contrib/InstallOptions/InstallerOptions.cpp +++ b/Contrib/InstallOptions/InstallerOptions.cpp @@ -29,6 +29,17 @@ static int popstring(char *str) return 0; } +#define CC_TEXT 1 +#define CC_BK 4 + +typedef struct { + COLORREF text; + LOGBRUSH bk; + HBRUSH bkb; + int bkmode; + int flags; +} ctlcolors; + #define strcpy(x,y) lstrcpy(x,y) #define strncpy(x,y,z) lstrcpyn(x,y,z) #define strdup(x) STRDUP(x) @@ -164,6 +175,8 @@ int bBackEnabled = FALSE; int bCancelEnabled = FALSE; // by ORTIM: 13-August-2002 int bCancelShow = FALSE; // by ORTIM: 13-August-2002 +int bRTL = FALSE; + FieldType *pFields = NULL; #define DEFAULT_RECT 1018 int nRectId = 0; @@ -468,6 +481,8 @@ int ReadSettings(void) { bCancelEnabled = GetPrivateProfileInt("Settings", "CancelEnabled", 0xFFFF0000, pszFilename); bCancelShow = GetPrivateProfileInt("Settings", "CancelShow", 0xFFFF0000, pszFilename); + bRTL = GetPrivateProfileInt("Settings", "RTL", 0, pszFilename); + if (nNumFields > 0) { // make this twice as large for the worst case that every control is a browse button. // the structure is small enough that this won't waste much memory. @@ -621,21 +636,21 @@ int ReadSettings(void) { pFields[nIdx].hImage = (HANDLE)GetPrivateProfileInt(szField, "TxtColor", RGB(0,0,255), pszFilename); pFields[nIdx].nControlID = 1200 + nIdx; - if ( pFields[nIdx].nType == FIELD_FILEREQUEST || pFields[nIdx].nType == FIELD_DIRREQUEST ) + if (pFields[nIdx].nType == FIELD_FILEREQUEST || pFields[nIdx].nType == FIELD_DIRREQUEST) { - FieldType *pNewField = &pFields[nIdx+1]; - pNewField->nControlID = 1200 + nIdx + 1; - pNewField->nParentIdx = nIdx; - pNewField->nType = FIELD_BROWSEBUTTON; - pNewField->nFlags = pFields[nIdx].nFlags & (FLAG_DISABLED | FLAG_NOTABSTOP); - pNewField->pszText = STRDUP(szBrowseButtonCaption); // needed for generic FREE - pNewField->rect.right = pFields[nIdx].rect.right; - pNewField->rect.left = pNewField->rect.right - BROWSE_WIDTH; - pNewField->rect.bottom = pFields[nIdx].rect.bottom; - pNewField->rect.top = pFields[nIdx].rect.top; - pFields[nIdx].rect.right = pNewField->rect.left - 3; - nNumFields++; - nIdx++; + FieldType *pNewField = &pFields[nIdx+1]; + pNewField->nControlID = 1200 + nIdx + 1; + pNewField->nParentIdx = nIdx; + pNewField->nType = FIELD_BROWSEBUTTON; + pNewField->nFlags = pFields[nIdx].nFlags & (FLAG_DISABLED | FLAG_NOTABSTOP); + pNewField->pszText = STRDUP(szBrowseButtonCaption); // needed for generic FREE + pNewField->rect.right = pFields[nIdx].rect.right; + pNewField->rect.left = pNewField->rect.right - BROWSE_WIDTH; + pNewField->rect.bottom = pFields[nIdx].rect.bottom; + pNewField->rect.top = pFields[nIdx].rect.top; + pFields[nIdx].rect.right = pNewField->rect.left - 3; + nNumFields++; + nIdx++; } } @@ -753,11 +768,16 @@ BOOL CALLBACK cfgDlgProc(HWND hwndDlg, case WM_CTLCOLORBTN: case WM_CTLCOLORLISTBOX: { - BOOL brush = (BOOL)GetWindowLong((HWND)lParam, GWL_USERDATA); - if (brush) - { - SetBkMode((HDC)wParam, TRANSPARENT); - return brush; + ctlcolors *c = (ctlcolors *)GetWindowLong((HWND)lParam, GWL_USERDATA); + + if (c) { + SetBkMode((HDC)wParam, c->bkmode); + if (c->flags & CC_BK) + SetBkColor((HDC)wParam, c->bk.lbColor); + if (c->flags & CC_TEXT) + SetTextColor((HDC)wParam, c->text); + + return (BOOL)c->bkb; } } } @@ -861,13 +881,23 @@ int createCfgDlg() HFONT hFont = (HFONT)SendMessage(hMainWindow, WM_GETFONT, 0, 0); RECT dialog_r; + int width; hConfigWindow=CreateDialog(m_hInstance,MAKEINTRESOURCE(IDD_DIALOG1),hMainWindow,cfgDlgProc); if (hConfigWindow) { GetWindowRect(childwnd,&dialog_r); ScreenToClient(hMainWindow,(LPPOINT)&dialog_r); ScreenToClient(hMainWindow,((LPPOINT)&dialog_r)+1); - SetWindowPos(hConfigWindow,0,dialog_r.left,dialog_r.top,dialog_r.right-dialog_r.left,dialog_r.bottom-dialog_r.top,SWP_NOZORDER|SWP_NOACTIVATE); + width = dialog_r.right-dialog_r.left; + SetWindowPos( + hConfigWindow, + 0, + dialog_r.left, + dialog_r.top, + width, + dialog_r.bottom-dialog_r.top, + SWP_NOZORDER|SWP_NOACTIVATE + ); // Sets the font of IO window to be the same as the main window SendMessage(hConfigWindow, WM_SETFONT, (WPARAM)hFont, TRUE); } @@ -899,47 +929,75 @@ int createCfgDlg() static struct { char* pszClass; DWORD dwStyle; + DWORD dwRTLStyle; DWORD dwExStyle; + DWORD dwRTLExStyle; } ClassTable[] = { { "STATIC", // FIELD_LABEL DEFAULT_STYLES /*| WS_TABSTOP*/, + DEFAULT_STYLES | SS_RIGHT /*| WS_TABSTOP*/, + WS_EX_TRANSPARENT, WS_EX_TRANSPARENT }, { "STATIC", // FIELD_ICON DEFAULT_STYLES /*| WS_TABSTOP*/ | SS_ICON, + DEFAULT_STYLES /*| WS_TABSTOP*/ | SS_ICON, + 0, 0 }, { "STATIC", // FIELD_BITMAP DEFAULT_STYLES /*| WS_TABSTOP*/ | SS_BITMAP | SS_CENTERIMAGE, + DEFAULT_STYLES /*| WS_TABSTOP*/ | SS_BITMAP | SS_CENTERIMAGE, + 0, 0 }, { "BUTTON", // FIELD_BROWSEBUTTON DEFAULT_STYLES | WS_TABSTOP, + DEFAULT_STYLES | WS_TABSTOP, + 0, 0 }, { "BUTTON", // FIELD_CHECKBOX DEFAULT_STYLES | WS_TABSTOP | BS_TEXT | BS_VCENTER | BS_AUTOCHECKBOX | BS_MULTILINE, + DEFAULT_STYLES | WS_TABSTOP | BS_TEXT | BS_VCENTER | BS_AUTOCHECKBOX | BS_MULTILINE | BS_RIGHT | BS_LEFTTEXT, + 0, 0 }, { "BUTTON", // FIELD_RADIOBUTTON DEFAULT_STYLES | WS_TABSTOP | BS_TEXT | BS_VCENTER | BS_AUTORADIOBUTTON | BS_MULTILINE, + DEFAULT_STYLES | WS_TABSTOP | BS_TEXT | BS_VCENTER | BS_AUTORADIOBUTTON | BS_MULTILINE | BS_RIGHT | BS_LEFTTEXT, + 0, 0 }, { "EDIT", // FIELD_TEXT DEFAULT_STYLES | WS_TABSTOP | ES_AUTOHSCROLL, + DEFAULT_STYLES | WS_TABSTOP | ES_AUTOHSCROLL | ES_RIGHT, + WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE, WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE }, { "EDIT", // FIELD_FILEREQUEST DEFAULT_STYLES | WS_TABSTOP | ES_AUTOHSCROLL, + DEFAULT_STYLES | WS_TABSTOP | ES_AUTOHSCROLL | ES_RIGHT, + WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE, WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE }, { "EDIT", // FIELD_DIRREQUEST DEFAULT_STYLES | WS_TABSTOP | ES_AUTOHSCROLL, + DEFAULT_STYLES | WS_TABSTOP | ES_AUTOHSCROLL | ES_RIGHT, + WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE, WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE }, { "COMBOBOX", // FIELD_COMBOBOX DEFAULT_STYLES | WS_TABSTOP | WS_VSCROLL | WS_CLIPCHILDREN | CBS_AUTOHSCROLL | CBS_HASSTRINGS, - WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE }, + DEFAULT_STYLES | WS_TABSTOP | WS_VSCROLL | WS_CLIPCHILDREN | CBS_AUTOHSCROLL | CBS_HASSTRINGS, + WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE, + WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_RIGHT | WS_EX_RTLREADING }, { "LISTBOX", // FIELD_LISTBOX DEFAULT_STYLES | WS_TABSTOP | WS_VSCROLL | LBS_DISABLENOSCROLL | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT, - WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE }, + DEFAULT_STYLES | WS_TABSTOP | WS_VSCROLL | LBS_DISABLENOSCROLL | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT, + WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE, + WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_RIGHT | WS_EX_RTLREADING }, { "BUTTON", // FIELD_GROUPBOX DEFAULT_STYLES | BS_GROUPBOX, + DEFAULT_STYLES | BS_GROUPBOX | BS_RIGHT, + WS_EX_TRANSPARENT, WS_EX_TRANSPARENT }, { "BUTTON", // FIELD_LINK - DEFAULT_STYLES | WS_TABSTOP | BS_OWNERDRAW - }, + DEFAULT_STYLES | WS_TABSTOP | BS_OWNERDRAW, + DEFAULT_STYLES | WS_TABSTOP | BS_OWNERDRAW | BS_RIGHT, + 0, + 0 }, }; int nType = pFields[nIdx].nType; @@ -949,8 +1007,15 @@ int createCfgDlg() if (nType < 1 || nType > (sizeof(ClassTable) / sizeof(ClassTable[0]))) continue; - DWORD dwStyle = ClassTable[pFields[nIdx].nType - 1].dwStyle; - DWORD dwExStyle = ClassTable[pFields[nIdx].nType - 1].dwExStyle; + DWORD dwStyle, dwExStyle; + if (bRTL) { + dwStyle = ClassTable[pFields[nIdx].nType - 1].dwRTLStyle; + dwExStyle = ClassTable[pFields[nIdx].nType - 1].dwRTLExStyle; + } + else { + dwStyle = ClassTable[pFields[nIdx].nType - 1].dwStyle; + dwExStyle = ClassTable[pFields[nIdx].nType - 1].dwExStyle; + } // Convert from dialog units @@ -970,6 +1035,12 @@ int createCfgDlg() if (pFields[nIdx].rect.bottom < 0) rect.bottom += dialog_r.bottom - dialog_r.top; + if (bRTL) { + int right = rect.right; + rect.right = width - rect.left; + rect.left = width - right; + } + char *title = pFields[nIdx].pszText; switch (nType) { case FIELD_CHECKBOX: diff --git a/Contrib/InstallOptions/Readme.html b/Contrib/InstallOptions/Readme.html index f72aa96a..151e04d4 100644 --- a/Contrib/InstallOptions/Readme.html +++ b/Contrib/InstallOptions/Readme.html @@ -195,11 +195,16 @@ It can contain the following values:

(optional) Overrides the text for the back button. If not specified, the back button text will not be changed. - + Rect (optional) Overrides the default rect ID to run over. This will make IO resize itself according to a different rect than NSIS's dialogs rect. + + RTL + (optional) + If 1 is specified the dialog will be mirrored and all texts will be aligned to the + right. Use NSIS's $(^RTL) to fill this field, it's the easiest way.

Each field section has the heading "Field #" where # must be sequential numbers from 1 to NumFields. Each Field section can contain the following values:

@@ -612,12 +617,13 @@ FunctionEnd

Version history

diff --git a/Contrib/Language files/Arabic.nlf b/Contrib/Language files/Arabic.nlf index 708337f1..528944da 100644 --- a/Contrib/Language files/Arabic.nlf +++ b/Contrib/Language files/Arabic.nlf @@ -7,10 +7,12 @@ NLF v2 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +RTL # Translation by asdfuae@msn.com %s - %s - %s + $(^Name) + $(^Name) : : : @@ -34,7 +36,7 @@ NLF v2 : : : - %s : + $(^Name) : : : : diff --git a/Contrib/Language files/Bulgarian.nlf b/Contrib/Language files/Bulgarian.nlf index 350937ac..e1a681bf 100644 --- a/Contrib/Language files/Bulgarian.nlf +++ b/Contrib/Language files/Bulgarian.nlf @@ -7,10 +7,12 @@ NLF v2 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by Asparouh Kalyandjiev Nullsoft %s -%s -%s +$(^Name) +$(^Name) : : : @@ -34,7 +36,7 @@ Nullsoft : : , : - , %s: + , $(^Name): : : : diff --git a/Contrib/Language files/Catalan.nlf b/Contrib/Language files/Catalan.nlf index 8d6275bd..0913f9b8 100644 --- a/Contrib/Language files/Catalan.nlf +++ b/Contrib/Language files/Catalan.nlf @@ -8,10 +8,12 @@ NLF v5 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by falanko Nullsoft Install System %s -Installaci de %s -Desinstallaci de %s +Installaci de $(^Name) +Desinstallaci de $(^Name) : Acord de Llicncia : Opcions d'Installaci : Carpeta d'Installaci @@ -37,7 +39,7 @@ Personalitzada Indiqui el tipus d'installaci: Seleccioni els components: O seleccioni els components opcionals a installar: -Seleccioni la carpeta on installar %s: +Seleccioni la carpeta on installar $(^Name): Espai lliure: Espai necessari: Desinstallant de: diff --git a/Contrib/Language files/Croatian.nlf b/Contrib/Language files/Croatian.nlf index e5f1ba71..b81fefd2 100644 --- a/Contrib/Language files/Croatian.nlf +++ b/Contrib/Language files/Croatian.nlf @@ -7,10 +7,12 @@ NLF v5 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by Igor Ostriz Nullsoft Install System %s -%s Instalacija -%s Deinstalacija +$(^Name) Instalacija +$(^Name) Deinstalacija : Licenenni uvjeti : Instalacijske opcije : Instalacijska mapa @@ -36,7 +38,7 @@ Posebna Izaberite tip instalacije: Odaberite komponente za instalaciju: Ili po izboru oznaite komponente koje elite instalirati: -Odaberite mapu u koju elite instalirati program %s: +Odaberite mapu u koju elite instalirati program $(^Name): Slobodno prostora na disku: Potrebno prostora na disku: Uklanjam iz: diff --git a/Contrib/Language files/Czech.nlf b/Contrib/Language files/Czech.nlf index 7948fbc4..a0220b4b 100644 --- a/Contrib/Language files/Czech.nlf +++ b/Contrib/Language files/Czech.nlf @@ -7,10 +7,12 @@ NLF v5 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by T.V. Zuggy (http://zuggy.wz.cz/) Nullsoft Install System %s -Instalace programu %s -Odinstalovn programu %s +Instalace programu $(^Name) +Odinstalovn programu $(^Name) : Licenn ujednn : Monosti instalace : Umstn instalace @@ -36,7 +38,7 @@ Vlastn Zvolte typ instalace: Zvolte sousti pro instalaci: Nebo zvolte jednotliv sousti, kter si pejete nainstalovat: -Zvolte adres pro instalaci programu %s: +Zvolte adres pro instalaci programu $(^Name): Dostupn voln msto: Potebn voln msto: Odinstalovn z: diff --git a/Contrib/Language files/Danish.nlf b/Contrib/Language files/Danish.nlf index 0c59ee38..31dbfd97 100644 --- a/Contrib/Language files/Danish.nlf +++ b/Contrib/Language files/Danish.nlf @@ -7,10 +7,12 @@ NLF v2 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by Casper Bergenstoff Nullsoft Installerings System %s -%s Setup -%s Afinstaller +$(^Name) Setup +$(^Name) Afinstaller : Licens Aftale : Installations egenskaber : Installation mappe @@ -34,7 +36,7 @@ Tilpasset Vlg hvilken type du vil installere: Vlg komponenter du vil installere: Eller, Vlg de udvalgte komponenter som du vil installere: -Vlg mappe du vil installere %s i: +Vlg mappe du vil installere $(^Name) i: Plads til rdighed: Krvet plads: Afinstallerer fra: diff --git a/Contrib/Language files/Dutch.nlf b/Contrib/Language files/Dutch.nlf index 28db61ce..8b9ed9f1 100644 --- a/Contrib/Language files/Dutch.nlf +++ b/Contrib/Language files/Dutch.nlf @@ -7,10 +7,12 @@ NLF v5 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by Hendri Adriaens & Joost Verburg Nullsoft Install System %s -%s Installatie -%s Denstallatie +$(^Name) Installatie +$(^Name) Denstallatie : Licentie Overeenkomst : Installatie Opties : Installatie Map @@ -36,7 +38,7 @@ Handmatig Selecteer het installatietype: Selecteer de installatieonderdelen: Of selecteer de onderdelen die genstalleerd moeten worden: -Selecteer de map om %s in te installeren: +Selecteer de map om $(^Name) in te installeren: Beschikbare ruimte: Vereiste ruimte: Uninstallatie vanuit: diff --git a/Contrib/Language files/English.nlf b/Contrib/Language files/English.nlf index ba7178fd..010054cc 100644 --- a/Contrib/Language files/English.nlf +++ b/Contrib/Language files/English.nlf @@ -1,5 +1,5 @@ # Header, don't edit -NLF v5 +NLF v6 # Start editing here # Language ID 1033 @@ -7,76 +7,185 @@ NLF v5 - - # Codepage - dash (-) means ANSI code page +# RTL - anything else than RTL means LTR +- - # Translation by ..... (any credits should go here) +# ^Branding Nullsoft Install System %s -%s Setup -%s Uninstall +# ^SetupCaption +$(^Name) Setup +# ^UninstallCaption +$(^Name) Uninstall +# ^LicenseSubCaption : License Agreement +# ^ComponentsSubCaption : Installation Options +# ^DirSubCaption : Installation Folder +# ^InstallingSubCaption : Installing +# ^CompletedSubCaption : Completed +# ^UnComponentsSubCaption +: Uninstallation Options +# ^UnDirSubCaption +: Uninstallation Folder +# ^ConfirmSubCaption : Confirmation +# ^UninstallingSubCaption : Uninstalling +# ^UnCompletedSubCaption : Completed +# ^BackBtn < &Back +# ^NextBtn &Next > +# ^AgreeBtn I &Agree +# ^AcceptBtn I &accept the terms in the License Agreement +# ^DontAcceptBtn I &do not accept the terms in the License Agreement +# ^InstallBtn &Install +# ^UninstallBtn &Uninstall +# ^CancelBtn Cancel +# ^CloseBtn &Close +# ^BrowseBtn B&rowse... +# ^ShowDetailsBtn Show &details +# ^ClickNext +Click Next to continue. +# ^ClickInstall +Click Install to start the installation. +# ^ClickUninstall +Click Uninstall to start the uninstallation. +# ^Name Name +# ^Completed Completed +# ^LicenseText +Please review the license agreement before installing $(^Name). If you accept all terms of the agreement, click I Agree. +# ^LicenseTextCB +Please review the license agreement before installing $(^Name). If you accept all terms of the agreement, click the check box below. $_CLICK +# ^LicesnseTextRB +Please review the license agreement before installing $(^Name). If you accept all terms of the agreement, select the first option below. $_CLICK +# ^UnLicenseText +Please review the license agreement before uninstalling $(^Name). If you accept all terms of the agreement, click I Agree. +# ^UnLicenseTextCB +Please review the license agreement before uninstalling $(^Name). If you accept all terms of the agreement, click the check box below. $_CLICK +# ^UnLicesnseTextRB +Please review the license agreement before uninstalling $(^Name). If you accept all terms of the agreement, select the first option below. $_CLICK +# ^Custom Custom +# ^ComponentsText +Check the components you want to install and uncheck the components you don't want to install. $_CLICK +# ^ComponentsSubText1 Select the type of install: +# ^ComponentsSubText2_NoInstTypes Select components to install: +# ^ComponentsSubText2 Or, select the optional components you wish to install: -Select the folder to install %s in: -Space available: -Space required: +# ^UnComponentsText +Check the components you want to uninstall and uncheck the components you don't want to uninstall. $_CLICK +# ^UnComponentsSubText1 +Select the type of uninstall: +# ^UnComponentsSubText2_NoInstTypes +Select components to uninstall: +# ^UnComponentsSubText2 +Or, select the optional components you wish to uninstall: +# ^DirText +Setup will install $(^Name) in the following folder. To install in a different folder, click Browse and select another folder. $_CLICK +# ^DirSubText +Destination Folder +# ^DirBrowseText +Select the folder to install $(^Name) in: +# ^UnDirText +Setup will uninstall $(^Name) from the following folder. To uninstall from a different folder, click Browse and select another folder. $_CLICK +# ^UnDirSubText +"" +# ^UnDirBrowseText +Select the folder to uninstall $(^Name) from: +# ^SpaceAvailable +"Space available: " +# ^SpaceRequired +"Space required: " +# ^UninstallingText +This wizard will uninstall $(^Name) from your computer. $_CLICK +# ^UninstallingSubText Uninstalling from: -Error opening file for writing: \r\n\t"$0"\r\nHit abort to abort installation,\r\nretry to retry writing the file, or\r\nignore to skip this file -Error opening file for writing: \r\n\t"$0"\r\nHit retry to retry writing the file, or\r\ncancel to abort installation -Can't write: +# ^FileError +Error opening file for writing: \r\n\t\"$0\"\r\nHit abort to abort installation,\r\nretry to retry writing the file, or\r\nignore to skip this file +# ^FileError_NoIgnore +Error opening file for writing: \r\n\t\"$0\"\r\nHit retry to retry writing the file, or\r\ncancel to abort installation +# ^CantWrite +"Can't write: " +# ^CopyFailed Copy failed -Copy to -Registering: -Unregistering: -Could not find symbol: -Could not load: -Create folder: -Create shortcut: -Created uninstaller: -Delete file: -Delete on reboot: -Error creating shortcut: -Error creating: +# ^CopyTo +"Copy to " +# ^Registering +"Registering: " +# ^Unregistering +"Unregistering: " +# ^SymbolNotFound +"Could not find symbol: " +# ^CouldNotLoad +"Could not load: " +# ^CreateFolder +"Create folder: " +# ^CreateShortcut +"Create shortcut: " +# ^CreatedUninstaller +"Created uninstaller: " +# ^Delete +"Delete file: " +# ^DeleteOnReboot +"Delete on reboot: " +# ^ErrorCreatingShortcut +"Error creating shortcut: " +# ^ErrorCreating +"Error creating: " +# ^ErrorDecompressing Error decompressing data! Corrupted installer? +# ^ErrorRegistering Error registering DLL -ExecShell: -Execute: -Extract: -Extract: error writing to file +# ^ExecShell +"ExecShell: " +# ^Exec +"Execute: " +# ^Extract +"Extract: " +# ^ErrorWriting +"Extract: error writing to file " +# ^InvalidOpcode Installer corrupted: invalid opcode -No OLE for: -Output folder: -Remove folder: -Rename on reboot: -Rename: -Skipped: +# ^NoOLE +"No OLE for: " +# ^OutputFolder +"Output folder: " +# ^RemoveFolder +"Remove folder: " +# ^RenameOnReboot +"Rename on reboot: " +# ^Rename +"Rename: " +# ^Skipped +"Skipped: " +# ^CopyDetails Copy Details To Clipboard +# ^LogInstall Log install process -# byte +# ^Byte B -# kilo +# ^Kilo K -# mega +# ^Mega M -# giga +# ^Giga G \ No newline at end of file diff --git a/Contrib/Language files/Estonian.nlf b/Contrib/Language files/Estonian.nlf index f1b00d84..7c3b8df1 100644 --- a/Contrib/Language files/Estonian.nlf +++ b/Contrib/Language files/Estonian.nlf @@ -7,10 +7,12 @@ NLF v5 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by izzo (izzo@hot.ee) Nullsoft Install System %s -%s Paigaldamine -%s Eemaldamine +$(^Name) Paigaldamine +$(^Name) Eemaldamine : Litsentsileping : Paigaldusvalikud : Paigalduskaust diff --git a/Contrib/Language files/Finnish.nlf b/Contrib/Language files/Finnish.nlf index 2b31f828..43e1fbd8 100644 --- a/Contrib/Language files/Finnish.nlf +++ b/Contrib/Language files/Finnish.nlf @@ -7,10 +7,12 @@ NLF v5 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by AKX - Modifications by Eclipser Nullsoft Asennusjrjestelm %s -%s Asennus -%s Poisto +$(^Name) Asennus +$(^Name) Poisto : Lisenssisopimus : Asennusvaihtoehdot : Asennushakemisto @@ -36,7 +38,7 @@ Oma Valitse asennustyyppi: Valitse asennettavat komponentit: Tai, valitse valinnaiset komponentit: -Valitse hakemisto, johon %s asennetaan: +Valitse hakemisto, johon $(^Name) asennetaan: Tilaa vapaana: Tarvittava tila: Poistetaan hakemistosta: diff --git a/Contrib/Language files/French.nlf b/Contrib/Language files/French.nlf index 66a870e5..b8e26502 100644 --- a/Contrib/Language files/French.nlf +++ b/Contrib/Language files/French.nlf @@ -7,10 +7,12 @@ NLF v5 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by the French NSIS team - http://www.winampfr.com/nsis. Nullsoft Install System %s -Installation de %s -Dsinstallation de %s +Installation de $(^Name) +Dsinstallation de $(^Name) : Licence : Options d'installation : Dossier d'installation @@ -36,7 +38,7 @@ Personnalis Slectionnez le type d'installation : Slectionnez les composants installer : Ou, slectionnez les composants optionnels que vous voulez installer : -Slectionnez le dossier d'installation de %s : +Slectionnez le dossier d'installation de $(^Name) : Espace disponible : Espace requis : Dsinstallation de : diff --git a/Contrib/Language files/German.nlf b/Contrib/Language files/German.nlf index 4ad157d1..46b9b142 100644 --- a/Contrib/Language files/German.nlf +++ b/Contrib/Language files/German.nlf @@ -7,10 +7,12 @@ NLF v5 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by L.King, changes by R. Bisswanger Nullsoft Install System %s -%s Installation -%s Deinstallation +$(^Name) Installation +$(^Name) Deinstallation : Lizenzabkommen : Installations-Optionen : Zielverzeichnis @@ -36,7 +38,7 @@ Benutzerdefiniert Installations-Typ bestimmen: Whlen Sie die Komponenten aus, die Sie installieren mchten: oder whlen Sie zustzliche Komponenten aus: -Whlen Sie das Verzeichnis aus, in das Sie %s installieren mchten: +Whlen Sie das Verzeichnis aus, in das Sie $(^Name) installieren mchten: Verfgbarer Speicher: Bentigter Speicher: Deinstalliere aus: diff --git a/Contrib/Language files/Greek.nlf b/Contrib/Language files/Greek.nlf index 0a7e450d..7838b06b 100644 --- a/Contrib/Language files/Greek.nlf +++ b/Contrib/Language files/Greek.nlf @@ -7,10 +7,12 @@ NLF v5 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by Makidis N. Mike Nullsoft Install System %s - '%s' - '%s' + '$(^Name)' + '$(^Name)' : : : @@ -36,7 +38,7 @@ Nullsoft Install System %s : : , : - '%s': + '$(^Name)': : : . : diff --git a/Contrib/Language files/Hebrew.nlf b/Contrib/Language files/Hebrew.nlf index ac3af684..cabeaf05 100644 --- a/Contrib/Language files/Hebrew.nlf +++ b/Contrib/Language files/Hebrew.nlf @@ -7,10 +7,12 @@ NLF v5 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +RTL # Translation by Amir Szekely (aka KiCHiK) Nullsoft Install System %s - %s - %s + $(^Name) + $(^Name) : : : @@ -19,8 +21,8 @@ Nullsoft Install System %s : : : -< & -& > +& > +< & & & & @@ -28,20 +30,20 @@ Nullsoft Install System %s & & -&... +...& & - : - : -, : - %s: +: +: +:, +: $(^Name) : : - : +: :\r\n\t"$0"\r\n ,\r\n , \r\n - :\r\n\t"$0"\r\n , \r\n + :\r\n\t"$0"\r\n , \r\n : - @@ -74,8 +76,8 @@ Nullsoft Install System %s # byte " # kilo - + # mega - + # giga - \ No newline at end of file + \ No newline at end of file diff --git a/Contrib/Language files/Hungarian.nlf b/Contrib/Language files/Hungarian.nlf index 2053c73f..15612675 100644 --- a/Contrib/Language files/Hungarian.nlf +++ b/Contrib/Language files/Hungarian.nlf @@ -7,11 +7,13 @@ NLF v5 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by Soft-Trans Bt. (V2) # Translation by Orfanik Kft. (V3-V5) Nullsoft Teleptrendszer %s -%s Telept -%s Eltvolt +$(^Name) Telept +$(^Name) Eltvolt : Licencszerzds : Teleptsi lehetsgek : Clmappa @@ -37,7 +39,7 @@ Egy Vlassza ki a telepts tpust: Vlassza ki a teleptend sszetevket: vagy, jellje ki a vlaszthat sszetevk kzl a telepteni kvnta(ka)t: -Melyik mappba telepti a(z) %s fjlt: +Melyik mappba telepti a(z) $(^Name) fjlt: Szabad terlet: Helyigny: Eltvolts helye: diff --git a/Contrib/Language files/Italian.nlf b/Contrib/Language files/Italian.nlf index 97ff4b05..f5fc2a10 100644 --- a/Contrib/Language files/Italian.nlf +++ b/Contrib/Language files/Italian.nlf @@ -7,10 +7,12 @@ NLF v2 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by Orfanik - http://www.orfanik.hu Nullsoft Install System %s -Installazione di %s -Disinstallazione di %s +Installazione di $(^Name) +Disinstallazione di $(^Name) : Licenza d'uso : Opzioni di installazione : Cartella di installazione @@ -34,7 +36,7 @@ Personalizzata Seleziona il tipo d'installazione : Seleziona i componenti da installare : Oppure, seleziona i componenti opzionali che vuoi installare : -Seleziona la cartella dove installare %s : +Seleziona la cartella dove installare $(^Name) : Spazio disponibile : Spazio necessario : Rimozione da : diff --git a/Contrib/Language files/Japanese.nlf b/Contrib/Language files/Japanese.nlf index 4492bc25..68d787b4 100644 --- a/Contrib/Language files/Japanese.nlf +++ b/Contrib/Language files/Japanese.nlf @@ -7,10 +7,12 @@ NLF v5 9 # Codepage - dash (-) means ANSI code page 932 +# RTL - anything else than RTL means LTR +- # Translation by Dnanako, updated by Takahiro Yoshimura Nullsoft Install System %s -%s ZbgAbv -%s ACXg[ +$(^Name) ZbgAbv +$(^Name) ACXg[ FCZX_ FCXg[ IvV FCXg[ tH_ @@ -36,7 +38,7 @@ Nullsoft Install System %s CXg[ ^CvIF CXg[ R|[lgIF ܂́ACXg[ IvV R|[lgIF -%s CXg[tH_IĂF +$(^Name) CXg[tH_IĂF p”\ȃfBXNXy[XF KvȃfBXNXy[XF ACXg[F diff --git a/Contrib/Language files/Korean.nlf b/Contrib/Language files/Korean.nlf index dc55009c..379c694c 100644 --- a/Contrib/Language files/Korean.nlf +++ b/Contrib/Language files/Korean.nlf @@ -8,10 +8,12 @@ NLF v5 9 # Codepage - dash (-) means ANSI code page 949 +# RTL - anything else than RTL means LTR +- # Translation by dTomoyo - http://user.chol.com/~ckgfx / Modified by koder@popdesk.co.kr μƮ ġ ý %s -%s ġ -%s +$(^Name) ġ +$(^Name) : : ġ ɼ : @@ -37,7 +39,7 @@ NLF v5 ġ ¸ ϼ: ġϷ Ҹ ϼ: : -%s () ġմϴ: +$(^Name) () ġմϴ: ũ : ʿ ũ : : diff --git a/Contrib/Language files/Lithuanian.nlf b/Contrib/Language files/Lithuanian.nlf index 0ce67a53..b7d0bd58 100644 --- a/Contrib/Language files/Lithuanian.nlf +++ b/Contrib/Language files/Lithuanian.nlf @@ -7,10 +7,12 @@ NLF v3 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by NorCis Nullsoft Install System %s -%s Idiegimas -%s Panaikinti +$(^Name) Idiegimas +$(^Name) Panaikinti : Naudojimo sutartis : Idiegimo nustatymai : Idiegimo katalogas @@ -36,7 +38,7 @@ Kitoks Pasirinkite idiegimo tipa: Pasirinkite komponentus, kuriuos idiegti: Arba, pasirinkite neprivalomus komponentus, kuriuos jus norite idiegti: -Pasirinkite kataloga, kur idiegti %s: +Pasirinkite kataloga, kur idiegti $(^Name): Yra vietos: Reikia vietos: Trinama i: diff --git a/Contrib/Language files/Macedonian.nlf b/Contrib/Language files/Macedonian.nlf index fe10991f..f7538f1b 100644 --- a/Contrib/Language files/Macedonian.nlf +++ b/Contrib/Language files/Macedonian.nlf @@ -7,10 +7,12 @@ NLF v5 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by Sasko Zdravkin [vardarce@mail.com] Nullsoft Install System %s -%s -%s +$(^Name) +$(^Name) : : : @@ -36,7 +38,7 @@ Nullsoft Install System %s : : , : - %s: + $(^Name): : : : diff --git a/Contrib/Language files/Polish.nlf b/Contrib/Language files/Polish.nlf index 260c28f4..62945fd8 100644 --- a/Contrib/Language files/Polish.nlf +++ b/Contrib/Language files/Polish.nlf @@ -7,11 +7,13 @@ NLF v5 - # Codepage - dash (-) means ANSI code page 1250 +# RTL - anything else than RTL means LTR +- # Translation by Piotr Murawski & Rafa Lampe - www.lomsel.prv.pl # corrections, additions, updates by cube cube(at)lp.net.pl Nullsoft Install System %s -%s Instalator -%s Odinstaluj +$(^Name) Instalator +$(^Name) Odinstaluj : Warunki licencji : Opcje instalacji : Folder instalacji @@ -37,7 +39,7 @@ U Wybierz typ instalacji: Wybierz komponenty do zainstalowania: lub wybierz opcjonalne komponenty, ktre chcesz zainstalowa: -Wybierz folder instalacji %s: +Wybierz folder instalacji $(^Name): Dostpne miejsce: Wymagane miejsce: Odinstalowuje z: diff --git a/Contrib/Language files/Portuguese.nlf b/Contrib/Language files/Portuguese.nlf index fb526b2e..52e1b9fb 100644 --- a/Contrib/Language files/Portuguese.nlf +++ b/Contrib/Language files/Portuguese.nlf @@ -8,10 +8,12 @@ NLF v5 - # Codepage - dash (-) means ANSI code page 1252 +# RTL - anything else than RTL means LTR +- # Translation v4.0.3 by DragonSoull with help from Dre` - Updated by Ramon Sistema de Instalao Nullsoft %s -Instalao de %s -Desinstalao de %s +Instalao de $(^Name) +Desinstalao de $(^Name) : Contrato de Licena : Opes de instalao : Directoria de instalao @@ -37,7 +39,7 @@ Personalizada Escolha o tipo de instalao: Escolha os componentes a instalar: Ou, escolha os componentes opcionais que deseja instalar: -Escolha a directoria a instalar %s: +Escolha a directoria a instalar $(^Name): Espao disponvel: Espao necessrio: A Desinstalar de: diff --git a/Contrib/Language files/PortugueseBR.nlf b/Contrib/Language files/PortugueseBR.nlf index 92d449fa..5a243086 100644 --- a/Contrib/Language files/PortugueseBR.nlf +++ b/Contrib/Language files/PortugueseBR.nlf @@ -7,10 +7,12 @@ NLF v5 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by Diego Marcos Sistema de Instalao Nullsoft %s -Instalao do %s -Desinstalao do %s +Instalao do $(^Name) +Desinstalao do $(^Name) : Contrato de Licena : Opes de instalao : Diretrio de instalao @@ -36,7 +38,7 @@ Personalizado Escolha o tipo de instalao: Escolha os componentes para instalar: Ou, selecione os componentes opcionais que deseja instalar: -Escolha o diretrio para instalar %s: +Escolha o diretrio para instalar $(^Name): Espao disponvel: Espao necessrio: Desinstalando de: diff --git a/Contrib/Language files/Romanian.nlf b/Contrib/Language files/Romanian.nlf index 307418f6..4f3dfcb7 100644 --- a/Contrib/Language files/Romanian.nlf +++ b/Contrib/Language files/Romanian.nlf @@ -7,12 +7,14 @@ NLF v5 - # Codepage - dash (-) means ANSI code page 1250 +# RTL - anything else than RTL means LTR +- # Revision by Sorin Sbarnea (sorin@intersol.ro) v5.1 # Translation by Cristian Pirvu (pcristip@yahoo.com) v5 # and Sorin Sbarnea INTERSOL SRL (sorin@intersol.ro) v4 Sistem de instalare Nullsoft %s -Instalare %s -Dezinstalare %s +Instalare $(^Name) +Dezinstalare $(^Name) : Licenta de utilizare : Optiuni de instalare : Directorul de instalare @@ -38,7 +40,7 @@ Nestandard Alegeti tipul instalarii: Alegeti componentele de instalat: Sau alegeti componentele optionale pe care vreti sa le instalati: -Selectati directorul In care vreti sa instalati %s: +Selectati directorul In care vreti sa instalati $(^Name): Spatiu disponibil: Spatiu necesar: Dezinstaleaza din: diff --git a/Contrib/Language files/Russian.nlf b/Contrib/Language files/Russian.nlf index f41eba10..a7787e14 100644 --- a/Contrib/Language files/Russian.nlf +++ b/Contrib/Language files/Russian.nlf @@ -8,10 +8,12 @@ NLF v5 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by Timon [ timon@front.ru ] + 20030720 Nullsoft Install System %s -%s -%s +$(^Name) +$(^Name) : : : @@ -37,7 +39,7 @@ Nullsoft Install System %s : : , , : - %s : + $(^Name) : : : : diff --git a/Contrib/Language files/Serbian.nlf b/Contrib/Language files/Serbian.nlf index c7d0834c..e1b05bf0 100644 --- a/Contrib/Language files/Serbian.nlf +++ b/Contrib/Language files/Serbian.nlf @@ -7,10 +7,12 @@ NLF v5 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by Vladan "vladano@EUnet.yu" Obradovic Nullsoft Install System %s -%s Instalacija -%s Deinstalacija +$(^Name) Instalacija +$(^Name) Deinstalacija : Uslovi Licence : Installacione Opcije : Installacioni Direktorijum @@ -36,7 +38,7 @@ Posebno Odaberi tip instalacije: Odaberi komponente koje eli instalirati: Ili, odaberi opcione komponente koje eli instalirati: -Odaberi direktorijum u koji eli instalirati %s: +Odaberi direktorijum u koji eli instalirati $(^Name): Slobodno na disku: Potrebno na disku: Deinstaliram iz: diff --git a/Contrib/Language files/SimpChinese.nlf b/Contrib/Language files/SimpChinese.nlf index 15413058..82cb970d 100644 --- a/Contrib/Language files/SimpChinese.nlf +++ b/Contrib/Language files/SimpChinese.nlf @@ -7,10 +7,12 @@ NLF v5 9 # Codepage - dash (-) means ANSI code page ANSI ҳ 936 +# RTL - anything else than RTL means LTR +- # Translation by Kii Ali , Revision Date: 2003-05-30 Nullsoft Install System %s -%s װ -%s װ +$(^Name) װ +$(^Name) װ : Ȩ : װѡ : װļ @@ -36,7 +38,7 @@ Nullsoft Install System %s ѡװ: ѡװ: ߣԶѡ밲װ: -ѡҪװ %s ļ: +ѡҪװ $(^Name) ļ: ÿռ: ռ: װĿ¼: diff --git a/Contrib/Language files/Slovak.nlf b/Contrib/Language files/Slovak.nlf index 79f6e4f5..90588e11 100644 --- a/Contrib/Language files/Slovak.nlf +++ b/Contrib/Language files/Slovak.nlf @@ -7,10 +7,12 @@ NLF v3 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by trace & Kypec Nullsoft Install System %s -Intalcia %s -Odintalcia %s +Intalcia $(^Name) +Odintalcia $(^Name) : Licenn zmluva : Monosti intalcie : Adresr intalcie @@ -36,7 +38,7 @@ Vlastn Zvote typ intalcie: Zvote komponenty, ktor sa maj naintalova: Alebo, vyberte voliten komponenty, ktor sa maj naintalova: -Zvote adresr do ktorho sa m %s naintalova: +Zvote adresr do ktorho sa m $(^Name) naintalova: Von priestor: Potrebn priestor: Odintalovvam z: diff --git a/Contrib/Language files/Slovenian.nlf b/Contrib/Language files/Slovenian.nlf index dc9ea0ce..82ee70bf 100644 --- a/Contrib/Language files/Slovenian.nlf +++ b/Contrib/Language files/Slovenian.nlf @@ -8,10 +8,12 @@ NLF v5 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by Janez Dolinar Nullsoft Install System %s -%s Namestitev -%s Odstranitev +$(^Name) Namestitev +$(^Name) Odstranitev : Licenna pogodba : Monosti namestitve : Mapa namestitve @@ -37,7 +39,7 @@ Po meri Izberite tip namestitve: Izberite bloke namestitve: Ali si izberite bloke namestitve, ki jih elite: -Izberi mapo za namestitev %s: +Izberi mapo za namestitev $(^Name): Prosto: Zahtevano: Odstranjujem iz: diff --git a/Contrib/Language files/Spanish.nlf b/Contrib/Language files/Spanish.nlf index f9fe8ba3..63b3de8b 100644 --- a/Contrib/Language files/Spanish.nlf +++ b/Contrib/Language files/Spanish.nlf @@ -7,10 +7,12 @@ NLF v5 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by MoNKi Nullsoft Install System %s -Instalacin de %s -Desinstalacin de %s +Instalacin de $(^Name) +Desinstalacin de $(^Name) : Acuerdo de Licencia : Opciones de Instalacin : Directorio de Instalacin @@ -36,7 +38,7 @@ Personalizada Indique el tipo de instalacin: Seleccione los componentes: O seleccione los componentes opcionales a instalar: -Seleccione el directorio en el que instalar %s: +Seleccione el directorio en el que instalar $(^Name): Espacio disponible: Espacio requerido: Desinstalando desde: diff --git a/Contrib/Language files/Swedish.nlf b/Contrib/Language files/Swedish.nlf index 9784dcae..55e617cf 100644 --- a/Contrib/Language files/Swedish.nlf +++ b/Contrib/Language files/Swedish.nlf @@ -8,10 +8,12 @@ NLF v5 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by Magnus Bonnevier (magnus.bonnevier@telia.com) Nullsoft Install System %s -%s Setup -%s Avinstallation +$(^Name) Setup +$(^Name) Avinstallation : Licens Avtal : Installations Val : Installations Katalog @@ -37,7 +39,7 @@ Custom Vlj typ av installation: Vlj komponenter att installera: Eller, vlj alternativa komponenter du nskar installera: -Vlj katalog att installera %s i: +Vlj katalog att installera $(^Name) i: Ytrymme tillgngligt: Ytrymme som behvs: Avinstallerar frn: diff --git a/Contrib/Language files/Thai.nlf b/Contrib/Language files/Thai.nlf index 86eb919e..e9fee7ff 100644 --- a/Contrib/Language files/Thai.nlf +++ b/Contrib/Language files/Thai.nlf @@ -7,10 +7,12 @@ NLF v2 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by TuW@nNu tuwannu@hotmail.com (asdfuae) Nullsoft Install System %s -%s Դ -%s ͹õԴ +$(^Name) Դ +$(^Name) ͹õԴ : ͵ŧͧԢԷ : ͡õԴ : Դ @@ -34,7 +36,7 @@ Nullsoft Install System %s ͡ٻẺõԴ: ͡๹ͧõԴ: ͡๹ͧõԴ: -Դ %s ŧ: +Դ $(^Name) ŧ: ͷ: ͷͧ: ͹õԴ駨ҡ: diff --git a/Contrib/Language files/TradChinese.nlf b/Contrib/Language files/TradChinese.nlf index 76a9dd77..10346317 100644 --- a/Contrib/Language files/TradChinese.nlf +++ b/Contrib/Language files/TradChinese.nlf @@ -7,10 +7,12 @@ NLF v5 9 # Codepage - dash (-) means ANSI code page ANSI rX 950 +# RTL - anything else than RTL means LTR +- # Translation by Kii Ali , Revision Date: 2003-05-30 Nullsoft Install System %s -%s w -%s Ѱw +$(^Name) w +$(^Name) Ѱw : v : w˿ﶵ : w˸Ƨ @@ -36,7 +38,7 @@ Nullsoft Install System %s w˪: w˪: Ϊ̡AۭqQw˪: -nw %s Ƨ: +nw $(^Name) Ƨ: iΪŶ: һݪŶ: Ѱw˥ؿ: diff --git a/Contrib/Language files/Turkish.nlf b/Contrib/Language files/Turkish.nlf index 3c581ca3..8fa376d8 100644 --- a/Contrib/Language files/Turkish.nlf +++ b/Contrib/Language files/Turkish.nlf @@ -7,10 +7,12 @@ NLF v5 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by Fatih BOY (fatih@smartcoding.org) Nullsoft Kurulum Sistemi %s -%s Kurulumu -%s Uninstaller +$(^Name) Kurulumu +$(^Name) Uninstaller : Szlesme : Kurulum Ayarlari : Kurulum Dizini @@ -36,7 +38,7 @@ Tamamlandi Kurulum seklini seiniz: Kurulacak paketleri seiniz: Veya, kurmak istediginiz paketleri seiniz: -%s kurulumu iin bir dizin sein: +$(^Name) kurulumu iin bir dizin sein: Kalan bos alan: Gerekli bos alan: Kaldiriliyor: diff --git a/Contrib/Language files/Ukrainian.nlf b/Contrib/Language files/Ukrainian.nlf index f36c5317..cfa913f3 100644 --- a/Contrib/Language files/Ukrainian.nlf +++ b/Contrib/Language files/Ukrainian.nlf @@ -7,10 +7,12 @@ NLF v4 - # Codepage - dash (-) means ANSI code page - +# RTL - anything else than RTL means LTR +- # Translation by Yuri Holubow, Nash-Soft.com Nullsoft Install System %s -%s -%s +$(^Name) +$(^Name) : ii : i : i @@ -36,7 +38,7 @@ I i : i : , i , i : -i i %s : +i i $(^Name) : i: i i: : diff --git a/Contrib/StartMenu/Readme.txt b/Contrib/StartMenu/Readme.txt index af1cd51e..0103d904 100644 --- a/Contrib/StartMenu/Readme.txt +++ b/Contrib/StartMenu/Readme.txt @@ -2,7 +2,7 @@ StartMenu.dll shows a custom page that lets the user select a start menu program folder to put shortcuts in. To show the dialog use the Select function. This function has one required parameter -which is the program group default name, and some more optional parameters: +which is the program group default name, and some more optional switches: /autoadd - automatically adds the program name to the selected folder /noicon - doesn't show the icon in the top left corner /text [please select...] - sets the top text to something else than @@ -14,13 +14,20 @@ which is the program group default name, and some more optional parameters: the user checks this box, the return value will have > as its first character and you should not create the program group. + /rtl - sets the direction of every control on the selection dialog + to RTL. This means every text shown on the page will be + justified to the right. + +The order of the switches doesn't matter but the required parameter must come after +all of them. Every switch after the required parameter will be ignored and left +on the stack. The function pushes "success", "cancel" or an error to the stack. If there was no error and the user didn't press on cancel it will push the selected folder name -after "success". If the user checked the no shortcuts checkbox the '>' will be -appended to the folder name. The function does not push the full path but only the -selected sub-folder. It's up to you to decide if to put it in the current user or -all users start menu. +after "success". If the user checked the no shortcuts checkbox the result will be +prefixed with '>'. The function does not push the full path but only the selected +sub-folder. It's up to you to decide if to put it in the current user or all +users start menu. Look at Example.nsi for an example. diff --git a/Contrib/StartMenu/StartMenu.c b/Contrib/StartMenu/StartMenu.c index 01792f76..2a026c68 100644 --- a/Contrib/StartMenu/StartMenu.c +++ b/Contrib/StartMenu/StartMenu.c @@ -22,6 +22,7 @@ char checkbox[1024]; int autoadd = 0; int g_done = 0; int noicon = 0; +int rtl = 0; void *lpWndProcOld; @@ -54,6 +55,10 @@ void __declspec(dllexport) Select(HWND hwndParent, int string_size, char *variab { noicon = 1; } + else if (!lstrcmpi(buf+1, "rtl")) + { + rtl = 1; + } else if (!lstrcmpi(buf+1, "text")) { popstring(text); @@ -73,7 +78,8 @@ void __declspec(dllexport) Select(HWND hwndParent, int string_size, char *variab if (popstring(buf)) *buf = 0; } - if (*buf) lstrcpy(progname, buf); + if (*buf) + lstrcpy(progname, buf); else { pushstring("error reading parameters"); @@ -145,16 +151,22 @@ BOOL CALLBACK dlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) int y_offset = 0; + int width, height; + GetWindowRect(hwChild, &dialog_r); ScreenToClient(hwParent, (LPPOINT) &dialog_r); ScreenToClient(hwParent, ((LPPOINT) &dialog_r)+1); + + width = dialog_r.right - dialog_r.left; + height = dialog_r.bottom - dialog_r.top; + SetWindowPos( hwndDlg, 0, dialog_r.left, dialog_r.top, - dialog_r.right - dialog_r.left, - dialog_r.bottom - dialog_r.top, + width, + height, SWP_NOZORDER | SWP_NOACTIVATE ); @@ -171,6 +183,19 @@ BOOL CALLBACK dlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) SendMessage(hwDirList, WM_SETFONT, (WPARAM) hFont, TRUE); SendMessage(hwCheckBox, WM_SETFONT, (WPARAM) hFont, TRUE); + if (rtl) + { + long s; + s = GetWindowLong(hwText, GWL_STYLE); + SetWindowLong(hwText, GWL_STYLE, (s & ~SS_LEFT) | SS_RIGHT); + s = GetWindowLong(hwLocation, GWL_STYLE); + SetWindowLong(hwLocation, GWL_STYLE, (s & ~ES_LEFT) | ES_RIGHT); + s = GetWindowLong(hwDirList, GWL_EXSTYLE); + SetWindowLong(hwDirList, GWL_EXSTYLE, s | WS_EX_RIGHT | WS_EX_RTLREADING); + s = GetWindowLong(hwCheckBox, GWL_STYLE); + SetWindowLong(hwCheckBox, GWL_STYLE, s | BS_RIGHT | BS_LEFTTEXT); + } + if (!noicon) { SendMessage( @@ -180,39 +205,50 @@ BOOL CALLBACK dlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) (LPARAM)LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(103)) ); } + + GetClientRect(hwIcon, &temp_r); + SetWindowPos( hwIcon, 0, + rtl ? width - temp_r.right : 0, 0, - 0, - 32, - 32, + temp_r.right, + temp_r.bottom, SWP_NOACTIVATE | (noicon ? SWP_HIDEWINDOW : 0) ); - if (!*text) - lstrcpy(text, "Select the Start Menu folder in which you would like to create the program's shortcuts:"); + //GetWindowRect(hwIcon, &temp_r); + //ScreenToClient(hwndDlg, ((LPPOINT) &temp_r)); + //ScreenToClient(hwndDlg, ((LPPOINT) &temp_r) + 1); - GetWindowRect(hwIcon, &temp_r); - temp_r.right += 5; - temp_r.bottom += 5; - ScreenToClient(hwndDlg, ((LPPOINT) &temp_r) + 1); + if (rtl) + { + ProgressiveSetWindowPos( + hwText, + 0, + width - (noicon ? 0 : temp_r.right + 5), + temp_r.bottom + 2 + ); + } + else + { + ProgressiveSetWindowPos( + hwText, + noicon ? 0 : temp_r.right + 5, + width - (noicon ? 0 : temp_r.right + 5), + temp_r.bottom + 2 + ); + } - ProgressiveSetWindowPos( - hwText, - noicon ? 0 : temp_r.right, - dialog_r.right - dialog_r.left - (noicon ? 0 : temp_r.right), - temp_r.bottom + 2 - ); - - SetWindowText(hwText, text); + SetWindowText(hwText, *text ? text : "Select the Start Menu folder in which you would like to create the program's shortcuts:"); GetWindowRect(hwLocation, &temp_r); ProgressiveSetWindowPos( hwLocation, 0, - dialog_r.right - dialog_r.left, + width, temp_r.bottom - temp_r.top ); @@ -233,14 +269,14 @@ BOOL CALLBACK dlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) ProgressiveSetWindowPos( hwDirList, 0, - dialog_r.right - dialog_r.left, - dialog_r.bottom - dialog_r.top - y_offset - (*checkbox ? temp_r.bottom - temp_r.top + 5 : 0) + width, + height - y_offset - (*checkbox ? temp_r.bottom - temp_r.top + 5 : 0) ); ProgressiveSetWindowPos( hwCheckBox, 0, - dialog_r.right - dialog_r.left, + width, temp_r.bottom - temp_r.top ); diff --git a/Contrib/StartMenu/StartMenu.dsp b/Contrib/StartMenu/StartMenu.dsp index 82f0c009..62502efd 100644 --- a/Contrib/StartMenu/StartMenu.dsp +++ b/Contrib/StartMenu/StartMenu.dsp @@ -54,7 +54,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"_DllMainCRTStartup" /dll /machine:I386 /nodefaultlib /out:"../../Plugins/StartMenu.dll" /opt:nowin98 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"_DllMainCRTStartup" /dll /map /machine:I386 /nodefaultlib /out:"../../Plugins/StartMenu.dll" /opt:nowin98 # SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "StartMenu - Win32 Debug" diff --git a/Contrib/System/Source/System.c b/Contrib/System/Source/System.c index 31423bc7..a259e7ef 100644 --- a/Contrib/System/Source/System.c +++ b/Contrib/System/Source/System.c @@ -17,11 +17,12 @@ #define PCD_PARAMS 2 #define PCD_DONE 3 // Just Continue -int ParamSizeByType[6] = {0, // PAT_VOID (Size will be equal to 1) +int ParamSizeByType[7] = {0, // PAT_VOID (Size will be equal to 1) 1, // PAT_INT 2, // PAT_LONG 1, // PAT_STRING - 1, // PAT_BOOLEAN + 1, // PAT_WSTRING + 1, // PAT_GUID 0}; // PAT_CALLBACK (Size will be equal to 1) int z1, z2; // I've made them static for easier use at callback procs @@ -36,7 +37,6 @@ HINSTANCE g_hInstance; char retexpr[3] = {0xC2, 0x00, 0x00}; HANDLE retaddr; - char *GetResultStr(SystemProc *proc) { char *buf = AllocString(); @@ -180,6 +180,7 @@ PLUGINFUNCTION(Call) proc = CallBack(proc); break; case PT_PROC: + case PT_VTABLEPROC: proc = CallProc(proc); break; case PT_STRUCT: CallStruct(proc); break; @@ -253,7 +254,8 @@ PLUGINFUNCTIONSHORT(Int64Op) case '%': // It's unclear, but in this case compiler will use DivMod rountine // instead of two separate Div and Mod rountines. - i3 = i1 / i2; i4 = i1 % i2; + if (i2 == 0) { i3 = 0; i4 = i1; } + else {i3 = i1 / i2; i4 = i1 % i2; } if (*op == '/') i1 = i3; else i1 = i4; break; case '|': if (op[1] == '|') i1 = i1 || i2; else i1 |= i2; break; @@ -306,7 +308,12 @@ SystemProc *PrepareProc(BOOL NeedForCall) { case 0x0: SectionType = -1; break; case '#': SectionType = PST_PROC; ProcType = PT_NOTHING; break; - case '(': SectionType = PST_PARAMS; ParamIndex = 1; temp3 = temp = 0; break; + case '(': + SectionType = PST_PARAMS; + // fake-real parameter: for COM interfaces first param is Interface Pointer + ParamIndex = ((ProcType == PT_VTABLEPROC)?(2):(1)); + temp3 = temp = 0; + break; case ')': SectionType = PST_RETURN; temp3 = temp = 0; break; case '?': SectionType = PST_OPTIONS; temp = 1; break; } @@ -364,6 +371,7 @@ SystemProc *PrepareProc(BOOL NeedForCall) } break; case PT_PROC: + case PT_VTABLEPROC: lstrcpy(proc->ProcName, cbuf); lstrcpy(proc->DllName, sbuf); break; @@ -389,8 +397,16 @@ SystemProc *PrepareProc(BOOL NeedForCall) switch (*ib) { case ':': + case '-': // Is it '::' - if (*(ib+1) != ':') break; + if ((*(ib) == '-') && (*(ib+1) == '>')) + { + ProcType = PT_VTABLEPROC; + } else + { + if ((*(ib+1) != ':') || (*(ib) == '-')) break; + ProcType = PT_PROC; + } ib++; // Skip next ':' if (cb > cbuf) @@ -400,7 +416,6 @@ SystemProc *PrepareProc(BOOL NeedForCall) } else *sbuf = 0; // No dll - system proc // Ok - ProcType = PT_PROC; ChangesDone = PCD_DONE; break; case '*': @@ -442,8 +457,10 @@ SystemProc *PrepareProc(BOOL NeedForCall) case 'L': temp2 = PAT_LONG; break; case 't': case 'T': temp2 = PAT_STRING; break; - case 'b': - case 'B': temp2 = PAT_BOOLEAN; break; + case 'g': + case 'G': temp2 = PAT_GUID; break; + case 'w': + case 'W': temp2 = PAT_WSTRING; break; case 'k': case 'K': temp2 = PAT_CALLBACK; break; @@ -589,6 +606,32 @@ SystemProc *PrepareProc(BOOL NeedForCall) switch (proc->ProcType) { case PT_NOTHING: break; + case PT_VTABLEPROC: + { + // Use direct system proc address + int addr; + + if ((proc->Dll = addr = (HANDLE) myatoi(proc->DllName)) == 0) + { + proc->ProcResult = PR_ERROR; + break; + } + + // fake-real parameter: for COM interfaces first param is Interface Pointer + proc->Params[1].Output = IOT_NONE; + proc->Params[1].Input = AllocStr(proc->DllName); + proc->Params[1].Size = 1; + proc->Params[1].Type = PAT_INT; + proc->Params[1].Option = 0; + + // addr - pointer to interface vtable + addr = *((int *)addr); + // now addr contains the pointer to first item at VTABLE + // add the index of proc + addr = addr + (myatoi(proc->ProcName)*4); + proc->Proc = *((HANDLE*)addr); + } + break; case PT_PROC: if (*proc->DllName == 0) { @@ -607,7 +650,12 @@ SystemProc *PrepareProc(BOOL NeedForCall) // Get proc address if ((proc->Proc = GetProcAddress(proc->Dll, proc->ProcName)) == NULL) - proc->ProcResult = PR_ERROR; + { + // automatic A discover + lstrcat(proc->ProcName, "A"); + if ((proc->Proc = GetProcAddress(proc->Dll, proc->ProcName)) == NULL) + proc->ProcResult = PR_ERROR; + } } break; case PT_STRUCT: @@ -634,6 +682,7 @@ void ParamsIn(SystemProc *proc) { int i, *place; char *realbuf; + LPWSTR wstr; i = (proc->ParamCount > 0)?(1):(0); while (TRUE) @@ -654,7 +703,10 @@ void ParamsIn(SystemProc *proc) // Retreive pointer to place if (proc->Params[i].Option == -1) place = (int*) proc->Params[i].Value; else place = (int*) &(proc->Params[i].Value); - + + // by default no blocks are allocated + proc->Params[i].allocatedBlock = NULL; + // Step 2: place it switch (proc->Params[i].Type) { @@ -671,10 +723,19 @@ void ParamsIn(SystemProc *proc) /* if (proc->Params[i].Input == IOT_NONE) *((int*) place) = (int) NULL; else*/ - *((int*) place) = (int) AllocStr(realbuf); + *((int*) place) = (int) (proc->Params[i].allocatedBlock = AllocStr(realbuf)); break; - case PAT_BOOLEAN: - *((int*) place) = lstrcmpi(realbuf, "true"); + case PAT_WSTRING: + case PAT_GUID: + wstr = (LPWSTR) (proc->Params[i].allocatedBlock = GlobalAlloc(GPTR, g_stringsize*2)); + MultiByteToWideChar(CP_ACP, 0, realbuf, g_stringsize, wstr, g_stringsize); + if (proc->Params[i].Type == PAT_GUID) + { + *((HGLOBAL*)place) = (proc->Params[i].allocatedBlock = GlobalAlloc(GPTR, 16)); + CLSIDFromString(wstr, *((LPCLSID*)place)); + GlobalFree((HGLOBAL) wstr); + } else + *((LPWSTR*)place) = wstr; break; case PAT_CALLBACK: // Generate new or use old callback @@ -718,6 +779,7 @@ void ParamsOut(SystemProc *proc) { int i, *place; char *realbuf; + LPWSTR wstr; i = proc->ParamCount; do @@ -745,17 +807,29 @@ void ParamsOut(SystemProc *proc) int num = lstrlen(*((char**) place)); if (num >= g_stringsize) num = g_stringsize-1; lstrcpyn(realbuf,*((char**) place), num+1); - realbuf[num] = 0; + realbuf[num] = 0; } break; - case PAT_BOOLEAN: - lstrcpy(realbuf,(*((int*) place))?("true"):("false")); + case PAT_GUID: + wstr = (LPWSTR) GlobalAlloc(GPTR, g_stringsize*2); + StringFromGUID2(*((REFGUID*)place), wstr, g_stringsize*2); + WideCharToMultiByte(CP_ACP, 0, wstr, g_stringsize, realbuf, g_stringsize, NULL, NULL); + GlobalFree((HGLOBAL)wstr); + break; + case PAT_WSTRING: + wstr = *((LPWSTR*)place); + WideCharToMultiByte(CP_ACP, 0, wstr, g_stringsize, realbuf, g_stringsize, NULL, NULL); break; case PAT_CALLBACK: wsprintf(realbuf, "%d", proc->Params[i].Value); break; } + // memory cleanup + if ((proc->Params[i].allocatedBlock != NULL) && ((proc->ProcType != PT_STRUCT) + || (proc->Params[i].Option > 0))) + GlobalFree(proc->Params[i].allocatedBlock); + // Step 2: place it if (proc->Params[i].Output == IOT_NONE); else if (proc->Params[i].Output == IOT_STACK) pushstring(realbuf); @@ -1160,7 +1234,11 @@ void CallStruct(SystemProc *proc) // pointer ptr = (char*) &(proc->Params[i].Value); break; - case PAT_STRING: ptr = (char*) proc->Params[i].Value; break; + + case PAT_STRING: + case PAT_GUID: + case PAT_WSTRING: + ptr = (char*) proc->Params[i].Value; break; } } diff --git a/Contrib/System/Source/System.h b/Contrib/System/Source/System.h index 2ce5c50e..1a30f803 100644 --- a/Contrib/System/Source/System.h +++ b/Contrib/System/Source/System.h @@ -18,6 +18,7 @@ #define PT_NOTHING 0 #define PT_PROC 1 #define PT_STRUCT 2 +#define PT_VTABLEPROC 3 // Proc results: #define PR_OK 0 @@ -29,8 +30,9 @@ #define PAT_INT 1 #define PAT_LONG 2 #define PAT_STRING 3 -#define PAT_BOOLEAN 4 -#define PAT_CALLBACK 5 +#define PAT_WSTRING 4 +#define PAT_GUID 5 +#define PAT_CALLBACK 6 // Input/Output Source/Destination #define IOT_NONE 0 @@ -58,6 +60,7 @@ typedef struct int Size; // Value real size (should be either 1 or 2 (the number of pushes)) int Input; int Output; + HGLOBAL allocatedBlock; // block allocated for passing string, wstring or guid param } ProcParameter; // Our single proc (Since the user will free proc with GlobalFree, diff --git a/Contrib/System/Source/System.sln b/Contrib/System/Source/System.sln index 9268efc2..48478b66 100644 --- a/Contrib/System/Source/System.sln +++ b/Contrib/System/Source/System.sln @@ -1,12 +1,12 @@ -Microsoft Visual Studio Solution File, Format Version 7.00 +Microsoft Visual Studio Solution File, Format Version 8.00 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "System", "System.vcproj", "{2FB013AB-6FD4-4239-9974-C999F4DFD70C}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection EndProject Global GlobalSection(SolutionConfiguration) = preSolution - ConfigName.0 = Debug - ConfigName.1 = Release - EndGlobalSection - GlobalSection(ProjectDependencies) = postSolution + Debug = Debug + Release = Release EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {2FB013AB-6FD4-4239-9974-C999F4DFD70C}.Debug.ActiveCfg = Debug|Win32 diff --git a/Contrib/System/Source/System.vcproj b/Contrib/System/Source/System.vcproj index 8c557e43..afd4ac7f 100644 --- a/Contrib/System/Source/System.vcproj +++ b/Contrib/System/Source/System.vcproj @@ -1,7 +1,7 @@ - + @@ -19,7 +19,7 @@ + + + + CharacterSet="2" + WholeProgramOptimization="FALSE"> + DebugInformationFormat="3" + CompileAs="1"/> + + + + + - - + + + + + + RelativePath="stdafx.h"> + RelativePath="System.h"> Handle to system proc (memory address) *addr -> Structure * -> New structure + IPtr->MemberIdx -> Call member with member index from interface given + by interface pointer IPtr (IPtr will be passed to + proc automatically, use like C++ call). nothing -> Dup proc, usually callback or for future defenition proc -> Ready proc specification for use or redefinition @@ -109,8 +112,8 @@ Params & Return - Type: i - int (includes char, byte, short, handles, pointers and so on) l - long & large integer (know as int64) t - text, string (LPCSTR, pointer to first character) - b - boolean (needs/returns 'true':'false') - by the fact this type is - senseless -> usual integer can be used ('0':'1') + w - WCHAR text, or unicode string. + g - GUID k - callback. See Callback section. * - pointer specifier -> the proc needs the pointer to type, affects @@ -124,7 +127,10 @@ For structures: &i - smaller types: &i4, &i2 (short), &i1 (byte) &l - cumbersome, but &lN means the structure size (N bytes value), calculated automaticaly, outputed always as int (N could be 0). - &t - structure contains plain text, &tN - lenght == N bytes. + &t - structure contains plain text, &tN, where lenght == N bytes. + &w - structure contains plain unicode text, &tN, + where lenght == (N)/2 chars = N bytes. + &g - &gN copy N bytes of plain GUID. in fact guid size is 16 :) ---------------------------------- Params & Return - Source / Destination: diff --git a/Contrib/UIs/UI Holder/resource.h b/Contrib/UIs/UI Holder/resource.h index e3522a98..df080c82 100644 --- a/Contrib/UIs/UI Holder/resource.h +++ b/Contrib/UIs/UI Holder/resource.h @@ -2,35 +2,27 @@ // Microsoft Developer Studio generated include file. // Used by resource.rc // +#ifndef DS_SHELLFONT +#define DS_SHELLFONT (DS_SETFONT | DS_FIXEDSYS) +#endif + #define IDC_BACK 3 -#define IDD_DIALOG1 101 -#define IDI_ICON1 102 -#define IDD_DIALOG2 102 #define IDD_LICENSE 102 +#define IDD_LICENSE_FSRB 108 +#define IDD_LICENSE_FSCB 109 #define IDI_ICON2 103 #define IDD_DIR 103 #define IDD_SELCOM 104 #define IDD_INST 105 #define IDD_INSTFILES 106 #define IDD_UNINST 107 -#define IDB_BITMAP1 109 -#define IDB_BITMAP2 110 -#define IDI_ICON3 110 #define IDD_VERIFY 111 -#define IDB_BITMAP3 111 +#define IDB_BITMAP1 110 #define IDC_EDIT1 1000 #define IDC_BROWSE 1001 -#define IDC_COPYRIGHT 1003 #define IDC_PROGRESS 1004 #define IDC_INTROTEXT 1006 -#define IDC_WMA 1007 #define IDC_CHECK1 1008 -#define IDC_MJF 1008 -#define IDC_VERSION 1009 -#define IDC_EDIT2 1010 -#define IDC_DIRCAPTION 1011 -#define IDC_STATUSTEXT 1014 -#define IDC_LICTEXT 1015 #define IDC_LIST1 1016 #define IDC_COMBO1 1017 #define IDC_CHILDRECT 1018 @@ -40,9 +32,6 @@ #define IDC_TEXT2 1022 #define IDC_SPACEREQUIRED 1023 #define IDC_SPACEAVAILABLE 1024 -#define IDC_INSTVER 1024 -#define IDC_UNINSTTEXT 1025 -#define IDC_PROGRESSTEXT 1026 #define IDC_SHOWDETAILS 1027 #define IDC_VERSTR 1028 #define IDC_UNINSTFROM 1029 @@ -50,6 +39,8 @@ #define IDC_ULICON 1031 #define IDC_TREE1 1032 #define IDC_BRANDIMAGE 1033 +#define IDC_LICENSEAGREE 1034 +#define IDC_LICENSEDISAGREE 1035 // Next default values for new objects // @@ -57,7 +48,9 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 112 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1034 +#define _APS_NEXT_CONTROL_VALUE 1036 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif + + diff --git a/Contrib/UIs/UI Holder/resource.rc b/Contrib/UIs/UI Holder/resource.rc index ba18d09e..b8bd59e4 100644 --- a/Contrib/UIs/UI Holder/resource.rc +++ b/Contrib/UIs/UI Holder/resource.rc @@ -25,92 +25,156 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // Dialog // -IDD_LICENSE DIALOGEX DISCARDABLE 0, 0, 266, 130 -STYLE DS_CONTROL | DS_SHELLFONT | WS_CHILD -FONT 8, "MS Shell Dlg" +IDD_LICENSE DIALOGEX 0, 0, 266, 130 +STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - ICON IDI_ICON2,IDC_ULICON,0,0,20,20 + ICON IDI_ICON2,IDC_ULICON,0,0,22,20 LTEXT "",IDC_INTROTEXT,25,0,241,23 CONTROL "",IDC_EDIT1,"RichEdit20A",WS_BORDER | WS_VSCROLL | 0x804,0,24,266,105 END -IDD_DIR DIALOGEX DISCARDABLE 0, 0, 266, 130 -STYLE DS_CONTROL | DS_SHELLFONT | WS_CHILD +IDD_LICENSE_FSRB DIALOG DISCARDABLE 0, 0, 266, 130 +STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CAPTION FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_ICON2,1031,0,0,22,20 + LTEXT "",IDC_INTROTEXT,25,0,241,23 + CONTROL "",IDC_EDIT1,"RichEdit20A",WS_BORDER | WS_VSCROLL | + 0x804,0,24,266,85 + CONTROL "",IDC_LICENSEDISAGREE,"Button",BS_AUTORADIOBUTTON | + WS_TABSTOP,0,120,266,9 + CONTROL "",IDC_LICENSEAGREE,"Button",BS_AUTORADIOBUTTON | + WS_TABSTOP,0,110,266,9 +END + +IDD_LICENSE_FSCB DIALOG DISCARDABLE 0, 0, 266, 130 +STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CAPTION +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_ICON2,1031,0,0,22,20 + LTEXT "",IDC_INTROTEXT,25,0,241,23 + CONTROL "",IDC_EDIT1,"RichEdit20A",WS_BORDER | WS_VSCROLL | + 0x804,0,24,266,95 + CONTROL "",IDC_LICENSEAGREE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,0,120,266,9 +END + +IDD_DIR DIALOGEX 0, 0, 266, 130 +STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN EDITTEXT IDC_DIR,8,49,187,12,ES_AUTOHSCROLL PUSHBUTTON "",IDC_BROWSE,202,48,55,14 - ICON IDI_ICON2,IDC_ULICON,0,0,20,20 - CONTROL "",IDC_SELDIRTEXT,"Static",SS_LEFTNOWORDWRAP, - 0,36,265,8 - CONTROL "",IDC_SPACEAVAILABLE,"Static",SS_LEFTNOWORDWRAP,0,122,265,8 + ICON IDI_ICON2,IDC_ULICON,0,0,22,20 + + CONTROL "",IDC_SPACEAVAILABLE,"Static",SS_LEFTNOWORDWRAP,0,122, + 265,8 CONTROL "",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | - WS_TABSTOP,8,65,118,10 - CONTROL "",IDC_SPACEREQUIRED,"Static",SS_LEFTNOWORDWRAP,0,111,265,8 + WS_TABSTOP,8,71,118,10 + CONTROL "",IDC_SPACEREQUIRED,"Static",SS_LEFTNOWORDWRAP,0,111, + 265,8 LTEXT "",IDC_INTROTEXT,25,0,241,34 + GROUPBOX "",IDC_SELDIRTEXT,1,38,264,30 END -IDD_SELCOM DIALOGEX DISCARDABLE 0, 0, 266, 130 -STYLE DS_CONTROL | DS_SHELLFONT | WS_CHILD -FONT 8, "MS Shell Dlg" +IDD_SELCOM DIALOGEX 0, 0, 266, 130 +STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - COMBOBOX IDC_COMBO1,114,25,152,102,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP | NOT WS_VISIBLE - ICON IDI_ICON2,IDC_ULICON,0,0,21,20 + COMBOBOX IDC_COMBO1,114,25,152,102,CBS_DROPDOWNLIST | NOT + WS_VISIBLE | WS_VSCROLL | WS_TABSTOP + ICON IDI_ICON2,IDC_ULICON,0,0,22,20 LTEXT "",IDC_TEXT2,0,40,108,65 CONTROL "",IDC_TEXT1,"Static",SS_LEFTNOWORDWRAP,0,27,108,8 - CONTROL "",IDC_SPACEREQUIRED,"Static",SS_LEFTNOWORDWRAP,0,111,111,8 + LTEXT "",IDC_SPACEREQUIRED,0,111,111,18,NOT WS_GROUP LTEXT "",IDC_INTROTEXT,25,0,241,25 CONTROL "",IDC_TREE1,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP | WS_BORDER | WS_TABSTOP,114,39,151,90 END -IDD_INST DIALOGEX DISCARDABLE 0, 0, 280, 162 -STYLE DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_BORDER -FONT 8, "MS Shell Dlg" +IDD_INST DIALOGEX 0, 0, 280, 162 +STYLE DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | + WS_SYSMENU +FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - PUSHBUTTON "",IDC_BACK,171,142,50,14,WS_GROUP | NOT WS_VISIBLE + PUSHBUTTON "",IDC_BACK,171,142,50,14,NOT WS_VISIBLE | WS_GROUP PUSHBUTTON "",IDOK,223,142,50,14 PUSHBUTTON "",IDCANCEL,7,142,50,14 - CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ | WS_GROUP,7,138,267,1 - CONTROL "",IDC_CHILDRECT,"Static",SS_BLACKRECT | NOT WS_VISIBLE | WS_GROUP, - 7,6,266,130 - CTEXT "",IDC_VERSTR,59,145,108,8,WS_DISABLED | WS_GROUP + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ | WS_GROUP,7,138, + 267,1 + CONTROL "",IDC_CHILDRECT,"Static",SS_BLACKRECT | NOT WS_VISIBLE | + WS_GROUP,7,6,266,130 + CTEXT "",IDC_VERSTR,59,145,108,8,WS_DISABLED END -IDD_INSTFILES DIALOGEX DISCARDABLE 0, 0, 266, 130 -STYLE DS_CONTROL | DS_SHELLFONT | WS_CHILD -FONT 8, "MS Shell Dlg" +IDD_INSTFILES DIALOGEX 0, 0, 266, 130 +STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - CONTROL "",IDC_PROGRESS,"msctls_progress32",WS_BORDER,24,10,241,11 - CONTROL "",IDC_INTROTEXT,"Static",SS_LEFTNOWORDWRAP, - 24,0,241,8 + CONTROL "",IDC_PROGRESS,"msctls_progress32",WS_BORDER,24,10,241, + 11 + CONTROL "",IDC_INTROTEXT,"Static",SS_LEFTNOWORDWRAP,24,0,241,8 CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_NOCOLUMNHEADER | NOT WS_VISIBLE | WS_BORDER | WS_TABSTOP,0,25,265,104 - ICON IDI_ICON2,IDC_ULICON,0,0,20,20 + ICON IDI_ICON2,IDC_ULICON,0,0,22,20 PUSHBUTTON "",IDC_SHOWDETAILS,0,28,60,14,NOT WS_TABSTOP END -IDD_UNINST DIALOGEX DISCARDABLE 0, 0, 266, 130 -STYLE DS_CONTROL | DS_SHELLFONT | WS_CHILD -FONT 8, "MS Shell Dlg" +IDD_UNINST DIALOGEX 0, 0, 266, 130 +STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - ICON IDI_ICON2,IDC_ULICON,0,1,20,20 + ICON IDI_ICON2,IDC_ULICON,0,1,22,20 LTEXT "",IDC_UNINSTFROM,0,45,55,8 EDITTEXT IDC_EDIT1,56,43,209,12,ES_AUTOHSCROLL | ES_READONLY LTEXT "",IDC_INTROTEXT,25,0,241,34 END -IDD_VERIFY DIALOGEX DISCARDABLE 0, 0, 162, 22 -STYLE DS_MODALFRAME | DS_SHELLFONT | DS_CENTER | WS_POPUP | WS_VISIBLE -FONT 8, "MS Shell Dlg" +IDD_VERIFY DIALOGEX 0, 0, 162, 22 +STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP +FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN CTEXT "",IDC_STR,7,7,148,8 END + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + "IDD_INST$(NSIS_CONFIG_VISIBLE_SUPPORT)", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 273 + TOPMARGIN, 6 + BOTTOMMARGIN, 156 + END + + "IDD_INSTFILES$(NSIS_CONFIG_VISIBLE_SUPPORT)", DIALOG + BEGIN + RIGHTMARGIN, 246 + BOTTOMMARGIN, 125 + END + + "IDD_VERIFY$(_NSIS_CONFIG_VERIFYDIALOG)", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 155 + TOPMARGIN, 7 + BOTTOMMARGIN, 15 + END +END +#endif // APSTUDIO_INVOKED + + #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // @@ -125,6 +189,7 @@ END 2 TEXTINCLUDE DISCARDABLE BEGIN "#include ""afxres.h""\r\n" + "#include ""config.h""\0" END 3 TEXTINCLUDE DISCARDABLE @@ -134,4 +199,7 @@ END #endif // APSTUDIO_INVOKED -#endif \ No newline at end of file +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + diff --git a/Contrib/UIs/default.exe b/Contrib/UIs/default.exe index 3c5d062683c7fc40437b88b1ea5f9bc3f420265b..4fe5b8dd13f94429631cada707f4ff765d4770c7 100755 GIT binary patch delta 996 zcmcJNJ7`m36vzMH%{5I@?9I)iruBibSR6!xlZa>%TN@vRm@3xENE4e>n?w?5wqAlt z7R7j$I9N04AQURnMXBJ>NsFU6bnH}7mmr1f$$gmM;^cvk-+6xDJ?9?ns1|vwo!I}a zrCxvZG2T6&;t96DJfL`zx%-tKpJp!A*A1rfGr3M~BOE%E90x858OMH3o`EHsP(;6Q z0x~kTca{KcmRV=!m@Q_WxyqblZZK~%x0rXB z5YXlsA!d;oVba<_g3<#4xheodsoP4^R$kc3s--Nhv$7d8Uh3Ry$dNH%jQzHhcvh!+ z?B#PD>9r?-eLeO@0{CDTGn;YXbB|p*3%oIHkAdcSAl(T2sj4K!AiekQed3cTtvYF2 zi4P~_wP+`8myzocHG_Z)w4@9#I)J3*!5{+YlXblYUGK~jkc`+6Yu~X4+m24m6xr3X z>O$~{tJrd+kjD&i7)OS+3XUU!n3WB6iz2zt!mpJKa*&Svon z{huCg{IdtgUp-i#No6HSQLkpqK1`B&P)yK>dYN_8 delta 583 zcmYk2KS*0)6vfZ?cqA`sV$91w&<+7xR8*2h1w|6IZJ@TKDzrre#l$2A6D7f9Ga$GL zPcHrm;NTWNax(ucY5@w?|-&gJrzgXLkZyjL51^Wio+ zUNN69Gg|q{`cHV%;B9oQa>qK$`aAPHW2yXL4!sB&Tu85{{$=sMVvm7&A!B5DX4>?= zqFZzd3m~)OXt^JIm`)ruS0vp^JJK_%iPH|<%5IpS(pZpwSt66tVj>%Vp2+9dl8Fd# zz`F1%osH*;ONml}onvV+l`FO^VE=v|%jJPkM(9tTH#5 z@0l6q4Kv5oL0N}aRs=xX4!7(#n*p<#Xf@GvDFVFXh*`lIV2+1o6=s2{HeH|NNxSA> z>ub|jPk>7^%+#J5=kp-}myh)Buy9kznWO=iW^}#wE+7Wi%3r_8jL851 diff --git a/Contrib/UIs/sdbarker_tiny.exe b/Contrib/UIs/sdbarker_tiny.exe index c2eb8ee47d785168838c54706a18ba3d7f84ac8e..0f4a99bf684c11940531d41e4805cd536859d90e 100644 GIT binary patch delta 506 zcmZXPze_?<9L3MIN98koni@hP2DJrATNGix$Z9B}KftLUR+L*?Z*)|?OIzYpvkeX* z4h@bD4NcP66xGyb$NRkSpbL-BIq%%>`M&4QyV=UOid27!0oYOs?8&3Lw_yXw@v$3+ zf!EM(5XUsvfO|rg$y2gMo{>$mNOs9{@`Jn}q2OK;N%D%!lF|<6r4Wu=Hww_AY{Z=r z4@NYH;G?5@ z+D@bB99hzuOf`D3x{^ZFl3FY+y?91ik+i(i=c1$X>15QjIFXrUQx}9f;Mc)cL4+)z z-*-)<>E(+$x4m5UqX}upSN}E74VstC_=vB0IH@DW9p+AF9Ip4{bxcXsS&-*M@(&1Z BT3P@A delta 277 zcmZoLXwaGPk&$oWr!1x`?2`+byeF?@oX>TIoq>VD0f;#^2QgjYwqR#S19B1=7#h-n zbOn&k0MZkHbS98q0i?5l^Z_894Ww@X>3kslfnjnUpBM`VBLlo0B28JUr%|N=uee)^) r5EkJ?hCGI11_g#-hE#?khD?yRHtUM4XJk3S!7yR+2JwK&X^c7mxO^|! diff --git a/Docs/src/attributes.but b/Docs/src/attributes.but index 139ac1b7..40e51c32 100644 --- a/Docs/src/attributes.but +++ b/Docs/src/attributes.but @@ -32,13 +32,13 @@ Specifies whether or not to use a gradient background window. If 'off', the inst \S2{abrandingtext} BrandingText -\c [/LANG=lang_id] /TRIM(LEFT|RIGHT|CENTER) text +\c /TRIM(LEFT|RIGHT|CENTER) text Sets the text that is shown (by default it is 'Nullsoft Install System vX.XX') in the bottom of the install window. Setting this to an empty string ("") uses the default; to set the string to blank, use " " (a space). If it doesn't matter to you, leave it the default so that everybody can know why the installer didn't suck. heh. Use /TRIMLEFT, /TRIMRIGHT or /TRIMCENTER to trim down the size of the control to the size of the string. \S2{acaption} Caption -\c [/LANG=lang_id] caption +\c caption Sets what the titlebars of the installer will display. By default, it is 'Name Setup', where Name is specified with the \R{aname}{Name command}. You can, however, override it with 'MyApp Installer' or whatever. If you specify an empty string (""), the default will be used (you can however specify " " to achieve a blank string) @@ -72,13 +72,13 @@ This bitmap should have a size of 96x16 pixels, no more than 8bpp (256 colors) a \S2{acompletedtext} CompletedText -\c [/LANG=lang_id] Completed text +\c Completed text Replaces the default text ("Completed") that is printed at the end of the install if parameter is specified. Otherwise, the default is used. \S2{acomponenttext} ComponentText -\c [[/LANG=lang_id] text [subtext] [subtext2]] +\c [text [subtext] [subtext2]] Specifies a string that is above the component list. This can be something that notifies the user what it is they are actually installing. Note that if no parameter is specified, or if the ComponentText command is omitted, then the component page will not be visible, and all of the sections will be installed. Note: if text is specified and non-empty and you leave subtext or subtext2 empty, the defaults will be used (to set one to blank, use a string like " "). empty strings mean default on subtext and subtext2. Likewise, if you wish to enable the component page, but don't want any text on the top line, set text to " ". @@ -90,7 +90,7 @@ Specifies whether or not the installer will perform a CRC on itself before allow \S2{adetailsbuttontext} DetailsButtonText -\c [/LANG=lang_id] show details text +\c show details text Replaces the default details button text of "Show details", if parameter is specified (otherwise the default is used). @@ -102,13 +102,19 @@ Specifies whether or not the user will see the directory selection page. Note th \S2{adirtext} DirText -\c [[/LANG=lang_id] text [subtext] [browse text]] +\c [text] [subtext] [browse_button_text] [browse_dlg_text] Specifies a string that is above the directory selection area. If this command is not specified, or no parameter is specified, then the directory page is never visible to the user (even if DirShow show is specified). If subtext is specified and not empty, it overrides the default text above the path entry box ("Select the directory to install MyApp in:"). If browse button text is specified but not empty, it overrides the default browse button text ("Browse..."). +\S2{adirvar} DirVar + +\c user_var(dir input/output) + +Specifies which variable is to be used to contain the directory selected. This variable should contain the default value too. This allows to easily create two different directory pages that will not require you to move values in and out of $INSTDIR. The default variable is $INSTDIR. This can only be used in \R{pageex}{PageEx} and for directory and uninstConfirm pages. + \S2{a} FileErrorText -\c [/LANG=lang_id] file error text +\c file error text Replaces the default text that comes up when a file cannot be written to. This string can contain a reference to $0, which is the filename ($0 is temporarily changed to this value). Example: "Can not write to file $\\r$\\n$0$\\r$\\ngood luck, bitch.". @@ -120,7 +126,7 @@ Sets the icon of the installer. Every icon in the icon file will be included in \S2{ainstallbuttontext} InstallButtonText -\c [/LANG=lang_id] install button text +\c install button text If parameter is specified, overrides the default install button text (of "Install") with the specified text. @@ -150,7 +156,7 @@ Valid values for flag are "smooth" (smooth the progress bar) or "colored" (color \S2{ainsttype} InstType -\c install_type_name | /NOCUSTOM | ([/LANG=lang_id] /CUSTOMSTRING=str) | /COMPONENTSONLYONCUSTOM +\c install_type_name | /NOCUSTOM | /CUSTOMSTRING=str | /COMPONENTSONLYONCUSTOM Adds an install type to the install type list, or disables the custom install type. There can be as many as 32 types, each one specifying the name of the install. Instead of an "hard-coded" name you can use User Variables which are processed at Runtime. This allows you to change InstType name dynamically. Another way of changing the InstType name during runtime is the \R{sinsttypesettext}{InstTypeSetText} command. The difference is that with InstTypeSetText you are saving your precious user variables. The first type is the default (generally 'Typical'). Each type is numbered, starting at 1. See SectionIn for information on how those numbers are used. If the /NOCUSTOM switch is specified, then the "custom" install type is disabled, and the user has to choose one of the pre-defined install types. Alternatively, if the /CUSTOMSTRING switch is specified, the parameter will override the "Custom" install type text. Alternatively, if the /COMPONENTSONLYONCUSTOM flag is specified, the component list will only be show n if the "Custom" install type is selected. @@ -163,33 +169,33 @@ Sets the background color of the license data. Color is specified using the form \S2{alicensedata} LicenseData -\c [/LANG=lang_id] licdata.(txt|rtf) +\c licdata.(txt|rtf) -Specifies a text file or a RTF file to use for the license that the user can read. Omit this to not have a license displayed. Note that the file must be in the evil DOS text format (\\r\\n, yeah!) +Specifies a text file or a RTF file to use for the license that the user can read. Omit this to not have a license displayed. Note that the file must be in the evil DOS text format (\\r\\n, yeah!). To define a multilingual license data use \R{licenselangstring}{LicenseLangString}. If you make your license file a RTF file it is recommended you edit it with WordPad and not MS Word. Using WordPad will result in a much smaller file. \S2{alicenseforceselection} LicenseForceSelection -\c [/LANG=lang_id] (checkbox [accept_text] | radiobuttons [accept_text] [decline_text] | \\off\\) +\c (checkbox [accept_text] | radiobuttons [accept_text] [decline_text] | \\off\\) Specifies if the displayed license must be accept explicit or not. This can be done either by a checkbox or by radiobuttons. By default the "next button" is disabled and will only be enabled if the checkbox is enabled or the right radio button is selected. If off is specified the "next button" is enabled by default. \S2{alicensetext} LicenseText -\c [[/LANG=lang_id] text [button_text]] +\c [text [button_text]] Specifies a string that is above the license text. Omit this to not have a license displayed. If button_text is specified, it will override the default button text of "I Agree". \S2{amiscbuttontext} MiscButtonText -\c [[/LANG=lang_id] back button text [next button text] [cancel button text] [close button text]] +\c [back button text [next button text] [cancel button text] [close button text]] Replaces the default text strings for the four buttons (< Back, Next >, Cancel and Close). If parameters are omitted, the defaults are used. \S2{aname} Name -\c [/LANG=lang_id] name +\c name Sets the name of the installer. The name is usually simply the product name such as 'MyApp' or 'CrapSoft MyApp'. @@ -231,25 +237,25 @@ Specifies whether or not the uninstaller should be silent. If it is 'silent' or \S2{aspacetexts} SpaceTexts -\c [[/LANG=lang_id] req text [avail text]] +\c [req text [avail text]] If parameters are specified, overrides the space required and space available text ("Space required: " and "Space available: " by default). If 'none' is specified as the required text no space texts will be shown. \S2{asubcaption} SubCaption -\c [[/LANG=lang_id] page_number subcaption] +\c [page_number subcaption] Overrides the subcaptions for each of the installer pages (0=": License Agreement",1=": Installation Options",2=": Installation Directory", 3=": Installing Files", 4=": Completed"). If you specify an empty string (""), the default will be used (you can however specify " " to achieve a blank string) \S2{auninstallbuttontext} UninstallButtonText -\c [/LANG=lang_id] button text +\c button text Changes the text of the button that by default says "Uninstall" in the uninstaller. If no parameter is specified, the default text is used. See also \R{WriteUninstaller}{WriteUninstaller} (replaces UninstallEXEName). \S2{auninstallcaption} UninstallCaption -\c [/LANG=lang_id] caption +\c caption Sets what the titlebars of the uninstaller will display. By default, it is 'Name Uninstall', where Name is specified with the Name command. You can, however, override it with 'MyApp uninstaller' or whatever. If you specify an empty string (""), the default will be used (you can however specify " " to achieve a blank string) @@ -261,13 +267,13 @@ Sets the icon of the uninstaller. This icon file \e{must} have the exact same st \S2{auninstallsubcaption} UninstallSubCaption -\c [/LANG=lang_id] page_number subcaption +\c page_number subcaption Overrides the subcaptions for each of the uninstaller pages (0=": Confirmation",1=": Uninstalling Files",2=": Completed"). If you specify an empty string (""), the default will be used (you can however specify " " to achieve a blank string) \S2{auninstalltext} UninstallText -\c [/LANG=lang_id] text [subtext] +\c text [subtext] Specifies the text on the first page of the uninstaller. If subtext is specified and not empty, it will replace the default secondary text on that page, "Uninstall from:". diff --git a/Docs/src/callback.but b/Docs/src/callback.but index b2a90eda..a81add66 100644 --- a/Docs/src/callback.but +++ b/Docs/src/callback.but @@ -17,7 +17,8 @@ Example: \c GetDlgItem $R0 $HWNDPARENT 1028 \c CreateFont $R1 "Tahoma" 10 700 \c SendMessage $R0 ${WM_SETFONT} $R1 0 -\c SetBkColor $R0 0x00FFFFFF +\c # set background color to white and text color to red +\c SetCtlColors $R0 FFFFFF FF0000 \c FunctionEnd \S3{oninit} .onInit diff --git a/Docs/src/flowcontrol.but b/Docs/src/flowcontrol.but index f8d544c2..c828ca16 100644 --- a/Docs/src/flowcontrol.but +++ b/Docs/src/flowcontrol.but @@ -69,6 +69,12 @@ Checks for existence of file(s) file_to_check_for (which can be a wildcard, or a Checks the reboot flag, and jumps to jump_if_set if the reboot flag is set, otherwise jumps to jump_if_not_set. The reboot flag can be set by Delete and Rename, or manually with SetRebootFlag. +\S2{ifsilent} IfSilent + +\c [jump_if_silent] [jump_if_not] + +Checks the silent flag, and jumps to jump_if_silent if the installer is silent, otherwise jumps to jump_if_not. The silent flag can be set by \R{asilentinstall}{SilentInstall}, \R{asilentuninstall}{SilentUninstall}, \R{setsilent}{SetSilent} and by the user passing /S on the command line. + \S2{intcmp} IntCmp \c val1 val2 jump_if_equal [jump_if_val1_less] [jump_if_val1_more] diff --git a/Docs/src/history.but b/Docs/src/history.but index 9afe816d..3938416f 100644 --- a/Docs/src/history.but +++ b/Docs/src/history.but @@ -5,6 +5,10 @@ \b User variables ($VARNAME) that can be declared with the \R{var}{Var} command +\b Added \R{pageex}{PageEx}, \R{pagecallbacks}{PageCallbacks} and \R{adirvar}{DirVar} - it's now a lot easier to add the same page type twice + +\b Extraction progress + \b \W{../Contrib/Modern UI/Readme.html}{Modern UI 1.65}: Easier page macro system, language specific fonts, \R{alicenseforceselection}{LicenseForceSelection} support, new options for Finish page / language selection dialog, fixes, more \b Added \R{asetallowskipfiles}{AllowSkipFiles}: Set whether the user should be able to skip a file when overwriting failed @@ -15,7 +19,19 @@ \b \W{../Contrib/Makensisw/Readme.txt}{MakeNSISW 2.0}: UI to define symbols, toolbar, more -\b NLF language files (v5): More strings translatable (K/M/G Byte, registering, unregistering), language specific fonts +\b NLF language files (v6): language specific fonts, RTL and more strings + +\b Full \R{rtl}{RTL} support (set in language file) + +\b Inner LangStrings can be used in the script + +\b No more /LANG, only LangStrings - easier to set one string to all languages + +\b LangStrings are no longer installer/uninstaller specific (no un.) + +\b No more unprocessed strings, variables can be used everywhere + +\b Added \R{ifsilent}{IfSilent} and \R{setsilent}{SetSilent} to allow better /S interaction \b /o Switch for \R{ssection}{Section} provides ability to unselect the section by default @@ -23,6 +39,10 @@ \b Added \R{ssectionsetsize}{SectionSetSize}, \R{ssectiongetsize}{SectionGetSize}, \R{ssetcurinsttype}{SetCurInstType}, \R{sgetcurinsttype}{GetCurInstType} +\b New parameter for DirText to set the browse dialog text + +\b Better ClearType support + \b System Plug-in: Fixed a bug with calling proc(void) and added e switch to get GetLastError return value \b Components Tree: Fixed problems with sub-sections with RO sections as children, SF_EXPAND now refreshes the components tree, Added SF_PSELECTED for partially selected sub-sections @@ -37,7 +57,7 @@ \b Added \R{rmdir}{RMDir /REBOOTOK}: Remove folders on reboot -\b Added \R{setbkcolor}{SetBkColor}: Background colors can be set for non-static controls, transparent background support +\b Added \R{setctlcolors}{SetCtlColors}: Sets background and text color for every dialog control \b \R{ainsttype}{InstType} /NOCUSTOM and /COMPONENTSONLYONCUSTOM work together @@ -47,9 +67,9 @@ \b Fixed a problem regarding borders in Plug-ins BgImage and InstallOptions -\b Fixed plug-ins directory init function generation +\b Minor bug fixes -\b Fixed overlapping chars in directory input +\b Code clean-ups and some more comments \\Notes:\\ diff --git a/Docs/src/langs.but b/Docs/src/langs.but index 28b2a342..f59fbc57 100644 --- a/Docs/src/langs.but +++ b/Docs/src/langs.but @@ -6,19 +6,17 @@ Loads a language file for the construction of a language table. All of the language files that come with NSIS are in \W{../Contrib/Language files}{Contrib\\Language Files} -For ease of use LoadLanguageFile defines $\{LANG_language_file\} as the language id. Use it with /LANG, LangString, LangStringUP, and LangDLL. +For ease of use LoadLanguageFile defines $\{LANG_language_file\} as the language id. Use it with \R{langstring}{LangString}, LangDLL and \R{viaddversionkey}{VIAddVersionKey}. -\S2{langstring} LangString and LangStringUP +\S2{langstring} LangString -\c [un.]name language_id string +\c name language_id string -Defines a multilingual string and spares the comparing of $LANGUAGE to every language you have in your installer for every string you use. This also allows you to make section names and install types multilingual. To use in the uninstaller make sure you name the string with the un. prefix before. +Defines a multilingual string. This means the its value will be different (or not, it's up to you) for every language. It allows you to easily make your installer multilingual without the need to add massive swithces to the script. -LangStrings can you only be used on their own. You can't include them in other strings. "look at my $(string)! isn't it beautiful?" will be seen exactly as written, $(string) will not be expanded. If you want to use LangStrings in other strings you can first copy the LangString to a variable and then use the variable wherever you want. This is a temporary situation, it will be changed before NSIS 2 final. +Each LangString has a name that identifies it and a value for each language used by the installer. To use a LangString you must know its name. LangStrings can be used in any runtime string in the script. To use a LangString all you need to add to the string is $(LangString_name_here) where you want the LangString to be inserted. -\\Note #1:\\ Unlike defines that use curly braces - \{\}, multilingual strings use parenthesis - (). - -\\Note #2:\\ If you see weird characters between letters in the string when you use LangString, use LangStringUP (LangString for unprocessed string such as InstType) +\\Note:\\ Unlike defines that use curly braces - \{\}, multilingual strings use parenthesis - (). For example, instead of: @@ -35,53 +33,42 @@ Use: \c LangString message ${LANG_FRENCH} "French message" \c LangString message ${LANG_KOREAN} "Korean message" \c -\c MessageBox MB_OK $(message) +\c MessageBox MB_OK "A translated message: $(message)" + +\S2{licenselangstring} LicenseLangString + +\c name lang_id license_path + +Does the same as \R{langstring}{LangString} only it loads the string from a text/RTF file and defines a special LangString that can be used only by \R{alicensedata}{LicenseData}. \S0{langs} Multiple Languages -As of version 2 NSIS fully supports multiple languages. An installer can have more than one language. Each string in the installer can be easily translated, and so can script strings such as messages in a message box. +As of version 2 NSIS fully supports multiple languages. An installer can have more than one language. Each string in the installer can be easily translated using \R{langstring}{LangStrings}. -Each installer has one or more language table which holds references to strings in the strings table. To create a language table all you need to do is use \R{loadlanguagefile}{LoadLanguageFile}, define strings used in your installer for that language such as Name and Caption, message box, install type, and other strings using \R{langstring}{LangString} or \R{langstring}{LangStringUP} and you have built your installer a language table. +Each installer has one or more language tables which hold references to strings in the strings table. To create a language table all you need to do is use that language. Either use \R{loadlanguagefile}{LoadLanguageFile} or define a \R{langstring}{LangString} and you have built your installer a language table. To make sure all of the inner strings NSIS uses are there you should load a language file using use \R{loadlanguagefile}{LoadLanguageFile}. The strings from the language file will be used as defaults in case you don't define some strings in the script. The language file strings can be used by the script too, not just internally by NSIS. Each string in the language file is assigned to a specific LangString. That LangString's name is listed as a comment just above the string in the English language file for your convenience. The language file is located in \W{../Contrib/Language files}{Contrib\\Language Files}. For an example of usage see \W{../Examples/languages.nsi}{languages.nsi}. \S1{langselection} Language Selection -When the installer starts up it goes through these stages to select the interface language: +When the installer starts up it goes through these steps to select the interface language: -\n Find a perfect match between the user default language (GetUserDefaultLangID()) +\n Get user's default language (GetUserDefaultLangID()) into \R{varconstant}{$LANGUAGE} + +\n Find a perfect match for the language id in \R{varconstant}{$LANGUAGE} \n If there is no perfect match, find a primary language match -\n If no match, take the first language defined in the script +\n If there is no no match, use the first language defined in the script -\n If \R{varconstant}{$LANGUAGE} has changed during .onInit, go through steps 1 to 3 with the language inside $LANGUAGE instead of the default user language. - -\S1{/lang} The /LANG Parameter - -All of the installer (and uninstaller) attributes setting commands have an optional parameter /LANG. This parameter tells the script compiler in which language table to put the specified string. - -For example: - -\c Caption /LANG=${LANG_ENGLISH} "English caption" -\c Caption /LANG=${LANG_FRENCH} "French caption" -\c Caption /LANG=${LANG_DUTCH} "Dutch caption" - -When the installer will select the English language the caption will be "English caption", when it selects French the caption will be "French caption" and when it selects Dutch the caption will be "Dutch caption". - -If no /LANG parameter is specified, the compiler will assume the last used language, or the last loaded language. - -\c LoadLanguageFile "${NSISDIR}\Language files\English.nlf" -\c Name "English name" -\c LoadLanguageFile "${NSISDIR}\Language files\German.nlf" -\c Name "German name" -\c Caption "German caption" -\c Caption /LANG=${LANG_ENGLISH} "English caption" -\c ComponentText "English components text" -\c ComponentText /LANG=${LANG_GERMAN} "German components text" +\n If \R{varconstant}{$LANGUAGE} has changed during .onInit, go through steps 2 to 4 again \S1{langdll} LangDLL Plug-in -The LangDLL plug-in lets you give the user the option to choose the language of the installer. Just push the language id ($\{LANG_*\}) and its name for every language in your installer, then the number of languages pushed, the caption, and the text that tells the user to select the language, call the plug-in function named LangDialog, pop the returned value into $LANGUAGE and you're good to go. If the user click on the cancel button the return value will be "cancel". +The LangDLL plug-in allows you to give the user an option to choose the language of the installer. Just push the language id ($\{LANG_*\}) and its name for every language in your installer, then the number of languages pushed, the caption, and the text that tells the user to select the language, call the plug-in function named LangDialog, pop the returned value into $LANGUAGE and you're good to go. If the user clicks on the cancel button the return value will be "cancel". -For an example of usage see \W{../Examples/languages.nsi}{languages.nsi}. \ No newline at end of file +For an example of usage see \W{../Examples/languages.nsi}{languages.nsi}. + +\S1{rtl} RTL Languages + +RTL languages are languages that are written from right to left. NSIS fully supports RTL languages. In the language file there is a place to specify if the language is RTL or not. If it is, NSIS will create another set of dialogs for the language that will be RTL. To find out on runtime if the language you're currently using is RTL or not check the value of the $(^RTL) language string. It will be 1 if the language is RTL and 0 otherwise. \ No newline at end of file diff --git a/Docs/src/pages.but b/Docs/src/pages.but index a6743868..ed7dd261 100644 --- a/Docs/src/pages.but +++ b/Docs/src/pages.but @@ -2,30 +2,74 @@ Each (non-silent) NSIS installer has a set of pages. Each page can be a NSIS built-in page or a custom page created by a user's function (with \W{../Contrib/InstallOptions/Readme.html}{InstallOptions} for example). +Using the script you can control the pages' order, appearance, and behavior. You can skip pages, paint them white, force the user to stay in a certain page until a certain condition is met, show a readme page, show custom designed pages for input and more. In this section, you will learn how to control all of the above. + +There are two basic commands regarding pages, \R{page}{Page} and \R{uninstpage}{UninstPage}. The first adds a page to the installer, the second adds a page to the uninstaller. On top of those two there is the \R{pageex}{PageEx} command which allows you to add a page to either one and with greater amount of options. \R{pageex}{PageEx} allows you to set options to the specific page you are adding instead of using the default that's set outside of \R{pageex}{PageEx}. + \S{pageoreder} Ordering -The page order is set simply by the order they are in the script. For example: +The page order is set simply by the order \R{page}{Page}, \R{uninstpage}{UninstPage} and \R{pageex}{PageEx} appear in the script. For example: \c Page license \c Page components \c Page directory \c Page instfiles +\c UninstPage uninstConfirm +\c UninstPage isntfiles -This code will show the license page, then the components selection page, then the directory selection page and then the install log, just like in old installers. +This code will tell NSIS to first show the license page, then the components selection page, then the directory selection page and finally the install log where sections are executed, just like in old installers. The uninstaller will first show the uninstall confirmation page and then the uninstallation log. -You can specify the same page type more than once, just make sure you know what you are doing. +You can specify the same page type more than once. -Please note that you must still use \R{alicensetext}{LicenseText} and \R{alicensedata}{LicenseData} for the license page to show, \R{acomponenttext}{ComponentText} for the components selection page to show and \R{adirtext}{DirText} for the directory page to show. +If you don't use any page command the installer's pages order will be just as in older versions: license (if \R{alicensetext}{LicenseText} and \R{alicensedata}{LicenseData} were specified), components (if \R{acomponenttext}{ComponentText} was specified and there is more than one visible section), directory (if \R{adirtext}{DirText} was specified) and instfiles. The uninstaller's pages order will be: uninstall confirmation page (if \R{auninstalltext}{UninstallText} was specified) and instfiles. -If you don't use any Page command the installer pages order will be just as in older version: license (if \R{alicensetext}{LicenseText} and \R{alicensedata}{LicenseData} were specified), components (if \R{acomponenttext}{ComponentText} was specified and there is more than one visible section), directory (if \R{adirtext}{DirText} was specified), instfiles. +\S{pageoptions} Page Options -\S{pagecallbacks} Callbacks +Each page has its unique set of data that defines how it will look and act. This section describes what data each type of page uses and how you can set it. \R{pagecallbacks_explain}{Callback functions} are described below and are not dealt with in this section. -Each built-in page has three callback functions. The pre-function, the show-creation function and the leave-function. The pre-function is called right before the page is created, the show-function is called right after it is created and before it is shown so you can tweak its user interface with \R{createfont}{CreateFont}, \R{setbkcolor}{SetBkColor } and \R{sendmessage}{SendMessage}; the leave-function is called right after the user has pressed the next button and before the page is left. +The list below lists what commands affect the certain page type. Unless mentioned otherwise, these commands can be used both in and out of a \R{pageex}{PageEx} block. If used inside a \R{pageex}{PageEx} block they will only affect the current page being set by \R{pageex}{PageEx}, else they will set the default for every other page. -A custom page has only two callback functions, one that creates it which is mandatory, and one leave-function that acts just like the leave-function for built-in pages. +\e{License page} -Use \R{abort}{Abort} from a built-in page's pre-function to skip the page, and from a built-in page's leave-function to stay in the page. +\b \R{alicensetext}{LicenseText} + +\b \R{alicensedata}{LicenseData} + +\b \R{alicenseforceselection}{LicenseForceSelection} + +\e{Components selection page} + +\b \R{acomponenttext}{ComponentText} + +\e{Directory selection page} + +\b \R{adirtext}{DirText} + +\b \R{adirvar}{DirVar} - can only be used in \R{pageex}{PageEx} + +\e{Un/Installation log page} + +\b \R{adetailsbuttontext}{DetailsButtonText} + +\b \R{acompletedtext}{CompletedText} + +\e{Uninstall confirmation page} + +\b \R{adirvar}{DirVar} - can only be used in \R{pageex}{PageEx} + +\b \R{auninstalltext}{UninstallText} + +\S{pagecallbacks_explain} Callbacks + +Each built-in page has three callback functions. The pre-function, the show-creation function and the leave-function. The pre-function is called right before the page is created, the show-function is called right after it is created and before it is shown and the leave-function is called right after the user has pressed the next button and before the page is left. + +\b The pre-function allows you to skip the page using \R{abort}{Abort}. + +\b The show-function allows you to tweak the page's user interface with \R{createfont}{CreateFont}, \R{setctlcolors}{SetCtlColors}, \R{sendmessage}{SendMessage} and others. + +\b The leave-function allows you to force the user to stay on the current page using \R{abort}{Abort}. + +A custom page only has two callback functions, one that creates it which is mandatory, and one leave-function that acts just like the leave-function for built-in pages. Examples: @@ -59,12 +103,44 @@ Examples: \S{page} Page -\c ((custom [creator_function] [leave_function] [caption]) | ((license|components|directory|instfiles) [pre_function] [show_function] [leave_function])) [define_if_last] +\c custom [creator_function] [leave_function] [caption] +\c OR +\c (license|components|directory|instfiles|uninstConfirm) [pre_function] [show_function] [leave_function] -Adds an installer page. See the above sections for more information about built-in versus custom pages and about callback functions. If define_if_last is specified, the parameter will be !defined if the page turns out to be the last page before a instfiles page. This helps you decide on dynamic scripts (such as the \W{../contrib/Modern UI/Readme.html}{Modern UI script}) what to put in this page's text, "click the install button to start installation" or "click next to continue" for example. +Adds an installer page. See the above sections for more information about built-in versus custom pages and about callback functions. \S{uninstpage} UninstPage -\c ((custom [creator_function] [leave_function] [caption]) | ((uninstConfirm|instfiles) [pre_function] [show_function] [leave_function])) [define_if_last] +\c custom [creator_function] [leave_function] [caption] +\c OR +\c (license|components|directory|instfiles|uninstConfirm) [pre_function] [show_function] [leave_function] -Adds an uninstaller page. See the above sections for more information about built-in versus custom pages and about callback functions. See Page for an explanation about define_if_last. \ No newline at end of file +Adds an uninstaller page. See the above sections for more information about built-in versus custom pages and about callback functions. + +\S{pageex} PageEx + +\c [un.](custom|uninstConfirm|license|components|directory|instfiles) + +Adds an installer page or an uninstaller page if the un. prefix was used. Every PageEx must have a matching \R{pageexend}{PageExEnd}. In a PageEx block you can set options that are specific to this page and will not be used for other pages. Options that are not set will revert to what was set outside the PageEx block or the default if nothing was set. To set the callback functions for a page set with PageEx use \R{pagecallbacks}{PageCallbacks}. See the above sections for more information about built-in versus custom pages. + +Example usage: + +\c PageEx license +\c LicenseText "Readme" +\c LicenseData readme.rtf +\c PageExEnd +\c +\c PageEx license +\c LicenseData license.txt +\c LicenseForceSelection checkbox +\c PageExEnd + +\S{pageexend} PageExEnd + +Ends a PageEx block. + +\S{pagecallbacks} PageCallbacks + +\c ([creator_function] [leave_function]) | ([pre_function] [show_function] [leave_function]) + +Sets the callback functions for a page defined using \R{pageex}{PageEx}. Can only be used inside a \R{pageex}{PageEx} block. See the above sections for more information about callback functions. \ No newline at end of file diff --git a/Docs/src/tutorial.but b/Docs/src/tutorial.but index 1e3ede41..75c7bfda 100644 --- a/Docs/src/tutorial.but +++ b/Docs/src/tutorial.but @@ -27,16 +27,27 @@ The default extension for a script file is .nsi. Header files have the .nsh exte \H{tutstructure} Scripting structure -A NSIS script can contain Installer Attributes and Sections/Functions. You can also use Compiler Commands for compile-time operations. The minimum is \R{aoutfile}{OutFile}, which tells NSIS where to write the installer, and one section. +A NSIS script can contain Installer Attributes and Sections/Functions. You can also use Compiler Commands for compile-time operations. Required is the \R{aoutfile}{OutFile} instruction, which tells NSIS where to write the installer, and one section. \S1{installerattributes} Installer Attributes -Installer Attributes determine the behavior and the look and feel of your installer. With these attributes you can define what pages are shown in which order, texts that will be shown during the installation, the number of installation types etc. Most of these commands can only be set and are not changeable during runtime. +Installer Attributes determine the behavior and the look and feel of your installer. With these attributes you can change texts that will be shown during the installation, the number of installation types etc. Most of these commands can only be set and are not changeable during runtime. -The most basic attributes are \R{aname}{Name}, \R{ainstalldir}{InstallDir} and \R{adirtext}{DirText}. +Other basic instructions are \R{aname}{Name} and \R{ainstalldir}{InstallDir}. For more information about installer attributes, have a look at \R{instattribs}{Installer Attributes}. +\S1{tut-pages} Pages + +An non-silent installer has a set of wizard pages to let the user configure the installer. You can set which pages to display using the \R{page}{Page} command (or \R{pageex}{PageEx} for more advanced settings). A typical set of pages looks like this: + +\c Page license +\c Page components +\c Page directory +\c Page instfiles +\c UninstPage uninstConfirm +\c UninstPage isntfiles + \S1{tut-sections} Sections In a common installer there are several things the user can install. For example in the NSIS distribution installer you can choose to install the source code, additional plug-ins, examples and more. Each of these components has its own piece of code. If the user selects to install this component, then the installer will execute that code. In the script, that code is in sections. Each visible section is a component for the user to choose from. We will not discuss invisible sections in this tutorial. It is possible to build your installer with only one section, but if you want to use the components page and let the user choose what to install you'll have to use more than one section. @@ -119,7 +130,7 @@ After calling the function, the variables contain the same value as before. Note \S2{tutdebug} Debugging Scripts -The more you work with NSIS the more complex the scripts will become. This will increase the potential of mistakes, especially when dealing with lots of variables. There are a few possibilities to help you debuging the code. To display the contents of variables you should use \R{messagebox}{MessageBoxes} or \R{detailprint}{DetailPrint}. To get a brief overview about all variables you should use the plugin \W{http://nsis.sourceforge.net/archive/viewpage.php?pageid=140}{Dumpstate}. By default all actions of the Installer are printed out in the Log Window. You can access the log if you right-click in the Log Window and select "Copy Details To Clipboard". There is also a way to write it directly to a file. See \R{dumplogtofile}{here}. Very useful if you force to close the installer automatically using \R{setautoclose}{SetAutoClose}. +The more you work with NSIS the more complex the scripts will become. This will increase the potential of mistakes, especially when dealing with lots of variables. There are a few possibilities to help you debuging the code. To display the contents of variables you should use \R{messagebox}{MessageBoxes} or \R{detailprint}{DetailPrint}. To get a brief overview about all variables you should use the plugin \W{http://nsis.sourceforge.net/archive/viewpage.php?pageid=140}{Dumpstate}. By default all actions of the Installer are printed out in the Log Window. You can access the log if you right-click in the Log Window and select "Copy Details To Clipboard". There is also a way to write it directly to a file, see \R{dumplogtofile}{here}. \S1{compilercommands} Compiler Commands diff --git a/Docs/src/ui.but b/Docs/src/ui.but index fd0cfe86..d5a5c049 100644 --- a/Docs/src/ui.but +++ b/Docs/src/ui.but @@ -86,11 +86,19 @@ Shows or hides the details, depending on which parameter you pass. Overrides the Sets mode at which commands print their status. None has commands be quiet, listonly has status text only added to the listbox, textonly has status text only printed to the status bar, and both enables both (the default). For extracting many small files, textonly is recommended (especially on win9x with smooth scrolling enabled). -\S2{setbkcolor} SetBkColor +\S2{setctlcolors} SetCtlColors -\c hwnd color +\c hwnd (branding | (text_color (transparent|bg_color))) -Sets a background color for a static control, edit control, button or a dialog. Use GetDlgItem to get the handle (HWND) of the control. To make the control transparent specify "transparent" as the color value. \e{Do not} use this on branding image controls! +Sets a background color and the text color for a static control, edit control, button or a dialog. Use GetDlgItem to get the handle (HWND) of the control. To make the control transparent specify "transparent" as the background color value. You can also specify branding instead of text color and background color to make the control completely gray. This is used by the branding text control in the MUI. + +\S2{setsilent} SetSilent + +\c silent | normal + +Sets the installer to silent mode or normal mode. See \R{asilentinstall}{SilentInstall} for more information about silent installations. Can only be used in \R{oninit}{.onInit}. + +Sets the installer \S2{showwindow} ShowWindow diff --git a/Plugins/InstallOptions.dll b/Plugins/InstallOptions.dll index b1f51a1a6bd44275a573d2f1a6fe67948529886b..5b0f6cb628554ea5ab511b6d21d9b629e2009cba 100644 GIT binary patch delta 7842 zcmd^Edw3hwmA|rOS&n5(2^LWjJCTX9G1vjgdd=uziK1XbO{?Hn3;|La=%54|U>pK9 zk%DYMOdJvh_`;U%#<;M2TNcuW1qy-6dE%A^Z<8kB(KcP6$Z=pz0mpF@W`AcSxenca z-|pW#{?44oz31F>?>+b2Gjd{0V$GI-W_W9GY5cnvbo^)8?SBQs?Plim$%qy8`L3uRYPFj5TYD*p?074CR}Sv-0XvjgGNONE))zMYX^t zz}C}^C1EdPYe84aS7;U%Xtnaz0%wsOyk=|lTsf`LYmUf6n#GzO@@IH&l;;$DTl3=1 zTM8c5JffZJY_&7f9!0ci6>~Gla5OWlC`uR%UXhdwXuwY>(H^`N~{40 zr_!f2Cf8RKcQ1)C{FN(fp+f%B8XeG8Yr5qTUFB?YSTQp!MOIG{%hB(QTv=RGNd^x@ zY?YV^OGRu}<7QuhN>yMQD~sotPm;Oi0pY{Tm`ON%Gb|lN%jRMZ6FgAt*G$NTdhf#H zXl+-_VRXjESpXG63N~Amqr_8_e4V~-F*$eY*u320 z32R}yEps1EK#QOcW6qTojCFQqgDn*)M<~H!vRhZdj6FBNWM4$*Y7r9XN+Fl|QhRt+O7)hoJq8Tfc$y=I#3-k=?csPKDZ2nPMsaa=0R9W_G_1#&= zq~>x%VwFb2vRfEqLMx4-9G#kY-Be5S^cEqI^Q9)!4PU0ZudruFisWY0HO)~8q_&le=0kN+!V4&1XIAlrxc2V^DD#LIE5knteox*CTyAV z^UOESoq=_##qu?s%BdF9^cF!+9BkS$H=Ln$Huh{mjJ2rAeYPp6EMV+TgFyKLGRhZ; zU|Rk`S#|jth!iuYP73b+YuS9wW_hS=v7MY2a159*M!_*{eVec$xtvzC1Nj=mhM{UL z_jFRkNeHv#@tRblE3^AcMM)K_%i9UDHPvWMrawzHTJkGyOEuc^bY-fsQfjp1c3C~O z$xI=PTNR{~7s_W}Oee&+=`u`EJxe!Sf8Djoy%l?s-8K{Jx*lmopILzsSErjPuH-Mu z7tXk5oYIOdnu*HQ#@WRjEGXtRa>%&gyT8WXDP0vEN|%9d9JgI<`w%O^cNwH(T}yl4 z>$)_ltQX6ZxJk-0v(UdMEnW<+OQ#eKBPpYmNZT4%EqV(AHJh3gcQ*HDm4`t+ytSru0rX8(-ug_ zFSlq#gR)MqN-DDwjaaI9Q~@K!%S|J8s7XsrgBerQ__DmjG{bW@PGoYgX~ak^T@@`I z$~tXk_;U*0V;B`fsG}mT%cFglS4Nd}$j*o5TTOG~w53?lzKGtE6(7SWtKVx@w@ncX zo7BEEv?@vNuM}(uioWhb%hPzWyL)d%;hw%G%QD=_cI7VEem~zoc79)^(3)i0+`c!~ zq#~u+m?+#MHQD5%nP%N_wYO}YIp0X`z>2F-xt+|&SIw-{?380OYrd0nv~V!S=tf=} zR@}7R866Hg=8mOZJ)ZSCzvZGXqL^vJ5lJXCl1fR}JJ>-i_9h4yu>`VotR`y)H@y7$ z%gMXi~=P57}BWfF{WLoRrH$W%P*z+KG6i>#UIEc(u2tGR1@jJk^2?-c# z%RBZQ{E*zw(z}eVESRvsyr|!Jnr=3+d|9sN5moNrM;>j49ZK5dQ7vf9=f|)B-8bR6 zSO)84L@{rNG**ze5RYjF0vIFD#|j6+(^#qMN$Rdq+$0@{P}3pFO?BQc7-FwOn23=w znHWgl1oBA#a?t*LVp%jR&Q@O?f}KWJ&7jYUe4ltuq?TwM!kc8mtqyafpDy^EAyuOG z>8A_(4Z6<#`^6HBk@cyc?rccT%a3}9>Z9;LB}VP1yBlqDNR&K|x>5C4U5dDA;0w$^ zs-lvrtu5xrEySTVVQ?P#LfbD*q`Ga(V>c=8CUA;*8~S2lDJd9xo<>RE7qQu4HM_u% zqE&Kl!8<1=6Uq@V9QtG#6l4KpU9L9XY;)B@J65qQii8)&eX3$?7nxVgbW~!Rj+i|s zIFxVDq7cO<>uI#H4wQ!4?1<~5psgg0*w({b69$e(V=lpt&_I(Z+Z2t>eWLT!>3Dni ziQ3)&F+m+s@1reWx(rycbjHos6)}c%kv+|YgHlsP^0X$^jIw4^Et-<2%Zv|P074q+ zYyLMj_{V}|a4j51luAFfT?#K!b$E{&q@P+LTB{!V&1kJuTWx=*)kZfRnT7p2X;3of^U7|i)yByu%#nEB<+)O~ zEevT*ZMV&eEw3TIb`q3TG9}LzrCMzk)Gf7<6)Nuqs0$e$>%}6s?3;ve9)973)uLe737~3 ztecD7v8@44t(5@1$-b!pa$gpC5kYZ2uJ+}=* z&8f)Dc;MWvlkhD`x8)XmLLv2twrI@Wt{kGWpjb3ve@w~A;tlo5$&w9aqqS(aAjuoh zLp76)RKyT`6!mq&KCBwrvT8-fp4qUPoYWb6%0Z|a@hKHrL__b8u_vgZPBXgZ;-jwO zGBCiFW8#JM>1<1cy1V8i z7Bm0Ex*1V&(N-CUdySBblhOfT)^)TkQw~+txz4H6K+b8&IVvs2!)~3}y|LS7p&`5O zh$*l4f{3xUzgY*VTd$Q4z^<_;j4lru6Q{c$Y_=`vDuf#}T>K(9Gdmhn1hNJFX5@?2Y9vHPwxgSK2)f3{25~4VBz^CY_$?{yie>L_Y53H; z^M14ND5dhN7w)6stjn;B=EQW1QwE!+MV9=#IrHM=o^S`IIhxHiQ(G@Z^x6dH=rSOd zG{R?aBfpSgd;!B?HXm*pz;|sj*s7+u8iAoQ62@@B<`TR5wXL|RIWHN5V`_OI=~HF# zX0%9psU(F0l@dIX^9uD79;y5!dV*gS&ES_Hh7!k_9$nOyxfKj$?Xjxn4`Yg-9 zW{jYn>CP}!&Kvh`2e&5~q*8>5eE$SKH`|kGeKdxX=Ynm;Jy8RhG=@bm^j%KB3oV~= zj-_;}mnr-8dqBwZ=FOiOooX#_hr{Mp`O0~7<2>#~WaivW=6r9!j(N0Xrz4bMLGm-F zD^*&e)*HFmD!iilWajF&Y%RQ7CNYAXosfNG0Ks1 zYL#71{ZvqVtno~n|GbcX6>ZqI2DHgx7gCceoUqz+!E6;-IDtcwRJX~e*jA4b?0PQA<6#W22 zDhSg6g)RugKphCtAiP3Bz6;-noqIAnKbPmvx5WQXs<)}C2Z~4uXP%8*i%%pPG8xR; z`JYGb%8h)9s;-n#-;n_@Qe=)zi+f04I6#%4SWGm-_a;JBJ~)4|hLgwVZ;QX{X3Xbd z>`K5&fC-=lOhA4DPy?EtRZhm%1DXLl>Tyd0+W;28B=`>j#{h2u-T>SOIXy?9|0&r- zo|p@GGiUE17i0hEVsZ8ih!+9-0o{P(fIkBYFt~*r0C)gRfOf#m01?mw*amnG@G9Uo z=-dd10wMqxpax(8=m6tz=mg+N!1I7KVAvUF?0pc&(1D&u;N3ldXL4Tda%AQ7-i&@V zcE${tUH&Q*GfVbuFCSVk_ECGy9Y9;~~0SmzRu3{^J zQKqrwz~oFbumLy%Tn3zfT;TB+XEq{Wu>zPBwZvN)qhI96F>)vjOb##*V~{g+JWd#Q z*Dzri*aZxh?I1qE*t5WBU{3;*!&`u@zzN_4un5dFi2OA~V8m4_4zuMdHnC+Ded@1yo%Pc!KOhvch{Ge1LD`zrzdsZTyxv|2Y36{$>6{{!{)G zU*tQ_SMR&hx6*f~FYbHT_n7Y~->bfTzK?x%{(Aq7e!;)h|D^vZ|MUJA{b&5M0=9rV za91D|7zn%=*cBKG91MIAI34&ZP!^mM^acaLYlF806TugPyMwN@u9l9`7AL2rnh8jcP z4t0c9gjR*VALI zU*KQof5pGUf6V`dXTF)fxxPidB|f*$=eyK*4PxXL-yOam`0n#P>wDh!vM=o$@(ufb z=Nt2l`xKwvZ}eCCFY!0{BmVFC8I!j-qn3zcxnqqZ;ds>XtYepB*zuub!eOYl*6-A~ H&S?G{R@2B@ delta 7663 zcmd^Ee|%KcmA{jjOeQeN449Dw5*c9B$S-G{U++!kS9OrIjdpM#A&Qi?sINn8p?!ns zMrPe7>Hm|0r}OHZLJ@6`_iN|RS1D)^Y(k*Ok(t7 z|Jc8G@;UFGbM86ko_p`P=brbHYDu+p`Zb5P1r{y2Z+6p%lh=I$lh$1e`ov!v*R4RS z?eVQ^MB90;Ol^0*VN%<>zWEJ-bXegRUBp;}rkJ&zx_R6CHATDUZo6`4snyHaS_o8T zmuTh`jcBvmik!uE(3)+trk5@h@7o}vcXjrd=0;6t_A;K9?5v`%XkOU8uILAvZFa+U z-E?Qv&dj}vXwxZ{dZ6K`d{j}CX5vH@O9S;v7W0G5?98k=x){+vXAO! z7aeKIcIj;Mh9H*O$gz$^uS7+IVlg|Ic|fmN3~1YPi5h9q(Gg->Or;+!1y-l+!J5PVZ%oVB+qPdH7nxF!|233U%P-w}n)i0P!>(I3EOIQOSPNhR< zN^htrX#L`c!;0lO#zU^AwiCYrjk_ZsHkNX}h4Gb4BDOjHn6ozv+9#{PX6ec}|dFBxu8_e5&2 zRdndQsZ~X+FRYo3kuMq6+$3W{jY7+~N0u;+i&+4y>4>eOK>|`&Y|cuh*6T?+b^Y>1 z%*+I4WlSJcs8AO|b+uBlaM`1!l}YN57hb_m4iq_aZx~p5up+jsvFWwV5oo0FXq5X9 zoI(qs-GeYJze@B9l^!Dc1)>{N`U25UfL7e(gA}mAP3K>`M?fqS!X$&`QTw`SACkfq zE!^WKcI-tID&0o(#)SD3JG!sJN=&H!6pyKL<~*-k2daw<*B#tA^_#gTvB*)`aT(L= zR>LR9FQDE`i_L7>+OK6v<{aL?V+}L!rG*Gb)jeN^sF<&)VSt?y46waSege@R6AWR@ z@3m_fYi`a5WF}IMuz|^RtG6XaAsWIo*yZqx3}lSlBm3GD%K%y zLyh8?Z~&UZKGm3oLu5fNn5HS*b!mM5G=+RZ!4!}LD4pUEy>6VIq>zN4uT1m?(v{hYeP6MKZ`h=NU<9J@;EY-;O7493(%Kg}FaW-|6&qd>U>JjxxZ z!1C<3%Vw4D086pVS0@E`pDDWzsce7QjdpTcz>#3W=7}R=jCyPcD=Eliz~-g+?H8v8^fzJi>sx@m4#ha zPjFh+!njo_ro)4bV@~&}`KEv(?SOCEG6z#uPv6Y1uDti2^nr@rbgRwG5-X7q4RRDt ztjRS{m}cejImtVRDeKsxas(X%7t>eD64T<7C?_gwb$GasV&;lPz>+v~y|{^DjjtIn z%_cr!lpZxFCZ!ckqFC<1)+>pMCM98{%gcR8)%pNhBzGpUsQvxK7t+cGu{@1Ssa)1W zzAYy%OoB}4m0|%29^HiQLn2U$SA(HuX0zhX-y`Q>?5k4m%6sn3Uy0HpV`F+`o)`~I zLBba!fm_g+9(w@KfCrEDlLH)a+Lz%OAAom?*T+FOmTe%Hr5wxAmq!V9k*9UmGwyCN1;D_yV)%2hi^A( z67DSscc}%btZ~LXuGt^ zI#SQZr&Mc>W*?tY`!(u;huR+6aKExPoZoTzX5<7c1XgX$aNgaqy%qHl#X>ua@WM`{ zmD0rTu~S$_5zOmZ3fVqhI~F(>vgWC?l3UP&HTz*yu^a;G%!LP@-!%9%9ZKi>d=14I zuDeVPg+Zo`k4m8ka)<1Hij-=&0*8wcP)(^RI5oL7xlQp1XLIn)P#vI!PKP2}~dX~{O2NN&BylB{TnQlX|d`Us_l*+H` zC69R6fk#)7*!xeFV4{lU=db|XRq$LagLN{ZSe^qnUNmMQ8P{~5pc9clO{e18?lTie zX~EMZu2I~??LJFgCnY!4hOaXOVw2DrCuK6xz5G6)r@H9Quj>`dqIq_{Vrvo((deof z$WR@i$|MUcwXACrR*?y}I?SmqDhdjQRE{dsMVI_*R07oXiKQ4L?^74u^Wa=FHtI>L zslwf_VAL+U_0d;Ftn>${HC2DrrAV5)w_pa+0xH8|vACnK5GP~8+cU@)3IJ&&(`s89 zzfW<007|hu30W*G9ez_=R8Kd$%?_*i1>S*P$=!)(fvx7LQy@6Vue`h8i9ltfP^Jnovqs=SLHxz>UO>*hF065e(W8 zjk|;cYW-s|=eru>)1PX-bh$D7)V$;y$3{p{u~eYXnd56HRd?^fvYECTiy6ZS%%5QG zA!%JjdQ@ZD@&}}W^k|vs@smKLnx!f_v~=U*^ynn9Ha$Ao)c!J9QoU>Vpib0pdY9n{4IeBrwf%%7-!=4S z^WB^N#KJhcZ>M_t%O_u!>UEh0n|a`2De4-2BP?pu?^@fAKTP^o==W(vi;`Tc+w|@M zXv=rQCT=u!=7;my>bDGKx3&l4w!ftgYi0~Jt(CR^PAr=I-c~W7%AatKEi;1B$TNOd+HCkF`Z;tU26}iA?c-dOM_6gTGxd zwYB0!3CTiC+8W~aCgo&$v_vf3xR6%8Y~V&1q>Iyt4pn{p5`uf8VZLw>3#KX+o7&8< zM7!2j0_4-uv~A5NOuMA#kIK$=rnI(`!gHGy$VN;tABHu4h zU2fgnV4IfE!VMa4E_|65jVl6~qE#AEPy@#`WGdBao5n=_C;lZlme}9_5!RD#X1s0Y z6-;e^1S^iaL9|)>j{;ARYDHIiv`D;}4s?4CETOpuS?4NV&D%bA>m&U?hLrO#R82qZ zk^U|j+7F9&NMTnzf5S>gFa5h`#_>7tQMSEn4o-ixaS7JYlKNb8^%Ei~+c14bvQhXB zW;l?~7ULlzMGU$W=SUb4KpNri@L+5S!};nmpR%@Gz^iIHFo?KjVy(cCpoGo1{|b3m zeSuco)IG)-gjeeAEg3Rp=UQ0OEE%NI3<^c{a71j&)wgnFTN#qbr>mkezVR?rAkN&t z^)dND5V&}EA;S)o#pIQFatBD+1l*Zx4pX(e=>XLfz3Bi|3QXj?I?*?AHx|RpD`Rje2Oe-- zKlw}QG`=OxD=_G8%Py;)og@|UMLu6H70Z+9ppYB5%_m1cajsy(@(OJ7HB>%GHB@hi zsPYS*yeGM7hbEL6%BfG45}zs=UZ=W%40L}w+$RjTo?1?VMz6aRu!Z)X9fb0Ui2Dl$^ z2Jjca6@VE|SOE(GVZfb$m4FsNE1(nbbHK}hyCGi>@B`)ptN=4$6waInd~5TYf&A4^7O122Ut)Pr6M zSOxg-Can5g#x?*R2Au*(*+*|oBgC!SYYoZO_*z8D^vx0Pi!54b>(NdI?MFKat-a9N z(4v@Sm1s-R8qwnYfHAaq1!5!kHilY_4WT86&Y?A;J&U#s?bz=KX#6GFK0;t|7g|z$ znrJH`5-mAK4u#Q@0}RM!>WAP4YUyI976z801c?|Yx{KI`4> z-RC{zecSst?`5x+GjP+nn>ahibGLC{;$qx#PTh{nG<81HnK;;2VMMf#(Bz0*3>C2n+^33RDDV2Ax5F@Ydjx;61^If=>mL z&jnuy?h3vf{7vw!;IZI`!Slh3!O@^DWDHqCGeWk|+|Vr{Unmq>9J(vCJalhpb?Don zMChMFn?jpI+0av=XG712c7^^ev_JGl=y>S&p>v_3&_z0PR-7aRXNkScKGj}npKYIO zx7&mEi2cj<751;&1^ajHDf{zD`@h;>wZCRRVE>){r2S9!i}tJbX^xo=o5SgdI_`6< zaXjKkJDzlOIbLe`#twr_n`Y@x5iWAv3cfs>>j`8i=MA|mU-^+B){f)z|-Op zJtzHBKYaGmchS_Y)v*xc9 zA(miT0dZD|wL^)HV=Ws!FY{_78Ds@FQR7BXv%;w(Ow zR-@;rVAiuXwKK%I#0Y1V%x8fnI85mY5^+0{Kgxt$g~p+*t&F?Vw$So(tKqU0e0yn7 zU=RGJS<`7G85{$Tw5*55_28H%H0lXn)AIB{1bizM5*=+1I@&{1BzmoiMD1imFQU7l z-k=Re?PcVWdK1L%(K2`{*e|L7rs@D4s;SeziN?XSC+o;0-@3ubMOB?5b4s3;QC zCI~hIolWovhedfntO9~+W}=zqG+~-=5o{(l&G8|xqTOev!x5d0X|K;IPUlB4lcOGq z0Nqv;b!po*M4Wj*!3j6eo5rZS7?|oQ_%jIn+;MBMbCkDluSD%ycx@-Qkkc zdbPtdys@(KX5oL)sl;i^#(P!;*25g#h?&9`51^IM3T#0?6{6Pu4tOh}=Jb5&zNLE@ zD_cfKV(v#UrLmsighHYY5{2&sE!CVaO{#~e&3JBhVJr;M>HwUfN;jD}=?k+;F`2YN z1Jg$l2h;sDPO8NNG!pgGUnpx776r;mALE0v(g#JWGRuTrai*7dQX#QvO%J8I;xIW+ zXhLHXgVsARv64YOH03$x39*$k+c2x4ZD_214*GzQ#DKMOUk;52$2(UG&X=6igHxVC z;Ng&H(Pj}N@c{KfdVqd{A_bZq-m$brHG|WNlh&@n=QcjR9u8lHWr>fMgH&6qA>-rh zV&;-Dk-deh0 z)Rw2te`q|fKz}W zz;!?bFa>awAhZDR7@!nT0r&|(13U}ZUxMn;YaqM{I0d)>7zI2H!4-f~z%2m1?Drl@ z<;Q`8?wnnUiFT7C%kvP8QdeB zi+h|~!L8=ja3Ss~F3f4%uefKp822KVnj!rbHWl2rt4M zUW;pRJ&xiR@P2#{zm9wH+xSoT1AG?$9e;{H!(ZUr_-p(vwo7xQJjo?3ktFGd(po7b zg{5XGrc19%?@7bbb?FP~OX+LrTgfVC%WfIV8{{YDT6v3HFE_{$`B}L|Zj*l_za+mZ zACY_I_vC*0jC@i4hs^jM@kzciU(mO~x5>BJ_cLFc?-kz>-!b1uzAt^>`K*4AU-bL^ mtNiQzKlShOH~W9@Kkh%{ANIrX7_ARC_ci5qFvdHU_5T5-ej=Oz delta 2331 zcmd5;jZYL;5Py4c2MEYYI6_4P3VzVTdi(MAmg@Ocu1d=30R_aGSR?9sT4@Z|8nxaj zV#Spf`jVLrRwzV3pq*2S!YSmONtqNlOpbfDg7-=P74efT`o`)v=2fE3RdGmWS z^JeDF?%|VtV$J4hrq1h;O5-!EXzT;MC)A zQxh^=4uo3VWWOyw?!uVO2BG#vy= zDFy3dt+mqci8^mw3un+IdJ2_=R&pxz?eXQBrUjf)%$88tD^xmOp^0Qd1P#+XH1j89 zt}%X0HZaA?lUT$SxR+|!2hlb23?NlJmH3S584a-I4lU4Hv+U(?P+d5bKSHu5>}ainKPD)>fq9&S|v94Y1k$JB0e0##=U}Ii|85 z7R_DkvPyqU{IP)LCzh#lQ=MV2jU#2Z5$5R*1Z>8RO|yAK`SnHb6yS8 z8PHm*9Bj3t!xe0NIgOU|4*U(Uy3y5YM;BNG)~ch|9cOWLx>QG(g?f5AHBU#eYF`CT znkQUqQ@Y_Wy3)r;=>e^-gVr@n-4Bs~^V60ObG_6|FMpV##ng?pI=d_v zEY6NRH*&cl6TQeb)iD$ZuIm;4Flc+=nga&~u3c}wW5~@~9R1JQ3vVn9q?^z{3somI z@Y(%v$J45_86yPq18Kw;OUDQ=iq)kquCaRr&7|Ijf z;Xz)Z^ixHDc@zVDp}O+m))klsUl;vimXs8bjZrB^eJaU;s6`AST2y8{d_7?dhct6I zER=AFRHT{5keSh=86Q~~UCvA-KSfU_#|&S3|4c*Z4xj}0^;qEGy+E1Iac8L?aD9N_V<5LjCjK9)8ug#58urB0F_CAO+_J@` zIZMh`&m=2G-OdR9M$Up?K?bS_LI!;*U z5cnJ$6UKSJu%56sTQ6B}SnpbUtOhQEi|5j~3~n-qx!1T{E}wgoTg)xzR&yS16Ssrg z#qHzjxf5IycZ=)c{^0)NG|tGsz$f$L`7A!4pU*Gh*YNB35BO?+KYxh-j6cW!z<2Wx z`Ak6&a)fz8iLgjmE|du#VXLsiE9?_KW|BVR#fCjZ?9VXX7Hg6qn=mcpLr*@5lAH37^M5 z;%oRO?!@;olEzC`Ns?wsxl+DVCi$ej(gCSnT5v=BaDl(tsH0eIF5%sDl>}dRH=1#U3J%m1I%t6>z)@MYLN~^i2L?)Us{hd z^Y7-I@BQBIk9+U;-tYH*zxSo9u`6(>D^T;Zf4bT}{$BqiY{@*=zX$Xs;74`-yZu{% z4}28U=||H?`X2%PX!>yfULC)n84?lev*I%fchMF<D_{3j8AI=+NW|o>#75ivPbCm`vo}_(D18f z6GyyS3HE3k)Pzd2qJSOHN(va`SYzTu-u%0nEg{*UmEg2&bZB$yAfIdC$fqEJ$dE6?0$Fu{ zhS>y@%PnJ3buOQjIz~+3GBNk}Nw4f1SO1hXLN!b470unD2*vK}!sC)=5FY59B55Y> z;NwuIK4tMB*L@xH`?>BiObf*6DAtTyMiHYoa@`G3m6TOnH;;}VDpPgF6t3GG)q7^H z`zjXqbFmqqBev9KP}Dar_Y~vyr)*%lFH_&>X+p%AZT*Oi$>^kG@=+Uf^_?+E%l0^Ex4aolvoki@iajEL1K|+!0N@(439Q)KM6~ z1nM``cd^bl%5^^t4kDIa8wixg5Lt9A-t!`isVfZ&#q>j3HA#x!%7>YN_AuLCwg}Tg z%5FHCj!DNE=g(o)E4^=&du&lqYIVe{=0+^4F;cOSA8x2ypW$L}VYw;#@YG3k`J`7J zz1ot2H3$U$yyisJ)e;RVzd_W}bW97&r`S1h-9Ct<;{o(ZP&tNpmyWMsgxu2z1WV)|KRR+xEn4cy z9(O=#!#r_wFD2pB6IkQwM>p!`%j+|#wXhNK9B=q9{=AfK;(BYq;9l=KIwudOSs7b3 zCsAlCixz?_?Z^;m#~9IkZ&>!>5HoUbIWyij9``q3B0edb9Tjr# z&0xyCRcK@9x$aK3X2%#2=R$E{Bq#BnZGIG3e!hySXuh$OTerrWS`X7BMzttnQu8A@ z@TM8w%-xu(247!1&fI@?wRGJY?vSLx{M5cl$zEL&UY**>wvXkw*cZ&H>(k2Te`bR) zJ{V9Mp%%V7kgr^09(lJQpy@bL0z>RD)K7ieO=d<2>D&tmWx}_6Q?18c)My>ic^MsBk(&>OR}8h;wq+D4>oQe(NoQ++jsGi zVuTnj6^k(xmMF2MI9N-47r;!J(ZvY3pQO?_ZroYTH+ldUnk7E{UUtNOR zau17BwF4Ko%R|Jeli~CZ6S@c0jkuB(xODD8xrfE4I2DZYNd~(=!b)0S3P$`WyZ1ru zb*84Bi6ygBi}TvrAPs6I#X9sqnoXAyho;YrR@^C$qUzs;=ZhsspJQ6`rb=^@G}sUt_#A3y zrF|JqG*ezR(#y)FZ{bCSu1@pX;vug4U*S09l6SJ`Wrl?Peqozmn1$^9JJ1^6#wvXi zDm@Sj)R(~3-xa20AhK!VfkM-htY)o7E4dZAI)fj+>#jgkp!u%5w30<&!r3gd@tV3- zmp3;a4n=XG5E~ut}c32%Nh5O0?p% zHwiHiWy3efkn)RhC0DaPJb+f0$t7%t3A1PFnpe75)v}3&Sre(g zffijv53oYVe~= zfeNf47SKX(VwwGh+?(O9zMB(`_EP`onfd*G?lL1#qv!24KJopP5k-QbWMgIb`N$~X{%-6bE7O;)UDF`Q7yhvqifQ! zBwnu?Mhy8bYQRIjG2C||xbZO|%#qSYp{SFW(mBzkG#7EHF2pHH_nQenEax`F&L<3I z#nFF|c36niVIjg&sk4BH=Gd^n1=(SUX{8kNA(Kg+_(Wn%mKqdOmT727I zk2PfxR#4~1lAT3Tx-2@ykJQLG)8vCpUA5}TR=K2NB@`Ca71MR;6nk=^n4q@I!EO6* z+QXi0(s38sD3;*5KZOtBGp_qxy<_CMU(q`zt~-Gackm6J%;{VrrE|F$`*=exX4xO3 z4<2EpvKw{;lz+#2BOI3VQZXZ!;t z8ZDH*Gl)}y%FOI*^oqo;uUUYe8Sl-Yvg0dutnFX^Mbxdsl0;Y$YK~aK@e}Oe;vFNw z%P%RnKs)|B#t6z1y8%Oa>~X2Q$t(*qZE@uCOPgC&SliEdbC~f$c~EHqm0i3dEEH(f zH?ym-=i-Uda>bB1WL)I4I0&%=DgjQwO2BP^5TFh47~pBZbAVq1P662OPZPMnNyxQ? zWA?n24dA}T{tue?{Rh(kJ^mx!*WlqDLoz?&&BhGgs%LJr|3BIC@$7ZhS4_M13hmpr z2n{4rHfOcF*VMdo`;OIZTiQ45UN7zvcCPxVu!HP0tlc3rZrLmN+S_-x6Y`+(2ib<* zlLHcu&RH0B8G=Il&W9gZ)4uzmwN2}8brK6%-56YVD`R9uWcRKeymRUHUAra^K*y8+ z!yUyg*~>p~0ycsc0EYmtOeN&&MTA@c-ZYJn;RX0->;^*iq5n(BUoA%S&w!JFQ-I$C zJ~;9HoJS1_^IY2r+uW}VW*Z^zCUPqOE;?3wc=;F0zgb@Be#yOY#pV@nuUJ;UcjdX2 z>dNaY%RCjHRh~7T+dOx8?)HQ{_jp=8TRr!CBA$mm?Vd+Gk9#^jPkMShPk9b{p7s3P zbHqa`2pNIR4x2PdPW_Ry1@k}xS9RE zk)6Zt{oEZ~YYNdg0mbU?nMGBN z7Lc$ZEMO7fwy%+p#x?iv6m~*}0l@*N{bDs>Db9O|0ZHXlF$jTQ)4-|S^ZvCyTeUsYuKo41~Keb zne1qk%EHnp8%j&HB^iWB=j}sOu2hGN_vHpk>SrbGVd2?eP>@q0179T_IM!&muukVW zL-4Sg264!6*{NVCsE%Zp-$UmTkr~5<9djyUU7hE+(av*H1Ci^Fd95GQ{cja6}`Y8%F9X_}*_YOT_})bw}T?!P&Z} z9eo!-r2ZbwlABA=>kKGv6c&jWsA2%k%pg~88b)uo;|}GPqwiY~D}PK40!doEpl-Hr zW=^YrV_(heRexbG%l&xTFp>#@?z?7Fb-Ng^zGWEE&P(UolxxzpRpAJCqg@s?S-dKX zld?Fi6@FnDGJj3x$F*FO{7@?gRu<9#$^3gVKc(=R%wJacsi&NdGjAwoIiq4s*dl35 zgnCKK6qW@Am!uVlJH~hoxkASHX_~Tn1$avwl-xZncTebU@KiCzPnvp7?#AC$ot0WO z13qf_%R-UDU#=Sy4j~M}o*tVtmEkyg5Y`+us2Fqf9fyaYqwf-AK(Co7@d1Pi^0Ca( zw+<3X+u-P1K~+IVyf4p`%yINFCc!%TXn=x_gcE$snVJBn@RM?XK2Cco2g16W3O|nU zh$Xx8kq5Jxs7%OboUoD4P)nutD)&yZ$C~W7;!MkV6>nU~Cg>zTZKXC(+i4qN=Lsve z2)SDviJ!uaAzlmVdFn@buDEJ?y;j4IJNjs>BgVVXYTZZ}Wg^+{gkSER8fR3k{@QG;#|?f;>edWL;>$lHgT(jDInm}r<6Y?tT@i64&Z7<~ zS=juYAh3-u0i`#gx0*QmPJj(*FHa%s$HiMtZsZ<@+wN4u;KL~DAX`PhL z-nsXZTk4)RWY#Cx6gEL{_!Fb?46G3Pw312I`{aS;n2wm2e175U=D~`U4U&3ei1Q8b_P4<#RANt z5VI)Sp85$RSx@E<}j#$UyW zAgRZZ5ug!Dl6nX-EeS_hq#UfFKA+^8anQMsQU3UMw3 zg|`WWg)<$Dm#N-x<cWH6|faL2jC9Shf8qhxLhszZe((99Cch|thw}E`cifTo*Z2 za7sPXhM0p3iPl+ZDUm*PZxzRJAL3qTl_Rvo$Socg=^JiC?`Ig=TY3VWScTIq%609h z*AWIy**GO>M0hAD{B=-h4+<4Qp&%&kHMrgM!fRWB8;?3TZ`Zd;0di^w7%}tI*MLI$ zdZWs4m4Z~JhFa91%N<|XW*lUVDsAtd3_~9=s`TOAVd&e^Nug{+EQJz!Us~I=Z@|Bv zn;7lM3ATl_E8wD07}E6^EuMTycT0yn`NWa*A~(A_JGQ6qAQEnmD58}!Y8t#asXg8s zW@T`S%i834xd)<}hElZRyil9bl9HZer z6ihyNq#1yVGotq|=>ZoRsH!GbIg!Zo~H{pNzgI9;2RNn19J@@ah( zr;%+FxN)!{iBWMfqOF)jL`+^X*VHH-w?j#|8=K@x>Z8V-2Cc4#_QcqG(~gw}Ix-@r zte1aoW;0{%CUcB-hRxQrI^*JOK#S8|V1Jqh_I7h4lln;yTxTAZp6|*Jvnb|mU&TRv zsBlr-G~=yG?^mgzP>zN|y2^-7a8LEp3H+c41M1lqGASlwnQMUx0Z8?9PMgW3m{W!i zny2Y(?C9*;u6*2Kl+zv&MetZ>u1c}V$gH9%K13VoDD`QH<-{6M4dF2TP)^^G7s#nb z*^5W_1(Iq!9bK$86|Hqw!(Or0y@?2PTa}Z>=o1tu);@+wFC7xOav}61=19*(b88V3A4+@1rAtxxVQnHYRdO7xsyCi4f zozhhIn?rM?TWmM0oYO71S(_8%Wm)>Oa+_7{C@zfe_#?e`>{1V2>5i}=(h{I;P79fi zDcsYz9Hk5Hx&fMjj-wmlP#K_gJbkNn(JD?$+i*2D19#;w?F6jV{5e8@%0!0ECq1b4 z7#VJck@gZTa1&;Eh!Zv%5f*CCVIdK%7=AjkJAEaxHMYKhX5A-bUuV53UwH6hY8?8A^=Nxu?e-xD#6&1xxc^zdVxz?)m)3-ok zR6SVYi0}Ud1+N?hFHf2(iq8p#wEv)zdGb+eq}$9=sZ~Q3mCn#71--n_n8%G(*5MT0 zq(dk9J84N`trE)i_MoseCYg-So;Vgg|uwkuhFQSt;hYlY4wK5 zav(WNUmVu{8S&Ng!`jcNQ!|jdJ*+)PIsLcNG6G||2Z>McvTpX|*F8^HDrR$^q;e4; zK9&7HO0!$x?dgE<`RQ=*&Tx!LM`Ka^Gi>Q)=?RvJ3fW=pDt?wk!`h2@SVWb(Sm|>^ zs8BNKq6&h7EhsJuYbWr?(p_O~C0@0=Y+La((j!c5bqsjy3+n<|Fem=l&nz{6m_{Y^pYra$a``XFc{yMhaR{uc#mHIz4)CTSf><%0bBm#0E z85j(FJMf*r-vx#OCjvhV{5bGp;Aer;fnNm923`+b3j8YYFM;<1k@cPHf3W`6dd#$x zkWnCu*WoSjmU)+Z>%H5&UEU+!5%25XH@(00e(bgS@_h4si+#)EzSX`;-v-}iU)UG* zb^7l2#e9$WdVT%AZ~DIL`-$&O-}^qBf4;xezsA4Gf0zG$f6V`g|A+oF{`3BS_5Y{; zhM(n}Tme_X`M40*$vw_J$;n)jdz$+mH^e>9{e*j!`!)9-r*j!=_pLp=_KC`;D!)~E oyz*C-zpL!3dbVobYgHGju2(HtSFx^Y-H+DItzK4*{}Mg^-_q5acmMzZ diff --git a/Source/DialogTemplate.cpp b/Source/DialogTemplate.cpp index 0895b464..76adfaa0 100644 --- a/Source/DialogTemplate.cpp +++ b/Source/DialogTemplate.cpp @@ -423,26 +423,45 @@ void CDialogTemplate::ConvertToRTL() { addExStyle = true; // Button else if (int(m_vItems[i]->szClass) == 0x80) { - if (m_vItems[i]->dwStyle & BS_LEFTTEXT) addExStyle = true; + m_vItems[i]->dwStyle ^= BS_LEFTTEXT; + m_vItems[i]->dwStyle ^= BS_RIGHT; + m_vItems[i]->dwStyle ^= BS_LEFT; + + if ((m_vItems[i]->dwStyle & (BS_LEFT|BS_RIGHT)) == (BS_LEFT|BS_RIGHT)) { + m_vItems[i]->dwStyle ^= BS_LEFT; + m_vItems[i]->dwStyle ^= BS_RIGHT; + if (m_vItems[i]->dwStyle & (BS_RADIOBUTTON|BS_CHECKBOX|BS_USERBUTTON)) + m_vItems[i]->dwStyle |= BS_RIGHT; + } } // Edit else if (int(m_vItems[i]->szClass) == 0x81) { - if (!(m_vItems[i]->dwStyle & ES_CENTER)) addExStyle = true; + if ((m_vItems[i]->dwStyle & ES_CENTER) == 0) + m_vItems[i]->dwStyle ^= ES_RIGHT; } // Static else if (int(m_vItems[i]->szClass) == 0x82) { - if (!(m_vItems[i]->dwStyle & (SS_CENTER|SS_RIGHT))) { - m_vItems[i]->dwStyle &= ~SS_LEFT; - m_vItems[i]->dwStyle &= ~SS_LEFTNOWORDWRAP; + if ((m_vItems[i]->dwStyle & SS_TYPEMASK) == SS_LEFT || (m_vItems[i]->dwStyle & SS_TYPEMASK) == SS_LEFTNOWORDWRAP) + { + m_vItems[i]->dwStyle &= ~SS_TYPEMASK; m_vItems[i]->dwStyle |= SS_RIGHT; } + else if ((m_vItems[i]->dwStyle & SS_TYPEMASK) == SS_ICON) { + m_vItems[i]->dwStyle |= SS_CENTERIMAGE; + } + } + else if (!IS_INTRESOURCE(m_vItems[i]->szClass) && strcmpi(m_vItems[i]->szClass, "RichEdit20A")) { + if ((m_vItems[i]->dwStyle & ES_CENTER) == 0) + m_vItems[i]->dwStyle ^= ES_RIGHT; } else addExStyle = true; + if (addExStyle) - m_vItems[i]->dwExtStyle |= WS_EX_RIGHT; + m_vItems[i]->dwExtStyle |= WS_EX_RIGHT | WS_EX_RTLREADING; + m_vItems[i]->sX = m_sWidth - m_vItems[i]->sWidth - m_vItems[i]->sX; } - m_dwExtStyle |= WS_EX_RIGHT; + m_dwExtStyle |= WS_EX_RIGHT | WS_EX_RTLREADING; } // Saves the dialog in the form of DLGTEMPLATE[EX] diff --git a/Source/DialogTemplate.h b/Source/DialogTemplate.h index ef40b1c3..65370062 100644 --- a/Source/DialogTemplate.h +++ b/Source/DialogTemplate.h @@ -49,7 +49,7 @@ struct DialogItemTemplate { short sHeight; DWORD dwExtStyle; DWORD dwStyle; - WORD wId; + WORD wId; char *szClass; char *szTitle; diff --git a/Source/ResourceEditor.cpp b/Source/ResourceEditor.cpp index afc0f884..7abb4056 100644 --- a/Source/ResourceEditor.cpp +++ b/Source/ResourceEditor.cpp @@ -303,7 +303,7 @@ BYTE* CResourceEditor::Save(DWORD &dwSize) { oldSeeker += dwSectionsSize; // Copy data tacked after the PE headers and sections (NSIS installation data for example) - DWORD dwTackedSize = oldSeeker - m_pbPE - m_iSize; + DWORD dwTackedSize = m_iSize - (oldSeeker - m_pbPE); if (dwTackedSize) CopyMemory(seeker, oldSeeker, dwTackedSize); diff --git a/Source/build.cpp b/Source/build.cpp index 004ef67d..97391326 100644 --- a/Source/build.cpp +++ b/Source/build.cpp @@ -10,7 +10,6 @@ #include "ResourceEditor.h" #include "exehead/resource.h" -#include "exehead/lang.h" #include "ResourceVersionInfo.h" bool isSimpleChar(char ch) @@ -27,15 +26,17 @@ CEXEBuild::~CEXEBuild() { free(header_data_new); free(m_unicon_data); - for (unsigned int i = 0; i < build_nlfs.size(); i++) - delete build_nlfs[i]; + + int nlt = lang_tables.getlen() / sizeof(LanguageTable); + LanguageTable *nla = (LanguageTable*)lang_tables.get(); + + for (int i = 0; i < nlt; i++) { + DeleteLangTable(nla+i); + } } CEXEBuild::CEXEBuild() { -#ifdef NSIS_SUPPORT_NAMED_USERVARS - b_abort_compile=false; -#endif linecnt = 0; fp = 0; curfilename = 0; @@ -45,6 +46,10 @@ CEXEBuild::CEXEBuild() display_errors=1; display_warnings=1; + cur_ifblock=NULL; + last_line_had_slash=0; + inside_comment=false; + has_called_write_output=0; ns_func.add("",0); // make sure offset 0 is special on these (i.e. never used by a label) @@ -73,19 +78,20 @@ CEXEBuild::CEXEBuild() } #endif // NSIS_CONFIG_UNINSTALL_SUPPORT - strcpy(cur_out_path,"$INSTDIR"); - +#define intdef2str_(x) #x +#define intdef2str(x) intdef2str_(x) + definedlist.add("NSIS_MAX_INST_TYPES", intdef2str(NSIS_MAX_INST_TYPES)); + definedlist.add("NSIS_MAX_STRLEN", intdef2str(NSIS_MAX_STRLEN)); + definedlist.add("NSIS_DEFAULT_LANG", intdef2str(NSIS_DEFAULT_LANG)); + definedlist.add("NSIS_COMPRESS_BZIP2_LEVEL", intdef2str(NSIS_COMPRESS_BZIP2_LEVEL)); +#undef intdef2str +#undef intdef2str_ #ifdef NSIS_BZIP2_COMPRESS_WHOLE definedlist.add("NSIS_BZIP2_COMPRESS_WHOLE"); #endif #ifdef NSIS_COMPRESS_BZIP2_SMALLMODE definedlist.add("NSIS_COMPRESS_BZIP2_SMALLMODE"); #endif - { - char bzip_level[32]; - wsprintf(bzip_level, "%d", NSIS_COMPRESS_BZIP2_LEVEL); - definedlist.add("NSIS_COMPRESS_BZIP2_LEVEL", bzip_level); - } #ifdef NSIS_CONFIG_COMPONENTPAGE definedlist.add("NSIS_CONFIG_COMPONENTPAGE"); #endif @@ -119,16 +125,6 @@ CEXEBuild::CEXEBuild() #ifdef NSIS_CONFIG_VISIBLE_SUPPORT definedlist.add("NSIS_CONFIG_VISIBLE_SUPPORT"); #endif - { - char max_inst_types[32]; - wsprintf(max_inst_types, "%d", NSIS_MAX_INST_TYPES); - definedlist.add("NSIS_MAX_INST_TYPES", max_inst_types); - } - { - char max_strlen[32]; - wsprintf(max_strlen, "%d", NSIS_MAX_STRLEN); - definedlist.add("NSIS_MAX_STRLEN", max_strlen); - } #ifdef NSIS_SUPPORT_ACTIVEXREG definedlist.add("NSIS_SUPPORT_ACTIVEXREG"); #endif @@ -257,6 +253,14 @@ CEXEBuild::CEXEBuild() cur_datablock=&build_datablock; cur_functions=&build_functions; cur_labels=&build_labels; + cur_sections=&build_sections; + cur_header=&build_header; + cur_strlist=&build_strlist; + cur_langtables=&build_langtables; + cur_ctlcolors=&build_ctlcolors; + cur_pages=&build_pages; + cur_page=0; + cur_page_type=-1; subsection_open_cnt=0; build_cursection_isfunc=0; @@ -281,37 +285,55 @@ CEXEBuild::CEXEBuild() memset(&build_header,-1,sizeof(build_header)); build_header.install_reg_rootkey=0; - build_header.num_sections=0; - build_header.common.num_entries=0; - build_header.common.flags=CH_FLAGS_NO_ROOT_DIR; - build_header.common.lb_bg=RGB(0,0,0); - build_header.common.lb_fg=RGB(0,255,0); + build_header.flags=CH_FLAGS_NO_ROOT_DIR; +#ifdef NSIS_CONFIG_VISIBLE_SUPPORT + build_header.lb_bg=RGB(0,0,0); + build_header.lb_fg=RGB(0,255,0); +#endif +#ifdef NSIS_CONFIG_LICENSEPAGE + build_header.license_bg=-COLOR_BTNFACE; +#endif + build_header.install_directory_ptr=0; + build_header.install_directory_auto_append=0; + build_header.install_reg_key_ptr=0; + build_header.install_reg_value_ptr=0; +#ifdef NSIS_CONFIG_COMPONENTPAGE + memset(build_header.install_types,0,sizeof(build_header.install_types)); +#endif + memset(&build_header.blocks,0,sizeof(build_header.blocks)); uninstall_mode=0; uninstall_size_full=0; uninstall_size=-1; memset(&build_uninst,-1,sizeof(build_uninst)); - build_uninst.common.lb_bg=RGB(0,0,0); - build_uninst.common.lb_fg=RGB(0,255,0); - build_uninst.common.num_entries=0; - build_uninst.code=0; - build_uninst.code_size=-1; - build_uninst.common.flags=0; + + build_header.install_reg_rootkey=0; + build_uninst.flags=0; +#ifdef NSIS_CONFIG_VISIBLE_SUPPORT + build_uninst.lb_bg=RGB(0,0,0); + build_uninst.lb_fg=RGB(0,255,0); +#endif +#ifdef NSIS_CONFIG_LICENSEPAGE + build_uninst.license_bg=-COLOR_BTNFACE; +#endif + build_uninst.install_directory_ptr=0; + build_uninst.install_directory_auto_append=0; + build_uninst.install_reg_key_ptr=0; + build_uninst.install_reg_value_ptr=0; +#ifdef NSIS_CONFIG_COMPONENTPAGE + memset(build_uninst.install_types,0,sizeof(build_uninst.install_types)); +#endif + memset(&build_uninst.blocks,0,sizeof(build_uninst.blocks)); uninstaller_writes_used=0; build_strlist.add("",0); ubuild_strlist.add("",0); - build_header.install_directory_ptr=0; - build_header.install_directory_auto_append=0; - build_header.install_reg_key_ptr=0; -#ifdef NSIS_CONFIG_COMPONENTPAGE - memset(build_header.install_types,0,sizeof(build_header.install_types)); -#endif - // Changed by Amir Szekely 11th July 2002 - // Changed to fit the new format in which uninstaller icons are saved + build_langstring_num=0; + ubuild_langstring_num=0; + m_unicon_data=(unsigned char *)malloc(unicondata_size+3*sizeof(DWORD)); memcpy(m_unicon_data+2*sizeof(DWORD),unicon_data+22,unicondata_size); *(DWORD*)(m_unicon_data) = unicondata_size; @@ -332,35 +354,19 @@ CEXEBuild::CEXEBuild() last_used_lang=MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US); - build_header.common.num_pages=0; -#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT - build_uninst.common.num_pages=0; -#endif - - build_custom_used=0; - ubuild_custom_used=0; - res_editor=0; - build_last_page_define[0]=0; - ubuild_last_page_define[0]=0; enable_last_page_cancel=0; uenable_last_page_cancel=0; - next_used=false; - install_used=false; - comppage_used=false; - license_force_radio_used=false; - register_used=false; - unregister_used=false; + license_res_id=IDD_LICENSE; notify_hwnd=0; + defcodepage_set=false; uDefCodePage=CP_ACP; - use_first_insttype=true; - - build_header.license_bg=-COLOR_BTNFACE; + InitLangTables(); #ifdef NSIS_SUPPORT_NAMED_USERVARS // Register static user variables $0, $1 and so one @@ -381,26 +387,52 @@ CEXEBuild::CEXEBuild() m_UserVarNames.add("OUTDIR",1); // 22 m_UserVarNames.add("EXEDIR",1); // 23 m_UserVarNames.add("LANGUAGE",1); // 24 - m_UserVarNames.add("PLUGINSDIR",1); // 25 - m_UserVarNames.add("PROGRAMFILES",1); // 26 - m_UserVarNames.add("SMPROGRAMS",1); // 27 - m_UserVarNames.add("SMSTARTUP",1); // 28 - m_UserVarNames.add("DESKTOP",1); // 29 - m_UserVarNames.add("STARTMENU",1); // 30 - m_UserVarNames.add("QUICKLAUNCH",1); // 31 - m_UserVarNames.add("TEMP",1); // 32 - m_UserVarNames.add("WINDIR",1); // 33 - m_UserVarNames.add("SYSDIR",1); // 34 everything after here doesn't have trailing slash removal - m_UserVarNames.add("HWNDPARENT",1); // 35 + m_UserVarNames.add("TEMP",-1); // 25 + m_UserVarNames.add("_CLICK",-1); // 26 + m_UserVarNames.add("PLUGINSDIR",-1); // 27 + m_UserVarNames.add("PROGRAMFILES",-1); // 28 + m_UserVarNames.add("SMPROGRAMS",-1); // 29 + m_UserVarNames.add("SMSTARTUP",-1); // 30 + m_UserVarNames.add("DESKTOP",-1); // 31 + m_UserVarNames.add("STARTMENU",-1); // 32 + m_UserVarNames.add("QUICKLAUNCH",-1); // 33 + m_UserVarNames.add("WINDIR",-1); // 34 + m_UserVarNames.add("SYSDIR",-1); // 35 everything after here doesn't have trailing slash removal + m_UserVarNames.add("HWNDPARENT",-1); // 36 #endif } int CEXEBuild::getcurdbsize() { return cur_datablock->getlen(); } -int CEXEBuild::add_string(const char *string) // returns offset in stringblock +int CEXEBuild::add_string(const char *string, int process/*=1*/) // returns offset in stringblock { - if (uninstall_mode) return add_string_uninst(string,1); - return add_string_main(string,1); + if (!*string) return 0; + + if (process && *string == '$' && *(string+1) == '(') { + int idx = 0; + char *cp = strdup(string+2); + char *p = strchr(cp, ')'); +#ifdef NSIS_SUPPORT_LANG_IN_STRINGS + if (p && p[1] == '\0' ) { // if string is only a language str identifier +#else + if (p) { +#endif + *p = 0; + idx = DefineLangString(cp, process); + } + free(cp); + if (idx < 0) return idx; + } + + if (!process) return cur_strlist->add(string,2); + + char buf[4096]; +#ifdef NSIS_SUPPORT_LANG_IN_STRINGS + preprocess_string(buf,string,false); +#else + preprocess_string(buf,string); +#endif + return cur_strlist->add(buf,2); } int CEXEBuild::add_intstring(const int i) // returns offset in stringblock @@ -446,16 +478,17 @@ int CEXEBuild::preprocess_string(char *out, const char *in) "OUTDIR\0" // 23 "EXEDIR\0" // 24 "LANGUAGE\0" // 25 - "PLUGINSDIR\0" // 26 - "PROGRAMFILES\0" // 27 - "SMPROGRAMS\0" // 28 - "SMSTARTUP\0" // 29 - "DESKTOP\0" // 30 - "STARTMENU\0" // 31 - "QUICKLAUNCH\0" // 32 - "TEMP\0" // 33 - "WINDIR\0" // 34 - "SYSDIR\0" // 35 + "TEMP\0" // 26 + "_CLICK\0" // 27 + "PLUGINSDIR\0" // 28 + "PROGRAMFILES\0" // 29 + "SMPROGRAMS\0" // 30 + "SMSTARTUP\0" // 31 + "DESKTOP\0" // 32 + "STARTMENU\0" // 33 + "QUICKLAUNCH\0" // 34 + "WINDIR\0" // 35 + "SYSDIR\0" // 36 ; #endif @@ -556,40 +589,26 @@ int CEXEBuild::preprocess_string(char *out, const char *in) *pos = 0; if ( !bUninstall ) { - if (!strnicmp(cp,"un.",3)) { - warning("Installer language strings can't start with un. (%s)! (%s:%d)", p, curfilename, linecnt); - } - else - { - idx = GetUserString(cp); - if ( idx >= 0 ) - { - idx = -((int)(idx+1+(sizeof(common_strings)+sizeof(installer_strings))/sizeof(int))); - *out++=(unsigned int)LANG_CODES_START; // Next word is lang-string Identifier - *(WORD*)out=(WORD)idx; - out += sizeof(WORD); - p += strlen(cp)+2; - bProceced = true; - } + idx = DefineLangString(cp); + if ( idx < 0 ) + { + *out++=(unsigned int)LANG_CODES_START; // Next word is lang-string Identifier + *(WORD*)out=(WORD)idx; + out += sizeof(WORD); + p += strlen(cp)+2; + bProceced = true; } } else - { - if (strnicmp(cp,"un.",3)) { - warning("Uninstaller language strings must start with un. (%s)! (%s:%d)", p, curfilename, linecnt); - } - else - { - idx = GetUserString(cp); - if ( idx >= 0 ) - { - idx = -((int)(idx+1+(sizeof(common_strings)+sizeof(uninstall_strings))/sizeof(int))); - *out++=(unsigned int)LANG_CODES_START; // Next word is lang-string Identifier - *(WORD*)out=(WORD)idx; - out += sizeof(WORD); - p += strlen(cp)+2; - bProceced = true; - } + { + idx = DefineLangString(cp); + if ( idx < 0 ) + { + *out++=(unsigned int)LANG_CODES_START; // Next word is lang-string Identifier + *(WORD*)out=(WORD)idx; + out += sizeof(WORD); + p += strlen(cp)+2; + bProceced = true; } } } @@ -631,7 +650,7 @@ int CEXEBuild::preprocess_string(char *out, const char *in) if (strstr(tbuf," ")) strstr(tbuf," ")[0]=0; } if ( bDoWarning ) - warning("unknown variable \"%s\" detected, ignoring (%s:%d)",tbuf,curfilename,linecnt); + warning_fl("unknown variable \"%s\" detected, ignoring",tbuf); i = '$'; } } @@ -643,78 +662,6 @@ int CEXEBuild::preprocess_string(char *out, const char *in) return 0; } -int CEXEBuild::add_string_main(const char *string, int process) // returns offset (in string block) -{ - if (!*string) return 0; - - if (*string == '$' && *(string+1) == '(') { - int idx = -1; - char *cp = strdup(string+2); - char *p = strchr(cp, ')'); -#ifdef NSIS_SUPPORT_LANG_IN_STRINGS - if (p && p[1] == '\0' ) { // if string is only a language str identifier -#else - if (p) { -#endif - *p = 0; - if (!strnicmp(cp,"un.",3)) { - warning("Installer language strings can't start with un. (%s)! (%s:%d)", string, curfilename, linecnt); - free(cp); - return 0; - } - idx = GetUserString(cp); - } - free(cp); - if (idx >= 0) return -((int)(idx+1+(sizeof(common_strings)+sizeof(installer_strings))/sizeof(int))); - } - - if (!process) return build_strlist.add(string,2); - - char buf[4096]; -#ifdef NSIS_SUPPORT_LANG_IN_STRINGS - preprocess_string(buf,string, false); -#else - preprocess_string(buf,string); -#endif - return build_strlist.add(buf,2); -} - -int CEXEBuild::add_string_uninst(const char *string, int process) // returns offset (in string block) -{ - if (!*string) return 0; - - if (*string == '$' && *(string+1) == '(') { - int idx = -1; - char *cp = strdup(string+2); - char *p = strchr(cp, ')'); -#ifdef NSIS_SUPPORT_LANG_IN_STRINGS - if (p && p[1] == '\0' ) { // if string is only a language str identifier -#else - if (p) { -#endif - *p = 0; - if (strnicmp(cp,"un.",3)) { - warning("Uninstaller language strings must start with un. (%s)! (%s:%d)", string, curfilename, linecnt); - free(cp); - return 0; - } - idx = GetUserString(cp); - } - free(cp); - if (idx >= 0) return -((int)(idx+1+(sizeof(common_strings)+sizeof(uninstall_strings))/sizeof(int))); - } - - if (!process) return ubuild_strlist.add(string,2); - - char buf[4096]; -#ifdef NSIS_SUPPORT_LANG_IN_STRINGS - preprocess_string(buf,string, true); -#else - preprocess_string(buf,string); -#endif - return ubuild_strlist.add(buf,2); -} - // what it does is, when you pass it the offset of the last item added, it will determine if // that data is already present in the datablock, and if so, reference it instead (and shorten // the datablock as necessary). Reduces overhead if you want to add files to a couple places. @@ -820,7 +767,7 @@ int CEXEBuild::add_data(const char *data, int length, IGrowBuf *dblock) // retur int CEXEBuild::add_label(const char *name) { - if (!build_cursection && !uninstall_mode) + if (!build_cursection) { ERROR_MSG("Error: Label declaration not valid outside of function/section\n"); return PS_ERROR; @@ -830,18 +777,9 @@ int CEXEBuild::add_label(const char *name) ERROR_MSG("Error: labels must not begin with 0-9, -, :, or a space.\n"); return PS_ERROR; } - int cs; - int ce; - if (build_cursection) - { - cs=build_cursection->code; - ce=cs+build_cursection->code_size; - } - else - { - cs=build_uninst.code; - ce=cs+build_uninst.code_size; - } + + int cs=build_cursection->code; + int ce=cs+build_cursection->code_size; char *p=strdup(name); if (p[strlen(p)-1] == ':') p[strlen(p)-1]=0; @@ -885,16 +823,18 @@ int CEXEBuild::add_function(const char *funname) ERROR_MSG("Error: Section open when creating function (use SectionEnd first)\n"); return PS_ERROR; } + if (cur_page) + { + ERROR_MSG("Error: PageEx open when creating function (use PageExEnd first)\n"); + return PS_ERROR; + } if (!funname[0]) { ERROR_MSG("Error: Function must have a name\n"); return PS_ERROR; } - if (!strnicmp(funname,"un.",3)) - { - set_uninstall_mode(1); - } + set_uninstall_mode(!strnicmp(funname,"un.",3)); int addr=ns_func.add(funname,0); int x; @@ -928,15 +868,12 @@ int CEXEBuild::function_end() ERROR_MSG("Error: No function open, FunctionEnd called\n"); return PS_ERROR; } + // add ret. + add_entry_indirect(EW_RET); + build_cursection_isfunc=0; build_cursection=NULL; - // add ret. - entry ent={EW_RET,}; - cur_entries->add(&ent,sizeof(entry)); - if (!uninstall_mode) build_header.common.num_entries++; - else build_uninst.common.num_entries++; - set_uninstall_mode(0); return PS_OK; } @@ -944,27 +881,17 @@ int CEXEBuild::function_end() int CEXEBuild::section_add_flags(int flags) { - if (uninstall_mode) - { - ERROR_MSG("Error: can't modify flags of uninstall section\n"); - return PS_ERROR; - } if (!build_cursection || build_cursection_isfunc) { ERROR_MSG("Error: can't modify flags when no section is open\n"); return PS_ERROR; } - build_cursection->flags|=flags; + build_cursection->flags |= flags; return PS_OK; } int CEXEBuild::section_add_install_type(int inst_type) { - if (uninstall_mode) - { - ERROR_MSG("Error: can't modify flags of uninstall section\n"); - return PS_ERROR; - } if (!build_cursection || build_cursection_isfunc) { ERROR_MSG("Error: can't modify flags when no section is open\n"); @@ -972,7 +899,7 @@ int CEXEBuild::section_add_install_type(int inst_type) } if (build_cursection->install_types == ~0) build_cursection->install_types = 0; - build_cursection->install_types|=inst_type; + build_cursection->install_types |= inst_type; return PS_OK; } @@ -991,25 +918,16 @@ int CEXEBuild::section_end() ERROR_MSG("Error: SectionEnd specified in function (not section)\n"); return PS_ERROR; } - else if (uninstall_mode) - { - entry ent={EW_RET,}; - cur_entries->add(&ent,sizeof(entry)); - build_uninst.common.num_entries++; - set_uninstall_mode(0); - } - else if (!build_cursection) + if (!build_cursection) { ERROR_MSG("Error: SectionEnd specified and no sections open\n"); return PS_ERROR; } - else - { - entry ent={EW_RET,}; - cur_entries->add(&ent,sizeof(entry)); - build_header.common.num_entries++; - } + add_entry_indirect(EW_RET); + build_cursection->code_size--; build_cursection=NULL; + if (!subsection_open_cnt) + set_uninstall_mode(0); return PS_OK; } @@ -1020,85 +938,120 @@ int CEXEBuild::add_section(const char *secname, const char *defname, int expand/ ERROR_MSG("Error: Section can't create section (already in function, use FunctionEnd first)\n"); return PS_ERROR; } - if (build_cursection || uninstall_mode) + if (cur_page) { + ERROR_MSG("Error: PageEx already open, call PageExEnd first\n"); + return PS_ERROR; + } + if (build_cursection) { ERROR_MSG("Error: Section already open, call SectionEnd first\n"); return PS_ERROR; } - if (!stricmp(secname,"uninstall")) - { - if (defname[0]) - { - ERROR_MSG("Error: Uninstall section cannot have index output define\n"); - return PS_ERROR; - } - if (build_uninst.code_size >= 0) - { - ERROR_MSG("Error: Uninstall section already specified\n"); - return PS_ERROR; - } - if (subsection_open_cnt) - { - ERROR_MSG("Error: Uninstall section specified inside SubSection\n"); - return PS_ERROR; - } - build_uninst.code=ubuild_entries.getlen()/sizeof(entry); - build_uninst.code_size=0; - set_uninstall_mode(1); - build_cursection=NULL; - return PS_OK; - } + + section new_section; + new_section.flags = SF_SELECTED; + new_section.flags |= expand ? SF_EXPAND : 0; + new_section.code_size = 0; + new_section.size_kb = 0; char *name = (char*)secname; - int n=(build_sections.getlen()/sizeof(section)); - build_sections.resize(build_sections.getlen()+sizeof(section)); - build_cursection=((section*)build_sections.get()) + n; - build_cursection->flags=SF_SELECTED; - build_cursection->flags|=expand?SF_EXPAND:0; - if (secname[0]=='!' || (secname[0]=='-' && secname[1]=='!')) { - name++; - build_cursection->flags|=SF_BOLD; - } - build_cursection->flags|=expand?SF_EXPAND:0; - build_cursection->name_ptr=add_string(secname[0]=='-'&&secname[1]?++name:name); - build_cursection->code=cur_entries->getlen()/sizeof(entry); - build_cursection->code_size=0; - build_cursection->size_kb=0; - build_cursection->install_types=*name?0:~0; - - if (secname[0]=='-') + if (secname[0] == '-') { - build_cursection->flags|=secname[1]?SF_SUBSEC:SF_SUBSECEND; - build_cursection=NULL; - entry ent={EW_RET,}; - cur_entries->add(&ent,sizeof(entry)); - build_header.common.num_entries++; + if (secname[1]) + { + new_section.flags |= SF_SUBSEC; + name++; + } + else + new_section.flags |= SF_SUBSECEND; + } + + if (name[0] == '!') + { + name++; + new_section.flags |= SF_BOLD; + } + + int old_uninstall_mode = uninstall_mode; + + set_uninstall_mode(0); + + if (!strnicmp(name, "un.", 3)) + { + set_uninstall_mode(1); + name += 3; + } + + if (!stricmp(name, "uninstall")) + { + set_uninstall_mode(1); + } + + if (subsection_open_cnt && !(new_section.flags & SF_SUBSECEND)) + { + if (uninstall_mode != old_uninstall_mode) + { + ERROR_MSG("Error: Can't create %s section in %s subsection (use SubSectionEnd first)\n", uninstall_mode ? "uninstaller" : "installer", old_uninstall_mode ? "uninstaller" : "installer"); + return PS_ERROR; + } + } + + new_section.code = cur_entries->getlen() / sizeof(entry); + + new_section.install_types = *name ? 0 : ~0; + new_section.name_ptr = add_string(name); + + cur_sections->add(&new_section, sizeof(section)); + build_cursection = (section *) cur_sections->get() + cur_header->blocks[NB_SECTIONS].num; + + if (new_section.flags & (SF_SUBSEC | SF_SUBSECEND)) + { + if (new_section.flags & SF_SUBSECEND) + { + subsection_open_cnt--; + if (subsection_open_cnt < 0) + { + ERROR_MSG("SubSectionEnd: no SubSections are open\n"); + return PS_ERROR; + } + if (!subsection_open_cnt) + set_uninstall_mode(0); + } + else + subsection_open_cnt++; + + add_entry_indirect(EW_RET); + build_cursection = 0; } if (defname[0]) { char buf[32]; - wsprintf(buf,"%d",build_header.num_sections); - if (definedlist.add(defname,buf)) + wsprintf(buf, "%d", cur_header->blocks[NB_SECTIONS].num); + if (definedlist.add(defname, buf)) { - ERROR_MSG("Error: \"%s\" already defined, can't assign section index!\n",defname); + ERROR_MSG("Error: \"%s\" already defined, can't assign section index!\n", defname); return PS_ERROR; } } - build_header.num_sections++; + cur_header->blocks[NB_SECTIONS].num++; return PS_OK; } -int CEXEBuild::make_sure_not_in_secorfunc(const char *str) +int CEXEBuild::make_sure_not_in_secorfunc(const char *str, int page_ok/*=0*/) { - if (build_cursection || uninstall_mode) + if (build_cursection) { ERROR_MSG("Error: command %s not valid in %s\n",str,build_cursection_isfunc?"function":"section"); return PS_ERROR; } + if (cur_page && !page_ok) { + ERROR_MSG("Error: command %s not valid in PageEx\n",str); + return PS_ERROR; + } return PS_OK; } @@ -1111,28 +1064,13 @@ int CEXEBuild::add_entry(const entry *ent) } cur_entries->add(ent,sizeof(entry)); - - if (!uninstall_mode) - { - if (!build_cursection_isfunc && build_cursection->name_ptr >=0 && build_strlist.get()[build_cursection->name_ptr] == '-') - { - ERROR_MSG("Error: cannot add entry to divider section\n"); - return PS_ERROR; - } - build_cursection->code_size++; - build_header.common.num_entries++; - } - else - { - build_uninst.common.num_entries++; - if (build_cursection) build_cursection->code_size++; - else build_uninst.code_size++; - } + build_cursection->code_size++; + cur_header->blocks[NB_ENTRIES].num++; return PS_OK; } -int CEXEBuild::add_entry_direct(int which, int o0, int o1, int o2, int o3, int o4, int o5 /*o#=0*/) +int CEXEBuild::add_entry_indirect(int which, int o0, int o1, int o2, int o3, int o4, int o5 /*o#=0*/) { entry ent; ent.which = which; @@ -1196,11 +1134,9 @@ int CEXEBuild::resolve_call_int(const char *fn, const char *str, int fptr, int * sec++; } ERROR_MSG("Error: resolving %s function \"%s\" in %s\n",str,(char*)ns_func.get()+fptr,fn); - ERROR_MSG("Note: uninstall functions must begin with \"un.\", and install functions must not\n"); - return 1; - } - - + ERROR_MSG("Note: uninstall functions must begin with \"un.\", and install functions must not\n"); + return 1; +} int CEXEBuild::resolve_instruction(const char *fn, const char *str, entry *w, int offs, int start, int end) { @@ -1309,60 +1245,91 @@ int CEXEBuild::resolve_coderefs(const char *str) } sec++; } - if (uninstall_mode) + + int cnt=0; + sec=(section *)cur_sections->get(); + l=cur_sections->getlen()/sizeof(section); + while (l-- > 0) { - int x; - for (x = build_uninst.code; x < build_uninst.code+build_uninst.code_size; x ++) - if (resolve_instruction("\"uninstall section\"",str,w+x,x,build_uninst.code,build_uninst.code+build_uninst.code_size)) return 1; + int x=sec->name_ptr; + char fname[1024]; + char *secname; + if (x < 0) + { + // lang string + secname = "$(lang string)"; + } + else + { + // normal string + secname = cur_strlist->get() + x; + } + if (x) wsprintf(fname,"%s section \"%s\" (%d)",str,secname,cnt); + else wsprintf(fname,"unnamed %s section (%d)",str,cnt); + for (x = sec->code; x < sec->code+sec->code_size; x ++) + { + if (resolve_instruction(fname,str,w+x,x,sec->code,sec->code+sec->code_size)) + return 1; + } + sec++; + cnt++; + } +#ifdef NSIS_CONFIG_VISIBLE_SUPPORT +#ifdef NSIS_SUPPORT_CODECALLBACKS + if (cur_pages->getlen()) { + page *p=(page *)cur_pages->get(); + int i = 0; + while (i < cur_header->blocks[NB_PAGES].num) { + char pagestr[1024]; + wsprintf(pagestr, "%s pages", str); + if (resolve_call_int(pagestr,"pre-page",p->prefunc,&p->prefunc)) return 1; + if (resolve_call_int(pagestr,p->dlg_id?"show-page":"leave-page",p->showfunc,&p->showfunc)) return 1; + if (resolve_call_int(pagestr,"leave-page",p->leavefunc,&p->leavefunc)) return 1; + p++; + i++; + } + } +#endif +#endif + } #ifdef NSIS_SUPPORT_CODECALLBACKS - if (ubuild_pages.getlen()) { - page *p=(page *)ubuild_pages.get(); - int i = 0; - while (i < build_uninst.common.num_pages) { - if (resolve_call_int("uninstall pages","pre-page",p->prefunc,&p->prefunc)) return 1; - if (resolve_call_int("uninstall pages",p->id?"show-page":"leave-page",p->showfunc,&p->showfunc)) return 1; - if (resolve_call_int("uninstall pages","leave-page",p->leavefunc,&p->leavefunc)) return 1; - p++; - i++; - } - } + // resolve callbacks + { + struct { + char *name; + int *p; + } callbacks[] = { + {"%s.onInit", &cur_header->code_onInit}, + {"%s.on%sInstSuccess", &cur_header->code_onInstSuccess}, + {"%s.on%sInstFailed", &cur_header->code_onInstFailed}, + {"%s.onUserAbort", &cur_header->code_onUserAbort}, + {"%s.onVerifyInstDir", &cur_header->code_onVerifyInstDir}, +#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT + {"%s.onGUIInit", &cur_header->code_onGUIInit}, + {"%s.onGUIEnd", &cur_header->code_onGUIEnd}, + {"%s.onMouseOverSection", &cur_header->code_onMouseOverSection}, #endif - } - else - { - int cnt=0; - sec=(section *)build_sections.get(); - l=build_sections.getlen()/sizeof(section); - while (l-- > 0) - { - int x; - for (x = sec->code; x < sec->code+sec->code_size; x ++) - { - char fname[1024]; - char *secname = (sec->name_ptr < 0) ? build_userlangstrings.idx2name(-sec->name_ptr-1-(sizeof(common_strings)+sizeof(installer_strings))/sizeof(int)) : build_strlist.get()+sec->name_ptr; - if (sec->name_ptr) wsprintf(fname,"section \"%s\" (%d)",secname,cnt); - else wsprintf(fname,"unnamed section (%d)",cnt); - if (resolve_instruction(fname,str,w+x,x,sec->code,sec->code+sec->code_size)) return 1; - } - sec++; - cnt++; - } -#ifdef NSIS_SUPPORT_CODECALLBACKS - if (build_pages.getlen()) { - page *p=(page *)build_pages.get(); - int i = 0; - while (i < build_header.common.num_pages) { - if (resolve_call_int("pages","pre-page",p->prefunc,&p->prefunc)) return 1; - if (resolve_call_int("pages",p->id?"show-page":"leave-page",p->showfunc,&p->showfunc)) return 1; - if (resolve_call_int("pages","leave-page",p->leavefunc,&p->leavefunc)) return 1; - p++; - i++; - } - } +#ifdef NSIS_CONFIG_COMPONENTPAGE + {"%s.onSelChange", &cur_header->code_onSelChange}, #endif + {0, 0} + }; + + for (int i = 0; callbacks[i].name; i++) { + char *un = uninstall_mode ? "un" : ""; + char fname[1024]; + wsprintf(fname, callbacks[i].name, un, un); + char cbstr[1024]; + wsprintf(cbstr, "%s callback", str); + char cbstr2[1024]; + wsprintf(cbstr2, "%s.callbacks", un); + + if (resolve_call_int(cbstr,cbstr2,ns_func.find(fname,0),callbacks[i].p)) + return PS_ERROR; } } +#endif//NSIS_SUPPORT_CODECALLBACKS // optimize unused functions { @@ -1407,16 +1374,97 @@ int CEXEBuild::resolve_coderefs(const char *str) return 0; } -int CEXEBuild::write_output(void) +#ifdef NSIS_CONFIG_VISIBLE_SUPPORT +int CEXEBuild::add_page(int type) { + page pg = { + 0, + 0, +#ifdef NSIS_SUPPORT_CODECALLBACKS + -1, + -1, + -1, +#endif + 0, + }; + +#ifndef NSIS_CONFIG_LICENSEPAGE + if (type == PAGE_LICENSE) + { + ERROR_MSG("Error: can't add license page, NSIS_CONFIG_LICENSEPAGE not defined.\n"); + return PS_ERROR; + } +#endif +#ifndef NSIS_CONFIG_COMPONENTPAGE + if (type == PAGE_COMPONENTS) + { + ERROR_MSG("Error: can't add components page, NSIS_CONFIG_COMPONENTPAGE not defined.\n"); + return PS_ERROR; + } +#endif +#ifndef NSIS_CONFIG_UNINSTALL_SUPPORT + if (type == PAGE_COMPONENTS) + { + ERROR_MSG("Error: can't add uninstConfirm page, NSIS_CONFIG_UNINSTALL_SUPPORT not defined.\n"); + return PS_ERROR; + } +#endif + + struct { + int wndproc_id; + int dlg_id; + } ids[] = { + {PWP_CUSTOM, 0}, // custom +#ifdef NSIS_CONFIG_LICENSEPAGE + {PWP_LICENSE, IDD_LICENSE}, // license +#else + {0, IDD_LICENSE}, // license +#endif +#ifdef NSIS_CONFIG_COMPONENTPAGE + {PWP_SELCOM, IDD_SELCOM}, // components +#else + {0, IDD_SELCOM}, // components +#endif + {PWP_DIR, IDD_DIR}, // directory + {PWP_INSTFILES, IDD_INSTFILES}, // instfiles +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT + {PWP_UNINST, IDD_UNINST}, // uninstConfirm +#else + {0, IDD_UNINST}, // uninstConfirm +#endif + {PWP_COMPLETED, -1} // completed + }; + + pg.wndproc_id = ids[type].wndproc_id; + pg.dlg_id = ids[type].dlg_id; + + cur_pages->add(&pg,sizeof(page)); + + cur_page = (page *)cur_pages->get() + cur_header->blocks[NB_PAGES].num++; + + cur_page_type = type; + + return PS_OK; +} + +int CEXEBuild::page_end() +{ + cur_page = 0; + + return PS_OK; +} +#endif + #ifdef NSIS_SUPPORT_VERSION_INFO - GrowBuf VerInfoStream; +int CEXEBuild::AddVersionInfo() +{ + GrowBuf VerInfoStream; bool bNeedVInfo = false; if ( rVersionInfo.GetStringTablesCount() > 0 ) { if ( !version_product_v[0] ) - { + { ERROR_MSG("Error: VIProductVersion is required when other version information functions are used.\n"); return PS_ERROR; } @@ -1436,23 +1484,440 @@ int CEXEBuild::write_output(void) { LANGID lang_id = rVersionInfo.GetLangID(i); int code_page = rVersionInfo.GetCodePage(i); - StringTable * Table = GetTable(lang_id); - + LanguageTable *Table = GetLangTable(lang_id); + if ( !rVersionInfo.FindKey(lang_id, code_page, "FileVersion") ) - warning("Generating version information for language \"%04d-%s\" without standard key \"FileVersion\"", lang_id, Table->nlf ? Table->nlf->m_szName : lang_id == 1033 ? "English" : "???"); + warning("Generating version information for language \"%04d-%s\" without standard key \"FileVersion\"", lang_id, Table->nlf.m_bLoaded ? Table->nlf.m_szName : lang_id == 1033 ? "English" : "???"); if ( !rVersionInfo.FindKey(lang_id, code_page, "FileDescription") ) - warning("Generating version information for language \"%04d-%s\" without standard key \"FileDescription\"", lang_id, Table->nlf ? Table->nlf->m_szName : lang_id == 1033 ? "English" : "???"); + warning("Generating version information for language \"%04d-%s\" without standard key \"FileDescription\"", lang_id, Table->nlf.m_bLoaded ? Table->nlf.m_szName : lang_id == 1033 ? "English" : "???"); if ( !rVersionInfo.FindKey(lang_id, code_page, "LegalCopyright") ) - warning("Generating version information for language \"%04d-%s\" without standard key \"LegalCopyright\"", lang_id, Table->nlf ? Table->nlf->m_szName : lang_id == 1033 ? "English" : "???"); + warning("Generating version information for language \"%04d-%s\" without standard key \"LegalCopyright\"", lang_id, Table->nlf.m_bLoaded ? Table->nlf.m_szName : lang_id == 1033 ? "English" : "???"); rVersionInfo.ExportToStream(VerInfoStream, i); - res_editor->UpdateResource(RT_VERSION, 1, lang_id, (BYTE*)VerInfoStream.get(), VerInfoStream.getlen()); + res_editor->UpdateResource(RT_VERSION, 1, lang_id, (BYTE*)VerInfoStream.get(), VerInfoStream.getlen()); } } } - + + return PS_OK; +} #endif // NSIS_SUPPORT_VERSION_INFO +#ifdef NSIS_CONFIG_VISIBLE_SUPPORT +int CEXEBuild::ProcessPages() +{ + SCRIPT_MSG("Processing pages... "); + + int license_normal=0; + int license_fsrb=0; + int license_fscb=0; + int selcom=0; + int dir=0, dir_used; + int uninstconfirm=0; + int instlog=0, instlog_used; + int main=0; + +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT +again: +#endif + + dir_used = 0; + instlog_used = 0; + +#ifdef NSIS_CONFIG_SILENT_SUPPORT + if ((cur_header->flags & (CH_FLAGS_SILENT|CH_FLAGS_SILENT_LOG)) == 0) +#endif + { + main++; + +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT +#define LS(inst, uninst) (uninstall_mode ? uninst : inst) +#else +#define LS(inst, uninst) inst +#endif + + DefineInnerLangString(LS(NLF_CAPTION, NLF_UCAPTION)); + DefineInnerLangString(NLF_BRANDING); + + if (!cur_pages->getlen()) { +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT + if (uninstall_mode) { + if (HasUserDefined(NLF_UNINST_TEXT)) { + add_page(PAGE_UNINSTCONFIRM); + page_end(); + } + add_page(PAGE_INSTFILES); + page_end(); + add_page(PAGE_COMPLETED); + page_end(); + } + else +#endif + { +#ifdef NSIS_CONFIG_LICENSEPAGE + if (HasUserDefined(NLF_LICENSE_TEXT) && HasUserDefined(NLF_LICENSE_DATA)) { + add_page(PAGE_LICENSE); + page_end(); + } +#endif +#ifdef NSIS_CONFIG_COMPONENTPAGE + if (HasUserDefined(NLF_COMP_TEXT)) { + add_page(PAGE_COMPONENTS); + page_end(); + } +#endif + if (HasUserDefined(NLF_DIR_TEXT)) { + add_page(PAGE_DIRECTORY); + page_end(); + } + add_page(PAGE_INSTFILES); + page_end(); + add_page(PAGE_COMPLETED); + page_end(); + } + } + // start processing the pages + { + int i = 0; + page *p = (page *) cur_pages->get(); + + for (i = 0; i < cur_header->blocks[NB_PAGES].num; i++, p++) { + page *pp = 0; + + if (i) { + pp = p - 1; + + // set back button + p->flags |= PF_BACK_SHOW; + if (pp->wndproc_id != PWP_COMPLETED && p->wndproc_id != PWP_COMPLETED && p->wndproc_id != PWP_INSTFILES) + p->flags |= PF_BACK_ENABLE; + if (!p->back) + p->back = DefineInnerLangString(NLF_BTN_BACK); + + // set previous page's next button + if (!pp->next) { + int str = 0; + +#ifdef NSIS_CONFIG_LICENSEPAGE + if (pp->wndproc_id == PWP_LICENSE && (!(pp->flags & PF_LICENSE_FORCE_SELECTION) || HasUserDefined(NLF_BTN_LICENSE))) + str = NLF_BTN_LICENSE; + else +#endif + if (p->wndproc_id == PWP_INSTFILES) + str = LS(NLF_BTN_INSTALL, NLF_BTN_UNINSTALL); + else + str = NLF_BTN_NEXT; + + pp->next = DefineInnerLangString(str); + } + + // set previous page's click next text + if (!pp->clicknext) { + int str = 0; + + if (p->wndproc_id == PWP_INSTFILES) + str = LS(NLF_CLICK_INSTALL, NLF_CLICK_UNINSTALL); + else + str = NLF_CLICK_NEXT; + + pp->clicknext = DefineInnerLangString(str); + } + } + + // enable next button + if (p->wndproc_id != PWP_INSTFILES) + p->flags |= PF_NEXT_ENABLE; + + // set cancel button + if (!p->cancel) + p->cancel = DefineInnerLangString(NLF_BTN_CANCEL); + if (p->wndproc_id != PWP_INSTFILES && p->wndproc_id != PWP_COMPLETED) + p->flags |= PF_CANCEL_ENABLE; + + // set caption + struct { + int caption; + int ucaption; + } captions[] = { +#ifdef NSIS_CONFIG_LICENSEPAGE + {NLF_SUBCAPTION_LICENSE, NLF_SUBCAPTION_LICENSE}, +#endif +#ifdef NSIS_CONFIG_COMPONENTPAGE + {NLF_SUBCAPTION_OPTIONS, NLF_SUBCAPTION_OPTIONS}, +#endif + {NLF_SUBCAPTION_DIR, NLF_SUBCAPTION_DIR}, + {NLF_SUBCAPTION_INSTFILES, NLF_USUBCAPTION_INSTFILES}, +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT + {NLF_USUBCAPTION_CONFIRM, NLF_USUBCAPTION_CONFIRM}, +#endif + {NLF_SUBCAPTION_COMPLETED, NLF_USUBCAPTION_COMPLETED} + }; + + if (!p->caption && p->wndproc_id != PWP_CUSTOM) { + p->caption = DefineInnerLangString(LS(captions[p->wndproc_id].caption, captions[p->wndproc_id].ucaption)); + } + + // set texts + switch (p->dlg_id) { +#ifdef NSIS_CONFIG_LICENSEPAGE + case IDD_LICENSE: + case IDD_LICENSE_FSRB: + case IDD_LICENSE_FSCB: + { + if (!(p->flags & PF_PAGE_EX)) + p->dlg_id = license_res_id; + if (!(p->flags & (PF_LICENSE_FORCE_SELECTION | PF_LICENSE_NO_FORCE_SELECTION))) + p->dlg_id = license_res_id; + + p->flags |= PF_NO_NEXT_FOCUS; + + if (!p->parms[1]) + p->parms[1] = DefineInnerLangString(NLF_LICENSE_DATA, 0); + + if (p->dlg_id == IDD_LICENSE) { + if (!p->parms[0]) + p->parms[0] = DefineInnerLangString(LS(NLF_LICENSE_TEXT, NLF_ULICENSE_TEXT)); + + license_normal++; + } + else if (p->dlg_id == IDD_LICENSE_FSCB) { + p->flags |= PF_LICENSE_FORCE_SELECTION; + + if (!p->parms[0]) + p->parms[0] = DefineInnerLangString(LS(NLF_LICENSE_TEXT_FSCB, NLF_ULICENSE_TEXT_FSCB)); + if (!p->parms[2]) + p->parms[2] = DefineInnerLangString(NLF_BTN_LICENSE_AGREE); + + license_fscb++; + } + else if (p->dlg_id == IDD_LICENSE_FSRB) { + p->flags |= PF_LICENSE_FORCE_SELECTION; + + if (!p->parms[0]) + p->parms[0] = DefineInnerLangString(LS(NLF_LICENSE_TEXT_FSRB, NLF_ULICENSE_TEXT_FSRB)); + if (!p->parms[2]) + p->parms[2] = DefineInnerLangString(NLF_BTN_LICENSE_AGREE); + if (!p->parms[3]) + p->parms[3] = DefineInnerLangString(NLF_BTN_LICENSE_DISAGREE); + + license_fsrb++; + } + break; + } +#endif +#ifdef NSIS_CONFIG_COMPONENTPAGE + case IDD_SELCOM: + { + if (!p->parms[0]) + p->parms[0] = DefineInnerLangString(LS(NLF_COMP_TEXT, NLF_UCOMP_TEXT)); + if (!p->parms[1]) + p->parms[1] = DefineInnerLangString(LS(NLF_COMP_SUBTEXT1, NLF_UCOMP_SUBTEXT1)); + if (!p->parms[2]) + p->parms[2] = DefineInnerLangString(LS(NLF_COMP_SUBTEXT2, NLF_UCOMP_SUBTEXT2)); + if (!p->parms[4]) + p->parms[4] = DefineInnerLangString(LS(NLF_COMP_SUBTEXT1_NO_INST_TYPES, NLF_UCOMP_SUBTEXT1_NO_INST_TYPES)); + + DefineInnerLangString(NLF_SPACE_REQ); + DefineInnerLangString(NLF_BYTE); + DefineInnerLangString(NLF_KILO); + DefineInnerLangString(NLF_MEGA); + DefineInnerLangString(NLF_GIGA); + + selcom++; + break; + } +#endif + case IDD_DIR: + { + if (!p->parms[0]) + p->parms[0] = DefineInnerLangString(LS(NLF_DIR_TEXT, NLF_UDIR_TEXT)); + if (!p->parms[1]) + p->parms[1] = DefineInnerLangString(LS(NLF_DIR_SUBTEXT, NLF_UDIR_SUBTEXT)); + if (!p->parms[2]) + p->parms[2] = DefineInnerLangString(NLF_BTN_BROWSE); + if (!p->parms[3]) + p->parms[3] = DefineInnerLangString(LS(NLF_DIR_BROWSETEXT, NLF_UDIR_BROWSETEXT)); + if (!p->parms[4]) + p->parms[4] = m_UserVarNames.get("INSTDIR"); + else + p->parms[4]--; + + DefineInnerLangString(NLF_SPACE_AVAIL, 0); + DefineInnerLangString(NLF_SPACE_REQ, 0); + DefineInnerLangString(NLF_BYTE, 0); + DefineInnerLangString(NLF_KILO, 0); + DefineInnerLangString(NLF_MEGA, 0); + DefineInnerLangString(NLF_GIGA); +#ifdef NSIS_CONFIG_LOG + DefineInnerLangString(NLF_LOG_INSTALL_PROCESS); +#endif + + dir++; + break; + } + case IDD_INSTFILES: + { + if (!p->parms[1]) + p->parms[1] = DefineInnerLangString(NLF_BTN_DETAILS); + if (!p->parms[2]) + p->parms[2] = DefineInnerLangString(NLF_COMPLETED); + + DefineInnerLangString(NLF_COPY_DETAILS); + + instlog++; + instlog_used++; + break; + } + case IDD_UNINST: + { + if (!p->parms[0]) + p->parms[0] = DefineInnerLangString(NLF_UNINST_TEXT); + if (!p->parms[1]) + p->parms[1] = DefineInnerLangString(NLF_UNINST_SUBTEXT); + if (!p->parms[4]) + p->parms[4] = m_UserVarNames.get("INSTDIR"); + else + p->parms[4]--; + + uninstconfirm++; + break; + } + } + + p->flags &= ~PF_PAGE_EX; + } + + p--; + + if (!p->next) + p->next = DefineInnerLangString(NLF_BTN_CLOSE); + if (p->wndproc_id == PWP_COMPLETED) + (p-1)->next = DefineInnerLangString(NLF_BTN_CLOSE); + +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT + if (uninstall_mode) { + if (!uenable_last_page_cancel && instlog_used) + p->flags &= ~PF_CANCEL_ENABLE; + } + else +#endif + { + if (!enable_last_page_cancel && instlog_used) + p->flags &= ~PF_CANCEL_ENABLE; + } + + if (!instlog_used) { + warning("%sage instfiles not used, no sections will be executed!", uninstall_mode ? "Uninstall p" : "P"); + } + } + +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT + if (!uninstall_mode) { + set_uninstall_mode(1); + goto again; + } + else + set_uninstall_mode(0); +#endif//NSIS_CONFIG_UNINSTALL_SUPPORT + } + + SCRIPT_MSG("Done!\n"); + + try { + SCRIPT_MSG("Removing unused resources... "); + init_res_editor(); +#ifdef NSIS_CONFIG_LICENSEPAGE + if (!license_normal) { + res_editor->UpdateResource(RT_DIALOG, IDD_LICENSE, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); + } + if (!license_fsrb) { + res_editor->UpdateResource(RT_DIALOG, IDD_LICENSE_FSRB, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); + } + if (!license_fscb) { + res_editor->UpdateResource(RT_DIALOG, IDD_LICENSE_FSCB, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); + } +#endif // NSIS_CONFIG_LICENSEPAGE +#ifdef NSIS_CONFIG_COMPONENTPAGE + if (!selcom) { + res_editor->UpdateResource(RT_DIALOG, IDD_SELCOM, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); + res_editor->UpdateResource(RT_BITMAP, IDB_BITMAP1, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); + } +#endif // NSIS_CONFIG_COMPONENTPAGE + if (!dir) { + res_editor->UpdateResource(RT_DIALOG, IDD_DIR, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); + } +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT + if (!uninstconfirm) { + res_editor->UpdateResource(RT_DIALOG, IDD_UNINST, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); + } +#endif // NSIS_CONFIG_UNINSTALL_SUPPORT + if (!instlog) { + res_editor->UpdateResource(RT_DIALOG, IDD_INSTFILES, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); + } + if (!main) { + res_editor->UpdateResource(RT_DIALOG, IDD_INST, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); + if (!build_compress_whole && !build_crcchk) + res_editor->UpdateResource(RT_DIALOG, IDD_VERIFY, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); + } + + SCRIPT_MSG("Done!\n"); + } + catch (exception& err) { + ERROR_MSG("\nError: %s\n", err.what()); + return PS_ERROR; + } + + return PS_OK; +} +#endif // NSIS_CONFIG_VISIBLE_SUPPORT + +#ifdef NSIS_CONFIG_COMPONENTPAGE +void CEXEBuild::PreperInstTypes() +{ + if (!(cur_header->flags & CH_FLAGS_NO_CUSTOM)) + cur_header->install_types[NSIS_MAX_INST_TYPES] = DefineInnerLangString(NLF_COMP_CUSTOM); + + if (cur_header->install_types[0]) + { + int i = cur_header->blocks[NB_SECTIONS].num; + section *sections = (section *) cur_sections->get(); + + while (i--) + if ((sections[i].flags & SF_SELECTED) == 0) + return; + + i = cur_header->blocks[NB_SECTIONS].num; + + while (i--) + if ((sections[i].install_types & 1) == 0) + sections[i].flags &= ~SF_SELECTED; + } +} +#endif + +void CEXEBuild::PreperHeaders(IGrowBuf *hdrbuf) +{ + hdrbuf->add(cur_header,sizeof(header)); +#ifdef NSIS_CONFIG_VISIBLE_SUPPORT + cur_header->blocks[NB_PAGES].offset = hdrbuf->getlen(); + hdrbuf->add(cur_pages->get(),cur_pages->getlen()); +#endif + cur_header->blocks[NB_SECTIONS].offset = hdrbuf->getlen(); + hdrbuf->add(cur_sections->get(),cur_sections->getlen()); + cur_header->blocks[NB_ENTRIES].offset = hdrbuf->getlen(); + hdrbuf->add(cur_entries->get(),cur_entries->getlen()); + cur_header->blocks[NB_STRINGS].offset = hdrbuf->getlen(); + hdrbuf->add(cur_strlist->get(),cur_strlist->getlen()); + cur_header->blocks[NB_LANGTABLES].offset = hdrbuf->getlen(); + hdrbuf->add(cur_langtables->get(),cur_langtables->getlen()); + cur_header->blocks[NB_CTLCOLORS].offset = hdrbuf->getlen(); + hdrbuf->add(cur_ctlcolors->get(),cur_ctlcolors->getlen()); + + memcpy(hdrbuf->get(),cur_header,sizeof(header)); +} + +int CEXEBuild::write_output(void) +{ #ifndef NSIS_CONFIG_CRC_SUPPORT build_crcchk=0; #endif @@ -1483,7 +1948,7 @@ int CEXEBuild::write_output(void) return PS_ERROR; } - if (build_cursection || uninstall_mode) + if (build_cursection) { ERROR_MSG("Error: Section left open at EOF\n"); return PS_ERROR; @@ -1495,6 +1960,12 @@ int CEXEBuild::write_output(void) return PS_ERROR; } + if (cur_page) + { + ERROR_MSG("Error: PageEx still open at EOF, cannot proceed\n"); + return 1; + } + // deal with functions, for both install and uninstall modes. if (build_cursection_isfunc) { @@ -1502,12 +1973,20 @@ int CEXEBuild::write_output(void) return 1; } + int err; + #ifdef NSIS_CONFIG_PLUGIN_SUPPORT - int err=add_plugins_dir_initializer(); + err = add_plugins_dir_initializer(); if (err != PS_OK) return err; #endif //NSIS_CONFIG_PLUGIN_SUPPORT +#ifdef NSIS_SUPPORT_VERSION_INFO + err = AddVersionInfo(); + if (err != PS_OK) + return err; +#endif //NSIS_SUPPORT_VERSION_INFO + #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT if (ubuild_entries.getlen()) { @@ -1517,21 +1996,15 @@ int CEXEBuild::write_output(void) } else { - build_uninst.common.flags|=build_header.common.flags&(CH_FLAGS_PROGRESS_COLORED|CH_FLAGS_NO_ROOT_DIR); + build_uninst.flags|=build_header.flags&(CH_FLAGS_PROGRESS_COLORED|CH_FLAGS_NO_ROOT_DIR); set_uninstall_mode(1); - #ifdef NSIS_SUPPORT_CODECALLBACKS - if (resolve_call_int("uninstall callback","un.callbacks",ns_func.find("un.onInit",0),&build_uninst.common.code_onInit)) return PS_ERROR; - if (resolve_call_int("uninstall callback","un.callbacks",ns_func.find("un.onUninstSuccess",0),&build_uninst.common.code_onInstSuccess)) return PS_ERROR; - if (resolve_call_int("uninstall callback","un.callbacks",ns_func.find("un.onUninstFailed",0),&build_uninst.common.code_onInstFailed)) return PS_ERROR; - if (resolve_call_int("uninstall callback","un.callbacks",ns_func.find("un.onUserAbort",0),&build_uninst.common.code_onUserAbort)) return PS_ERROR; - #ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT - if (resolve_call_int("uninstall callback","un.callbacks",ns_func.find("un.onGUIInit",0),&build_uninst.common.code_onGUIInit)) return PS_ERROR; - if (resolve_call_int("uninstall callback","un.callbacks",ns_func.find("un.onGUIEnd",0),&build_uninst.common.code_onGUIEnd)) return PS_ERROR; - #endif - #endif//NSIS_SUPPORT_CODECALLBACKS - - if (resolve_coderefs("uninstall")) return PS_ERROR; + if (resolve_coderefs("uninstall")) + return PS_ERROR; +#ifdef NSIS_CONFIG_VISIBLE_SUPPORT + // set sections to the first insttype + PreperInstTypes(); +#endif set_uninstall_mode(0); } } @@ -1542,321 +2015,27 @@ int CEXEBuild::write_output(void) } #endif - -#ifdef NSIS_SUPPORT_CODECALLBACKS - if (resolve_call_int("install callback",".callbacks",ns_func.find(".onInit",0),&build_header.common.code_onInit)) return PS_ERROR; - if (resolve_call_int("install callback",".callbacks",ns_func.find(".onInstSuccess",0),&build_header.common.code_onInstSuccess)) return PS_ERROR; - if (resolve_call_int("install callback",".callbacks",ns_func.find(".onInstFailed",0),&build_header.common.code_onInstFailed)) return PS_ERROR; - if (resolve_call_int("install callback",".callbacks",ns_func.find(".onUserAbort",0),&build_header.common.code_onUserAbort)) return PS_ERROR; - if (resolve_call_int("install callback",".callbacks",ns_func.find(".onVerifyInstDir",0),&build_header.code_onVerifyInstDir)) return PS_ERROR; - #ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT - if (resolve_call_int("install callback",".callbacks",ns_func.find(".onGUIInit",0),&build_header.common.code_onGUIInit)) return PS_ERROR; - if (resolve_call_int("install callback",".callbacks",ns_func.find(".onGUIEnd",0),&build_header.common.code_onGUIEnd)) return PS_ERROR; - if (resolve_call_int("install callback",".callbacks",ns_func.find(".onMouseOverSection",0),&build_header.code_onMouseOverSection)) return PS_ERROR; - #endif -#ifdef NSIS_CONFIG_COMPONENTPAGE - if (resolve_call_int("install callback",".callbacks",ns_func.find(".onSelChange",0),&build_header.code_onSelChange)) return PS_ERROR; -#endif//NSIS_CONFIG_COMPONENTPAGE -#endif//NSIS_SUPPORT_CODECALLBACKS - - if (resolve_coderefs("install")) return PS_ERROR; - - // set sections to the first insttype - if (use_first_insttype && build_header.install_types[0]) - { - int n = build_sections.getlen()/sizeof(section); - section *sections = (section *) build_sections.get(); - for (int i = 0; i < n; i++) - { - if ((sections[i].install_types & 1) == 0) - sections[i].flags &= ~SF_SELECTED; - } - } + if (resolve_coderefs("install")) + return PS_ERROR; #ifdef NSIS_CONFIG_VISIBLE_SUPPORT - { - SCRIPT_MSG("Processing pages... "); - page pg = { - 0, -#ifdef NSIS_SUPPORT_CODECALLBACKS - -1, - -1, - -1, -#endif - 0 - }; - int add_pages=!build_pages.getlen(); - int add_uninst_pages=!ubuild_pages.getlen(); - - int license=0; - int selcom=0; - int dir=0; - int uninst=0; - int instlog=0; - int main=2; - -#ifdef NSIS_CONFIG_SILENT_SUPPORT - if (!(build_header.common.flags&(CH_FLAGS_SILENT|CH_FLAGS_SILENT_LOG))) -#endif - { -#ifdef NSIS_CONFIG_LICENSEPAGE - if (!IsNotSet(installer.licensedata)) license++; -#endif -#ifdef NSIS_CONFIG_COMPONENTPAGE - if (!IsNotSet(installer.componenttext)) selcom++; -#endif - if (!IsNotSet(installer.text)) dir++; - - if (!add_pages) { - int i=0; - page *p=(page *) build_pages.get(); - while (i!=build_header.common.num_pages) { - switch (p->id) { -#ifdef NSIS_CONFIG_LICENSEPAGE - case NSIS_PAGE_LICENSE: - license++; - break; -#endif -#ifdef NSIS_CONFIG_COMPONENTPAGE - case NSIS_PAGE_SELCOM: - selcom++; - break; -#endif - case NSIS_PAGE_DIR: - dir++; - break; - case NSIS_PAGE_INSTFILES: - instlog++; - break; - } - p++; - i++; - } - - if (license==1) { - ERROR_MSG("\nError: %s page and %s depend on each other, both must be in the script!\n", "license", "LicenseData"); - return PS_ERROR; - } - if (selcom==1) { - ERROR_MSG("\nError: %s page and %s depend on each other, both must be in the script!\n", "components", "ComponentText"); - return PS_ERROR; - } - if (dir==1) { - ERROR_MSG("\nError: %s page and %s depend on each other, both must be in the script!\n", "directory selection", "DirText"); - return PS_ERROR; - } - if (!instlog) { - warning("Page instfiles not specefied, no sections will be executed!"); - } - } - else { -#ifdef NSIS_CONFIG_LICENSEPAGE - if (license) { - pg.id=NSIS_PAGE_LICENSE; - pg.caption=LANG_SUBCAPTION(0); - build_pages.add(&pg,sizeof(page)); - build_header.common.num_pages++; - } -#endif -#ifdef NSIS_CONFIG_COMPONENTPAGE - if (selcom) { - pg.id=NSIS_PAGE_SELCOM; - pg.caption=LANG_SUBCAPTION(1); - build_pages.add(&pg,sizeof(page)); - build_header.common.num_pages++; - } -#endif - if (dir) { - pg.id=NSIS_PAGE_DIR; - pg.caption=LANG_SUBCAPTION(2); - build_pages.add(&pg,sizeof(page)); - build_header.common.num_pages++; - } - instlog++; - pg.id=NSIS_PAGE_INSTFILES; - pg.caption=LANG_SUBCAPTION(3); - build_pages.add(&pg,sizeof(page)); - build_header.common.num_pages++; - pg.id=NSIS_PAGE_COMPLETED; - pg.caption=LANG_SUBCAPTION(4); - build_pages.add(&pg,sizeof(page)); - build_header.common.num_pages++; - } - - page *p=(page *) build_pages.get(); - for (int i=0; ibutton_states=SW_SHOWNA|2|4; - else p->button_states=4; - - p->next=LANG_BTN_NEXT; - - if (iid==NSIS_PAGE_INSTFILES) { - p->next=LANG_BTN_INSTALL; - install_used = true; - } - #ifdef NSIS_CONFIG_LICENSEPAGE - if (p->id==NSIS_PAGE_LICENSE) { - if (build_header.common.flags&CH_FLAGS_LICENSE_FORCE_SELECTION) - p->button_states|=16; - else - p->next=LANG_BTN_LICENSE; - } - #endif - if (p->id==NSIS_PAGE_INSTFILES || p->id==NSIS_PAGE_COMPLETED) - p->button_states&=~6; - if (i && (p-1)->id==NSIS_PAGE_COMPLETED) - p->button_states&=~2; - - if (p->next == LANG_BTN_NEXT) next_used = true; - } - (--p)->next=LANG_BTN_CLOSE; - if (!enable_last_page_cancel && instlog) { - p->button_states&=~4; - } - if (p->id==NSIS_PAGE_COMPLETED) (--p)->next=LANG_BTN_CLOSE; - } -#ifdef NSIS_CONFIG_SILENT_SUPPORT - else main--; + // set sections to the first insttype + PreperInstTypes(); #endif -#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT -#ifdef NSIS_CONFIG_SILENT_SUPPORT - if (!(build_header.common.flags&(CH_FLAGS_SILENT|CH_FLAGS_SILENT_LOG)) && uninstaller_writes_used) -#endif - { - if (!IsNotSet(uninstall.uninstalltext)) uninst++; - - int uninstlog = 0; - - if (!add_uninst_pages) { - int i=0; - page *p=(page *) ubuild_pages.get(); - while (i!=build_header.common.num_pages) { - switch (p->id) { -#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT - case NSIS_PAGE_UNINST: - uninst++; - break; -#endif - case NSIS_PAGE_INSTFILES: - instlog++; - uninstlog++; - break; - } - p++; - i++; - } - - if (uninst==1) { - ERROR_MSG("\nError: %s page and %s depend on each other, both must be in the script!\n", "uninstConfirm", "UninstallText"); - return PS_ERROR; - } - if (!instlog) { - warning("UninstPage instfiles not specefied, no sections will be executed!"); - } - } - else { - if (uninst) { - pg.id=NSIS_PAGE_UNINST; - pg.caption=LANG_SUBCAPTION(0); - ubuild_pages.add(&pg,sizeof(page)); - build_uninst.common.num_pages++; - } - instlog++; - pg.id=NSIS_PAGE_INSTFILES; - pg.caption=LANG_SUBCAPTION(1); - ubuild_pages.add(&pg,sizeof(page)); - build_uninst.common.num_pages++; - pg.id=NSIS_PAGE_COMPLETED; - pg.caption=LANG_SUBCAPTION(2); - ubuild_pages.add(&pg,sizeof(page)); - build_uninst.common.num_pages++; - } - - page *p=(page *) ubuild_pages.get(); - int noinstlogback=0; - for (int i=0; ibutton_states=SW_SHOWNA|2|4; - else p->button_states=4; - - p->next=LANG_BTN_NEXT; - - if (iid==NSIS_PAGE_INSTFILES) { - if (p->id==NSIS_PAGE_UNINST) - noinstlogback=1; - p->next=LANG_BTN_UNINST; - } - if (p->id==NSIS_PAGE_INSTFILES || p->id==NSIS_PAGE_COMPLETED) - p->button_states=noinstlogback?0:SW_SHOWNA; - if (i && (p-1)->id==NSIS_PAGE_COMPLETED) - p->button_states&=~2; - - if (p->next == LANG_BTN_NEXT) next_used = true; - } - (--p)->next=LANG_BTN_CLOSE; - if (!uenable_last_page_cancel && uninstlog) { - p->button_states&=~4; - } - if (p->id==NSIS_PAGE_COMPLETED) (--p)->next=LANG_BTN_CLOSE; - } -#ifdef NSIS_CONFIG_SILENT_SUPPORT - else -#endif -#endif - main--; - - SCRIPT_MSG("Done!\n"); - - try { - SCRIPT_MSG("Removing unused resources... "); - init_res_editor(); -#ifdef NSIS_CONFIG_LICENSEPAGE - if (!license) { - res_editor->UpdateResource(RT_DIALOG, IDD_LICENSE, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); - } -#endif // NSIS_CONFIG_LICENSEPAGE -#ifdef NSIS_CONFIG_COMPONENTPAGE - if (!selcom) { - res_editor->UpdateResource(RT_DIALOG, IDD_SELCOM, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); - res_editor->UpdateResource(RT_BITMAP, IDB_BITMAP1, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); - } -#endif // NSIS_CONFIG_COMPONENTPAGE - if (!dir) { - res_editor->UpdateResource(RT_DIALOG, IDD_DIR, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); - } -#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT - if (!uninst) { - res_editor->UpdateResource(RT_DIALOG, IDD_UNINST, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); - } -#endif // NSIS_CONFIG_UNINSTALL_SUPPORT - if (!instlog) { - res_editor->UpdateResource(RT_DIALOG, IDD_INSTFILES, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); - } - if (!main) { - res_editor->UpdateResource(RT_DIALOG, IDD_INST, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); - if (!build_compress_whole && !build_crcchk) - res_editor->UpdateResource(RT_DIALOG, IDD_VERIFY, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); - } - - SCRIPT_MSG("Done!\n"); - } - catch (exception& err) { - ERROR_MSG("\nError: %s\n", err.what()); - return PS_ERROR; - } - } -#endif // NSIS_CONFIG_VISIBLE_SUPPORT +#ifdef NSIS_CONFIG_VISIBLE_SUPPORT + err = ProcessPages(); + if (err != PS_OK) + return err; +#endif //NSIS_CONFIG_VISIBLE_SUPPORT // Generate language tables - if (WriteStringTables() == PS_ERROR) return PS_ERROR; + err = GenerateLangTables(); + if (err != PS_OK) + return err; #ifdef NSIS_SUPPORT_NAMED_USERVARS + init_res_editor(); VerifyDeclaredUserVarRefs(&m_UserVarNames); int MaxUserVars = m_UserVarNames.getnum(); if (!res_editor->AddExtraVirtualSize2PESection(VARS_SECTION_NAME, (MaxUserVars-TOTAL_COMPATIBLE_STATIC_VARS_COUNT) * sizeof(NSIS_STRING))) @@ -1901,8 +2080,6 @@ int CEXEBuild::write_output(void) } fseek(tmpfile,0,SEEK_END); exeheader_size_new=ftell(tmpfile); - exeheader_size_new+=511; - exeheader_size_new&=~511; // align to 512. fseek(tmpfile,0,SEEK_SET); unsigned char *header_data_older=header_data_new; header_data_new=(unsigned char *)malloc(exeheader_size_new); @@ -1964,6 +2141,7 @@ int CEXEBuild::write_output(void) fclose(fp); return PS_ERROR; } + #ifdef NSIS_CONFIG_CRC_SUPPORT #ifdef NSIS_CONFIG_CRC_ANAL crc=CRC32(crc,header_data_new,exeheader_size_new); @@ -1972,6 +2150,23 @@ int CEXEBuild::write_output(void) #endif #endif + int exeheader_size_new_aligned = (exeheader_size_new + 511) & ~511; + if (exeheader_size_new_aligned != exeheader_size_new) { + // align to 512 + const unsigned char z = 0; + int write_size = exeheader_size_new_aligned - exeheader_size_new; + for (int i=0; i= 0 && m_UserVarNames.get_reference(idxUserVar) >= 0) { - int idxUserVar = m_UserVarNames.get((char *)p+1); - if ( idxUserVar >= 0 ) - { - m_UserVarNames.inc_reference(idxUserVar); - return idxUserVar; - } + m_UserVarNames.inc_reference(idxUserVar); + return idxUserVar; } - return -1; - + } + return -1; #else - static const char *usrvars="$0\0$1\0$2\0$3\0$4\0$5\0$6\0$7\0$8\0$9\0" "$R0\0$R1\0$R2\0$R3\0$R4\0$R5\0$R6\0$R7\0$R8\0$R9\0" "$CMDLINE\0$INSTDIR\0$OUTDIR\0$EXEDIR\0$LANGUAGE\0"; diff --git a/Source/build.h b/Source/build.h index 17a27367..8bc5a379 100644 --- a/Source/build.h +++ b/Source/build.h @@ -1,8 +1,7 @@ #ifndef _BUILD_H_ #define _BUILD_H_ -#include -#include +#include using namespace std; #include "strlist.h" @@ -43,12 +42,8 @@ extern "C" #define PS_OK 0 #define PS_EOF 1 -#define PS_ENDIF 2 -#define PS_ELSE 3 -#define PS_ELSE_IF0 4 -#define PS_ELSE_IF1 5 #define PS_ERROR 50 -#define IS_PS_ELSE(x) (( x ) >= PS_ELSE && ( x ) <= PS_ELSE_IF1) +#define PS_WARNING 100 enum { MAKENSIS_NOTIFY_SCRIPT, @@ -57,6 +52,14 @@ enum { MAKENSIS_NOTIFY_OUTPUT }; +#define PAGE_CUSTOM 0 +#define PAGE_LICENSE 1 +#define PAGE_COMPONENTS 2 +#define PAGE_DIRECTORY 3 +#define PAGE_INSTFILES 4 +#define PAGE_UNINSTCONFIRM 5 +#define PAGE_COMPLETED 6 + class CEXEBuild { public: CEXEBuild(); @@ -64,6 +67,8 @@ class CEXEBuild { // to add a warning to the compiler's warning list. void warning(const char *s, ...); + // warning with file name and line count + void warning_fl(const char *s, ...); // to add a defined thing. void define(const char *p, const char *v=""); @@ -125,6 +130,27 @@ class CEXEBuild { int do_add_file(const char *lgss, int attrib, int recurse, int linecnt, int *total_files, const char *name_override=0, int generatecode=1, int *data_handle=0, int rec_depth=0); GrowBuf m_linebuild; // used for concatenating lines + // used by doParse to do preprocessing + struct ifblock + { + int hasexeced; + int elseused; + int ignore; + int inherited_ignore; + } *cur_ifblock; + + TinyGrowBuf build_preprocessor_data; + int last_line_had_slash; + + void start_ifblock(); + void end_ifblock(); + int num_ifblock(); + /*int ignore; + int if_count; + int ignored_if_count; + int wait_for_endif;*/ + bool inside_comment; + void ERROR_MSG(const char *s, ...); void SCRIPT_MSG(const char *s, ...); void INFO_MSG(const char *s, ...); @@ -142,21 +168,22 @@ class CEXEBuild { void section_add_size_kb(int kb); int section_add_flags(int flags); int section_add_install_type(int inst_type); + int add_page(int type); + int page_end(); int add_label(const char *name); int add_entry(const entry *ent); - int add_entry_direct(int which, int o0=0, int o1=0, int o2=0, int o3=0, int o4=0, int o5=0); + int add_entry_indirect(int which, int o0=0, int o1=0, int o2=0, int o3=0, int o4=0, int o5=0); int add_data(const char *data, int length, IGrowBuf *dblock=NULL); // returns offset - int add_string(const char *string); // returns offset (in string table) + int add_string(const char *string, int process=1); // returns offset (in string table) int add_intstring(const int i); // returns offset in stringblock - int add_string_main(const char *string, int process=1); // returns offset (in string table) - int add_string_uninst(const char *string, int process=1); // returns offset (in string table) + #ifdef NSIS_SUPPORT_LANG_IN_STRINGS int preprocess_string(char *out, const char *in, bool bUninstall); #else int preprocess_string(char *out, const char *in); #endif - int make_sure_not_in_secorfunc(const char *str); + int make_sure_not_in_secorfunc(const char *str, int page_ok=0); #ifdef NSIS_CONFIG_PLUGIN_SUPPORT // Added by Ximon Eighteen 5th August 2002 @@ -171,6 +198,11 @@ class CEXEBuild { void printline(int l); int process_jump(LineParser &line, int wt, int *offs); + int AddVersionInfo(); + int ProcessPages(); + void PreperInstTypes(); + void PreperHeaders(IGrowBuf *hdrbuf); + int resolve_jump_int(const char *fn, int *a, int offs, int start, int end); int resolve_call_int(const char *fn, const char *str, int fptr, int *ofs); int resolve_instruction(const char *fn, const char *str, entry *w, int offs, int start, int end); @@ -180,27 +212,44 @@ class CEXEBuild { int uninstall_generate(); void set_uninstall_mode(int un); - // lang.cpp functions and vars - StringTable *GetTable(LANGID &lang); - int SetString(char *string, int id, int process, LANGID lang=0); - int SetString(char *string, int id, int process, StringTable *table); - int GetUserString(char *name); - int SetUserString(char *name, LANGID lang, char *string, int process=1); - int WriteStringTables(); - void FillStringTable(StringTable *table, NLF *nlf=0); - #define IsNotSet(s) _IsNotSet(string_tables.size()?&(string_tables[0]->s):0) - bool _IsNotSet(int *str); // Checks if a string is not set in all of the string tables - #define IsSet(s,lang) _IsSet(string_tables.size()?&(string_tables[0]->s):0,lang) - bool _IsSet(int *str, LANGID lang); // Checks if a string is set in a given string table + // lang.cpp functions and variables + void InitLangTables(); + LanguageTable *GetLangTable(LANGID &lang); + int DefineLangString(char *name, int process=-1); + int DefineInnerLangString(int id, int process=-1); + int SetLangString(char *name, LANGID lang, char *string); + int SetInnerString(int id, char *string); + int GenerateLangTables(); + void FillLanguageTable(LanguageTable *table); + int HasUserDefined(int id) { + const char *us = UserInnerStrings.get(id); + return us && *us; + }; + + LanguageTable *LoadLangFile(char *filename); + void DeleteLangTable(LanguageTable *table); + + NLFRef NLFRefs[NLF_STRINGS]; + bool keep_ref; + StringsArray UserInnerStrings; + bool defcodepage_set; + GrowBuf lang_tables; + LANGID last_used_lang; + LangStringList build_langstrings; + int build_langstring_num, ubuild_langstring_num; unsigned int uDefCodePage; - bool next_used, install_used, comppage_used, license_force_radio_used, register_used, unregister_used; + // pages stuff + int license_res_id; + page *cur_page; + int cur_page_type; + int enable_last_page_cancel, uenable_last_page_cancel; + // User variables stuff int GetUserVarIndex(LineParser &line, int token); // Added by ramon 3 jun 2003 #ifdef NSIS_SUPPORT_NAMED_USERVARS - bool b_abort_compile; UserVarsStringList m_UserVarNames; int DeclaredUserVar(const char *VarName); void VerifyDeclaredUserVarRefs(UserVarsStringList *pVarsStringList); @@ -216,12 +265,6 @@ class CEXEBuild { bool build_compressor_set; bool build_compress_whole; - bool use_first_insttype; - - vector build_nlfs; - vector string_tables; - LANGID last_used_lang; - bool no_space_texts; int has_called_write_output; @@ -231,14 +274,12 @@ class CEXEBuild { build_datesave, build_optimize_datablock, build_allowskipfiles; // Added by ramon 23 May 2003 - header build_header; + header build_header, build_uninst, *cur_header; int uninstall_mode; - uninstall_header build_uninst; int uninstall_size,uninstall_size_full; int uninstaller_writes_used; char build_output_filename[1024]; - char cur_out_path[1024]; // Added by ramon 6 jun 2003 #ifdef NSIS_SUPPORT_VERSION_INFO @@ -262,21 +303,19 @@ class CEXEBuild { int build_cursection_isfunc; section *build_cursection; - TinyGrowBuf build_sections; + TinyGrowBuf build_sections, ubuild_sections, *cur_sections; GrowBuf build_entries,ubuild_entries, *cur_entries; TinyGrowBuf build_functions, ubuild_functions, *cur_functions; TinyGrowBuf build_labels, ubuild_labels, *cur_labels; - StringList build_strlist, ubuild_strlist; - GrowBuf build_langtables, ubuild_langtables; - LangStringList build_userlangstrings, ubuild_userlangstrings; - TinyGrowBuf build_pages, ubuild_pages; - - char build_last_page_define[1024], ubuild_last_page_define[1024]; - int build_custom_used, ubuild_custom_used; - int enable_last_page_cancel, uenable_last_page_cancel; + StringList build_strlist, ubuild_strlist, *cur_strlist; + GrowBuf build_langtables, ubuild_langtables, *cur_langtables; + TinyGrowBuf build_pages, ubuild_pages, *cur_pages; + TinyGrowBuf build_ctlcolors, ubuild_ctlcolors, *cur_ctlcolors; MMapBuf build_datablock, ubuild_datablock; // use GrowBuf here instead of MMapBuf if you want - IGrowBuf *cur_datablock; + IGrowBuf *cur_datablock; + + TinyGrowBuf verbose_stack; unsigned char *header_data_new; int exeheader_size_new; diff --git a/Source/exedata.cpp b/Source/exedata.cpp index 7d2b0933..fd271e6e 100644 --- a/Source/exedata.cpp +++ b/Source/exedata.cpp @@ -1,5 +1,6 @@ #include "exedata.h" +//#ifndef _DEBUG #ifdef NSIS_CONFIG_COMPONENTPAGE #include "exehead/Release-zlib/bitmap1.h" #endif @@ -7,11 +8,19 @@ #include "exehead/Release-zlib/unicon.h" #include "exehead/Release-zlib/exehead_zlib.h" #include "exehead/Release-bzip2/exehead_bzip2.h" -// Changed by Amir Szekely 31st July 2002 +/*#else +#ifdef NSIS_CONFIG_COMPONENTPAGE +#include "exehead/Debug-zlib/bitmap1.h" +#endif +#include "exehead/Debug-zlib/icon.h" +#include "exehead/Debug-zlib/unicon.h" +#include "exehead/Debug-zlib/exehead_zlib.h" +#include "exehead/Debug-bzip2/exehead_bzip2.h" +#endif*/ + int zlib_exeheader_size=sizeof(zlib_header_data); int bzip2_exeheader_size=sizeof(bzip2_header_data); int exeheader_size=0; -// Changed by Amir Szekely 8th July 2002 int icondata_size=sizeof(icon_data)-22; int unicondata_size=sizeof(unicon_data)-22; diff --git a/Source/exehead/Main.c b/Source/exehead/Main.c index 9fa8bb10..e2072bd5 100644 --- a/Source/exehead/Main.c +++ b/Source/exehead/Main.c @@ -26,6 +26,7 @@ #include #include +#include #include "resource.h" #include "util.h" #include "fileform.h" @@ -58,6 +59,13 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,LPSTR lpszCmdParam, InitCommonControls(); +#if defined(NSIS_SUPPORT_ACTIVEXREG) || defined(NSIS_SUPPORT_CREATESHORTCUT) + { + extern HRESULT g_hres; + g_hres=OleInitialize(NULL); + } +#endif + GetTempPath(sizeof(state_temp_dir), state_temp_dir); validate_filename(state_temp_dir); CreateDirectory(state_temp_dir, NULL); @@ -127,7 +135,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,LPSTR lpszCmdParam, while (*p) p++; while (p >= cmdline && (p[0] != '_' || p[1] != '?' || p[2] != '=')) p--; - + if (p >= cmdline) { *(p-1)=0; // terminate before the " _?=" @@ -200,6 +208,11 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,LPSTR lpszCmdParam, log_write(1); #endif//NSIS_CONFIG_LOG end: + +#if defined(NSIS_SUPPORT_ACTIVEXREG) || defined(NSIS_SUPPORT_CREATESHORTCUT) + OleUninitialize(); +#endif + if (g_db_hFile != INVALID_HANDLE_VALUE) CloseHandle(g_db_hFile); #ifdef NSIS_COMPRESS_WHOLE if (dbd_hFile != INVALID_HANDLE_VALUE) CloseHandle(dbd_hFile); diff --git a/Source/exehead/Ui.c b/Source/exehead/Ui.c index 75501de2..72ac7871 100644 --- a/Source/exehead/Ui.c +++ b/Source/exehead/Ui.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include "resource.h" @@ -40,9 +39,6 @@ HICON g_hIcon; -// Added by Amir Szekely 3rd August 2002 -char *language_tables; -int *cur_language_table; int dlg_offset; int g_quit_flag; // set when Quit has been called (meaning bail out ASAP) @@ -52,15 +48,11 @@ int g_quit_flag; // set when Quit has been called (meaning bail out ASAP) #endif int progress_bar_pos, progress_bar_len; -int g_is_uninstaller; - -HWND g_progresswnd; static char g_tmp[4096]; -int num_sections; - static int m_page=-1,m_retcode,m_delta=1; +static page *g_this_page; #define NOTIFY_BYE_BYE 'x' @@ -85,17 +77,12 @@ static BOOL CALLBACK UninstProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l static DWORD WINAPI install_thread(LPVOID p); -HWND insthwnd, insthwnd2,insthwndbutton; - -void *g_inst_combinedheader; -page *g_inst_page; -section *g_inst_section; -entry *g_inst_entry; +HWND insthwnd, insthwnd2, insthwndbutton; static HWND m_curwnd, m_bgwnd, m_hwndOK, m_hwndCancel; static BOOL NSISCALL SetDlgItemTextFromLang_(HWND dlg, int id, int lid) { - return my_SetDialogItemText(dlg,id+1000,LANG_STR(lid)); + return my_SetDialogItemText(dlg,id+1000,GetNSISStringTT(lid)); } #define SetDlgItemTextFromLang(dlg,id,lid) SetDlgItemTextFromLang_(dlg,(id)-1000,lid) @@ -114,16 +101,17 @@ static BOOL NSISCALL _HandleStaticBkColor(UINT uMsg, WPARAM wParam, LPARAM lPara case WM_CTLCOLORDLG: case WM_CTLCOLORBTN: { - BOOL brush = (BOOL)GetWindowLong((HWND)lParam, GWL_USERDATA); - if (!brush) return 0; - if (brush == -1) { - COLORREF dlgColor = GetSysColor(COLOR_BTNFACE); - SetBkColor((HDC)wParam, dlgColor); - SetTextColor((HDC)wParam, dlgColor); - return (BOOL)GetStockObject(NULL_BRUSH); + ctlcolors *c = (ctlcolors *)GetWindowLong((HWND)lParam, GWL_USERDATA); + + if (c) { + SetBkMode((HDC)wParam, c->bkmode); + if (c->flags & CC_BK) + SetBkColor((HDC)wParam, c->bk.lbColor); + if (c->flags & CC_TEXT) + SetTextColor((HDC)wParam, c->text); + + return (BOOL)c->bkb; } - SetBkMode((HDC)wParam, TRANSPARENT); - return brush; } } return 0; @@ -139,24 +127,26 @@ void NSISCALL build_g_logfile() } #endif +int *cur_langtable; + static void NSISCALL set_language() { - int i; LANGID lang_mask=(LANGID)~0; - LANGID lang=myatoi(state_language); + LANGID lang=state_language[0]?myatoi(state_language):GetUserDefaultLangID(); char *language_table=0; - int lang_num=g_inst_cmnheader->language_tables_num; + int lang_num; lang_again: - for (i = 0; i < lang_num; i++) { - language_table=language_tables+i*g_inst_cmnheader->language_table_size; + lang_num=g_blocks[NB_LANGTABLES].num; + while (lang_num--) { + language_table=((char*)g_blocks[NB_LANGTABLES].offset)+lang_num*g_header->langtable_size; if (!((lang ^ *(LANGID*)language_table) & lang_mask)) { dlg_offset=*(int*)(language_table+sizeof(LANGID)); - cur_language_table=(int*)(language_table+sizeof(LANGID)+sizeof(int)); + cur_langtable=(int*)(language_table+sizeof(LANGID)+sizeof(int)); break; } } - if (i == lang_num) { + if (!cur_langtable) { if (lang_mask == (LANGID)~0) lang_mask=0x3ff; // primary lang else // we already tried once and we still don't have a language table @@ -165,117 +155,122 @@ lang_again: } myitoa(state_language, *(LANGID*)language_table); -#ifdef NSIS_CONFIG_VISIBLE_SUPPORT - my_SetWindowText(m_bgwnd,process_string_fromtab(g_caption,LANG_CAPTION)); + { + char *caption = GetNSISString(g_caption,LANG_CAPTION); +#ifdef NSIS_SUPPORT_BGBG + my_SetWindowText(m_bgwnd, caption); #endif + } } int NSISCALL ui_doinstall(void) { - common_header *inst_cmnheader=g_inst_cmnheader; + header *header = g_header; static WNDCLASS wc; // richedit subclassing and bgbg creation - g_flags.autoclose=inst_flags&CH_FLAGS_AUTO_CLOSE; -#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT - if (!g_is_uninstaller) -#endif - { - if (!is_valid_instpath(state_install_directory)) - { - if (g_inst_header->install_reg_key_ptr) - { - myRegGetStr((HKEY)g_inst_header->install_reg_rootkey, - GetStringFromStringTab(g_inst_header->install_reg_key_ptr), - GetStringFromStringTab(g_inst_header->install_reg_value_ptr),ps_tmpbuf); - if (ps_tmpbuf[0]) - { - char *p=ps_tmpbuf; - char *e; - if (p[0]=='\"') - { - char *p2=CharNext(p); - p=p2; - while (*p2 && *p2 != '\"') p2=CharNext(p2); - *p2=0; - } - // p is the path now, check for .exe extension + g_exec_flags.autoclose=g_flags&CH_FLAGS_AUTO_CLOSE; - e=p+mystrlen(p)-4; - if (e > p) + if (!is_valid_instpath(state_install_directory)) + { + if (header->install_reg_key_ptr) + { + myRegGetStr((HKEY)header->install_reg_rootkey, + GetNSISStringNP(header->install_reg_key_ptr), + GetNSISStringNP(header->install_reg_value_ptr),ps_tmpbuf); + if (ps_tmpbuf[0]) + { + char *p=ps_tmpbuf; + char *e; + if (p[0]=='\"') + { + char *p2=CharNext(p); + p=p2; + while (*p2 && *p2 != '\"') p2=CharNext(p2); + *p2=0; + } + // p is the path now, check for .exe extension + + e=p+mystrlen(p)-4; + if (e > p) + { + // if filename ends in .exe, and is not a directory, remove the filename + if (*(int*)e == *(int*)".exe") // check extension { - // if filename ends in .exe, and is not a directory, remove the filename - if (!lstrcmpi(e,".exe")) // check extension + DWORD d; + d=GetFileAttributes(p); + if (d == (DWORD)-1 || !(d&FILE_ATTRIBUTE_DIRECTORY)) { - DWORD d; - d=GetFileAttributes(p); - if (d == (DWORD)-1 || !(d&FILE_ATTRIBUTE_DIRECTORY)) - { - e=scanendslash(p); - if (e>=p) *e=0; - } + e=scanendslash(p); + if (e>=p) *e=0; } } - - mystrcpy(state_install_directory,p); } + + mystrcpy(state_install_directory,p); } } - if (!is_valid_instpath(state_install_directory)) - { - process_string_fromtab(state_install_directory,g_inst_header->install_directory_ptr); - } + } + if (!is_valid_instpath(state_install_directory)) + { + GetNSISString(state_install_directory,header->install_directory_ptr); + } #ifdef NSIS_CONFIG_LOG - if (inst_flags&CH_FLAGS_SILENT_LOG) - { - build_g_logfile(); - log_dolog=1; - } -#endif - } - - // Added by Amir Szekely 3rd August 2002 - // Multilingual support + if (g_flags & CH_FLAGS_SILENT_LOG && !g_is_uninstaller) { - extern char *g_db_strtab; - language_tables=(void*)(g_db_strtab+inst_cmnheader->num_string_bytes); - - myitoa(state_language, GetUserDefaultLangID()); - set_language(); + build_g_logfile(); + log_dolog=1; } +#endif + + set_language(); #ifdef NSIS_CONFIG_VISIBLE_SUPPORT + g_hIcon=LoadImage(g_hInstance,MAKEINTRESOURCE(IDI_ICON2),IMAGE_ICON,0,0,LR_DEFAULTSIZE|LR_SHARED); +#ifdef NSIS_SUPPORT_BGBG + if (header->bg_color1 != -1) + { + RECT vp; + extern LRESULT CALLBACK BG_WndProc(HWND, UINT, WPARAM, LPARAM); + wc.lpfnWndProc = BG_WndProc; + wc.hInstance = g_hInstance; + wc.hIcon = g_hIcon; + //wc.hCursor = LoadCursor(NULL,IDC_ARROW); + wc.lpszClassName = "_Nb"; + + if (!RegisterClass(&wc)) return 0; + + SystemParametersInfo(SPI_GETWORKAREA, 0, &vp, 0); + + m_bgwnd = CreateWindowEx(WS_EX_TOOLWINDOW,"_Nb",0,WS_POPUP, + vp.left,vp.top,vp.right-vp.left,vp.bottom-vp.top,0,NULL,g_hInstance,NULL); + } + +#ifdef NSIS_SUPPORT_CODECALLBACKS + g_hwnd=m_bgwnd; +#endif//NSIS_SUPPORT_CODECALLBACKS + +#endif//NSIS_SUPPORT_BGBG + +#endif//NSIS_CONFIG_VISIBLE_SUPPORT + +#ifdef NSIS_SUPPORT_CODECALLBACKS + // Select language + if (ExecuteCodeSegment(header->code_onInit,NULL)) return 1; + set_language(); +#endif + +#ifdef NSIS_CONFIG_VISIBLE_SUPPORT + +#ifdef NSIS_SUPPORT_CODECALLBACKS +#ifdef NSIS_SUPPORT_BGBG + g_hwnd=NULL; +#endif//NSIS_SUPPORT_BGBG +#endif//NSIS_SUPPORT_CODECALLBACKS + #ifdef NSIS_CONFIG_SILENT_SUPPORT - if (!(inst_flags&(CH_FLAGS_SILENT|CH_FLAGS_SILENT_LOG))) + if (!g_exec_flags.silent) #endif//NSIS_CONFIG_SILENT_SUPPORT { - g_hIcon=LoadImage(g_hInstance,MAKEINTRESOURCE(IDI_ICON2),IMAGE_ICON,0,0,LR_DEFAULTSIZE|LR_SHARED); - m_bgwnd=0; -#ifdef NSIS_SUPPORT_BGBG - if (inst_cmnheader->bg_color1 != -1) - { - RECT vp; - extern LRESULT CALLBACK BG_WndProc(HWND, UINT, WPARAM, LPARAM); - wc.lpfnWndProc = BG_WndProc; - wc.hInstance = g_hInstance; - wc.hIcon = g_hIcon; - //wc.hCursor = LoadCursor(NULL,IDC_ARROW); - wc.lpszClassName = "_Nb"; - - if (!RegisterClass(&wc)) return 0; - - SystemParametersInfo(SPI_GETWORKAREA, 0, &vp, 0); - - m_bgwnd = CreateWindowEx(WS_EX_TOOLWINDOW,"_Nb",0,WS_POPUP, - vp.left,vp.top,vp.right-vp.left,vp.bottom-vp.top,0,NULL,g_hInstance,NULL); - } -#endif//NSIS_SUPPORT_BGBG -#ifdef NSIS_SUPPORT_CODECALLBACKS - g_hwnd=m_bgwnd; - // Select language - if (ExecuteCodeSegment(inst_cmnheader->code_onInit,NULL)) return 1; - set_language(); - g_hwnd=NULL; -#endif//NSIS_SUPPORT_CODECALLBACKS #ifdef NSIS_SUPPORT_BGBG ShowWindow(m_bgwnd, SW_SHOW); #endif//NSIS_SUPPORT_BGBG @@ -305,7 +300,7 @@ int NSISCALL ui_doinstall(void) { int ret=DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_INST+dlg_offset),0,DialogProc); #if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT) - ExecuteCodeSegment(g_inst_cmnheader->code_onGUIEnd,NULL); + ExecuteCodeSegment(header->code_onGUIEnd,NULL); #endif return ret; } @@ -314,21 +309,17 @@ int NSISCALL ui_doinstall(void) #ifdef NSIS_CONFIG_SILENT_SUPPORT #ifdef NSIS_CONFIG_VISIBLE_SUPPORT else -#endif +#endif//NSIS_CONFIG_VISIBLE_SUPPORT { -#ifdef NSIS_SUPPORT_CODECALLBACKS - if (ExecuteCodeSegment(inst_cmnheader->code_onInit,NULL)) return 1; - set_language(); -#endif//NSIS_SUPPORT_CODECALLBACKS if (install_thread(NULL)) { #ifdef NSIS_SUPPORT_CODECALLBACKS - if (!g_quit_flag) ExecuteCodeSegment(inst_cmnheader->code_onInstFailed,NULL); + if (!g_quit_flag) ExecuteCodeSegment(header->code_onInstFailed,NULL); #endif//NSIS_SUPPORT_CODECALLBACKS return 1; } #ifdef NSIS_SUPPORT_CODECALLBACKS - ExecuteCodeSegment(inst_cmnheader->code_onInstSuccess,NULL); + ExecuteCodeSegment(header->code_onInstSuccess,NULL); #endif//NSIS_SUPPORT_CODECALLBACKS return 0; @@ -338,7 +329,7 @@ int NSISCALL ui_doinstall(void) #ifdef NSIS_CONFIG_VISIBLE_SUPPORT -static int CALLBACK WINAPI BrowseCallbackProc( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData) +static int CALLBACK WINAPI BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData) { if (uMsg==BFFM_INITIALIZED) { @@ -354,24 +345,18 @@ BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) if (uMsg == WM_INITDIALOG || uMsg == WM_NOTIFY_OUTER_NEXT) { page *this_page; - static struct - { - unsigned int id; - DLGPROC proc; - } - windows[]= + static DLGPROC winprocs[]= { #ifdef NSIS_CONFIG_LICENSEPAGE - {IDD_LICENSE,LicenseProc}, + LicenseProc, #endif #ifdef NSIS_CONFIG_COMPONENTPAGE - {IDD_SELCOM,SelProc}, + SelProc, #endif - {IDD_DIR,DirProc}, - {IDD_INSTFILES,InstProc}, - {0,NULL}, // imaginary completed page + DirProc, + InstProc, #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT - {IDD_UNINST,UninstProc} + UninstProc #endif }; @@ -382,15 +367,13 @@ BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) m_hwndCancel=GetDlgItem(hwndDlg,IDCANCEL); SetDlgItemTextFromLang(hwndDlg,IDC_VERSTR,LANG_BRANDING); SetClassLong(hwndDlg,GCL_HICON,(long)g_hIcon); - SetDlgItemTextFromLang(hwndDlg,IDCANCEL,LANG_BTN_CANCEL); - SetDlgItemTextFromLang(hwndDlg,IDC_BACK,LANG_BTN_BACK); #if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT) - if (!(g_quit_flag = ExecuteCodeSegment(g_inst_cmnheader->code_onGUIInit,NULL))) + if (!(g_quit_flag = ExecuteCodeSegment(g_header->code_onGUIInit,NULL))) #endif ShowWindow(hwndDlg,SW_SHOW); } - this_page=g_inst_page+m_page; + this_page=g_pages+m_page; if (m_page>=0) { #ifdef NSIS_SUPPORT_CODECALLBACKS @@ -402,19 +385,22 @@ BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) // if the last page was a custom page, wait for it to finish by itself. // if it doesn't, it's a BAD plugin. // plugins should react to WM_NOTIFY_OUTER_NEXT. - if (this_page->id<0) return 0; + if (!this_page->dlg_id) return 0; } + SendMessage(m_curwnd, WM_NOTIFY_INIGO_MONTOYA, 0, 0); + nextPage: m_page+=m_delta; this_page+=m_delta; + g_this_page=this_page; #ifdef NSIS_SUPPORT_CODECALLBACKS - if (m_page==g_inst_cmnheader->num_pages) ExecuteCodeSegment(g_inst_cmnheader->code_onInstSuccess,NULL); + if (m_page==g_blocks[NB_PAGES].num) ExecuteCodeSegment(g_header->code_onInstSuccess,NULL); #endif//NSIS_SUPPORT_CODECALLBACKS - if (g_quit_flag || m_page < 0 || m_page == g_inst_cmnheader->num_pages) + if (g_quit_flag || (unsigned int)m_page >= (unsigned int)g_blocks[NB_PAGES].num) { DestroyWindow(m_curwnd); g_hwnd = 0; @@ -424,50 +410,59 @@ nextPage: { HWND hwndtmp; - SetDlgItemTextFromLang(hwndDlg,IDOK,this_page->next); + int pflags = this_page->flags; + + GetNSISString(state_click_next, this_page->clicknext); + SetDlgItemTextFromLang(hwndDlg, IDOK, this_page->next); + SetDlgItemTextFromLang(hwndDlg, IDC_BACK, this_page->back); + SetDlgItemTextFromLang(hwndDlg, IDCANCEL, this_page->cancel); - hwndtmp=GetDlgItem(hwndDlg,IDC_BACK); - if (g_flags.abort) + hwndtmp = GetDlgItem(hwndDlg, IDC_BACK); + if (g_exec_flags.abort) { - this_page->button_states|=16|4; - SendMessage(hwndDlg,DM_SETDEFID,IDCANCEL,0); + pflags &= ~(PF_BACK_ENABLE | PF_NEXT_ENABLE); + pflags |= PF_CANCEL_ENABLE; + SendMessage(hwndDlg, DM_SETDEFID, IDCANCEL, 0); } - else SendMessage(hwndDlg,DM_SETDEFID,IDOK,0); - SetWindowLong(hwndtmp,GWL_STYLE,GetWindowLong(hwndtmp,GWL_STYLE)&~BS_DEFPUSHBUTTON); - ShowWindow(hwndtmp,this_page->button_states&SW_SHOWNA);// SW_HIDE = 0, SW_SHOWNA = 8 - EnableWindow(hwndtmp,this_page->button_states&2); - EnableWindow(m_hwndOK,!(this_page->button_states&16)); - EnableWindow(m_hwndCancel,this_page->button_states&4); + else SendMessage(hwndDlg, DM_SETDEFID, IDOK, 0); + + SetWindowLong(hwndtmp, GWL_STYLE, GetWindowLong(hwndtmp, GWL_STYLE) & ~BS_DEFPUSHBUTTON); + ShowWindow(hwndtmp, pflags & PF_BACK_SHOW);// SW_HIDE = 0, PF_BACK_SHOW = SW_SHOWNA = 8 + EnableWindow(hwndtmp, pflags & PF_BACK_ENABLE); + EnableWindow(m_hwndOK, pflags & PF_NEXT_ENABLE); + EnableWindow(m_hwndCancel, pflags & PF_CANCEL_ENABLE); mystrcpy(g_tmp,g_caption); - process_string_fromtab(g_tmp+mystrlen(g_tmp),this_page->caption); + GetNSISString(g_tmp+mystrlen(g_tmp),this_page->caption); my_SetWindowText(hwndDlg,g_tmp); - SendMessage(m_curwnd, WM_NOTIFY_INIGO_MONTOYA, 0, 0); - #ifdef NSIS_SUPPORT_CODECALLBACKS - if (ExecuteCodeSegment(this_page->prefunc,NULL) || this_page->id<0) + if (ExecuteCodeSegment(this_page->prefunc, NULL) || !this_page->dlg_id) { goto nextPage; + } #endif //NSIS_SUPPORT_CODECALLBACKS - if (this_page->id!=NSIS_PAGE_COMPLETED) DestroyWindow(m_curwnd); + if (this_page->wndproc_id != PWP_COMPLETED) DestroyWindow(m_curwnd); else { - if (g_flags.abort) SetFocus(m_hwndCancel); - else if (g_flags.autoclose) goto nextPage; + if (g_exec_flags.abort) SetFocus(m_hwndCancel); + else if (g_exec_flags.autoclose) goto nextPage; else SetFocus(m_hwndOK); // without focus button, the system Beeps every time user press one key return 0; } - if (this_page->id>=0) // NSIS page + if (this_page->dlg_id > 0) // NSIS page { - m_curwnd=CreateDialog( + m_curwnd=CreateDialogParam( g_hInstance, - MAKEINTRESOURCE(windows[this_page->id].id+dlg_offset), - hwndDlg,windows[this_page->id].proc + MAKEINTRESOURCE(this_page->dlg_id+dlg_offset), + hwndDlg,winprocs[this_page->wndproc_id],(LPARAM)this_page ); if (m_curwnd) { RECT r; + + SetDlgItemTextFromLang(m_curwnd,IDC_INTROTEXT,this_page->parms[0]); + GetWindowRect(GetDlgItem(hwndDlg,IDC_CHILDRECT),&r); ScreenToClient(hwndDlg,(LPPOINT)&r); SetWindowPos(m_curwnd,0,r.left,r.top,0,0,SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER); @@ -475,13 +470,13 @@ nextPage: ExecuteCodeSegment(this_page->showfunc,NULL); #endif //NSIS_SUPPORT_CODECALLBACKS ShowWindow(m_curwnd,SW_SHOWNA); - SendMessage(m_curwnd, WM_NOTIFY_START, 0, 0); + SendMessage(m_curwnd,WM_NOTIFY_START,0,0); } //XGE 5th September 2002 - Do *not* move the focus to the OK button if we are //on the license page, instead we want the focus left alone because in //WM_INITDIALOG it is given to the richedit control. - if (this_page->id != NSIS_PAGE_LICENSE) + if ((pflags & PF_NO_NEXT_FOCUS) == 0) SetFocus(m_hwndOK); //XGE End } @@ -525,10 +520,10 @@ nextPage: } if (id == IDCANCEL) { - if (g_flags.abort) + if (g_exec_flags.abort) { #ifdef NSIS_SUPPORT_CODECALLBACKS - ExecuteCodeSegment(g_inst_cmnheader->code_onInstFailed,NULL); + ExecuteCodeSegment(g_header->code_onInstFailed,NULL); #endif//NSIS_SUPPORT_CODECALLBACKS m_retcode=2; outernotify(NOTIFY_BYE_BYE); @@ -536,7 +531,7 @@ nextPage: else { #ifdef NSIS_SUPPORT_CODECALLBACKS - if (!ExecuteCodeSegment(g_inst_cmnheader->code_onUserAbort,NULL)) + if (!ExecuteCodeSegment(g_header->code_onUserAbort,NULL)) #endif//NSIS_SUPPORT_CODECALLBACKS { m_retcode=1; @@ -567,40 +562,54 @@ DWORD CALLBACK StreamLicense(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb) return 0; } +#define this_page ((page*)lParam) + static BOOL CALLBACK LicenseProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { + page *m_this_page=g_this_page; HWND hwLicense; - static unsigned int uLastAcceptState; + if (uMsg == WM_INITDIALOG) { - EDITSTREAM es={(DWORD)LANG_STR(LANG_LICENSE_DATA),0,StreamLicense}; + char *l = (char *)GetNSISStringNP(GetNSISTab(this_page->parms[1])); + int lt = *l; + EDITSTREAM es = { + (DWORD)(++l), + 0, + StreamLicense + }; - SetUITextFromLang(IDC_LICENSEAGREE,LANG_BTN_LICENSE_AGREE); - SetUITextFromLang(IDC_LICENSEDISAGREE,LANG_BTN_LICENSE_DISAGREE); - SendMessage(GetUIItem(IDC_LICENSEAGREE+!uLastAcceptState), BM_SETCHECK, BST_CHECKED, 0); - EnableWindow(m_hwndOK, uLastAcceptState | !(inst_flags&CH_FLAGS_LICENSE_FORCE_SELECTION)); + int selected = (this_page->flags & PF_LICENSE_SELECTED) | !(this_page->flags & PF_LICENSE_FORCE_SELECTION); + + SetUITextFromLang(IDC_LICENSEAGREE,this_page->parms[2]); + SetUITextFromLang(IDC_LICENSEDISAGREE,this_page->parms[3]); + SendMessage(GetUIItem(IDC_LICENSEAGREE+!selected),BM_SETCHECK,BST_CHECKED,0); + EnableWindow(m_hwndOK,selected); hwLicense=GetUIItem(IDC_EDIT1); SendMessage(hwLicense,EM_AUTOURLDETECT,TRUE,0); -#define lbg g_inst_header->license_bg +#define lbg g_header->license_bg SendMessage(hwLicense,EM_SETBKGNDCOLOR,0,lbg>=0?lbg:GetSysColor(-lbg)); #undef lbg SendMessage(hwLicense,EM_SETEVENTMASK,0,ENM_LINK|ENM_KEYEVENTS); //XGE 8th September 2002 Or'd in ENM_KEYEVENTS dwRead=0; - SendMessage(hwLicense,EM_EXLIMITTEXT,0,mystrlen((char*)es.dwCookie)); - SendMessage(hwLicense,EM_STREAMIN,(((char*)es.dwCookie)[0]=='{')?SF_RTF:SF_TEXT,(LPARAM)&es); - SetUITextFromLang(IDC_INTROTEXT,LANG_LICENSE_TEXT); + SendMessage(hwLicense,EM_EXLIMITTEXT,0,mystrlen(l)); + SendMessage(hwLicense,EM_STREAMIN,lt,(LPARAM)&es); //XGE 5th September 2002 - place the initial focus in the richedit control SetFocus(hwLicense); return FALSE; //End Xge } if (uMsg == WM_COMMAND && HIWORD(wParam) == BN_CLICKED) { - if (inst_flags&CH_FLAGS_LICENSE_FORCE_SELECTION) + if (m_this_page->flags & PF_LICENSE_FORCE_SELECTION) { + int is = SendMessage(GetUIItem(IDC_LICENSEAGREE), BM_GETCHECK, 0, 0) & BST_CHECKED; + m_this_page->flags &= ~PF_LICENSE_SELECTED; + m_this_page->flags |= is; EnableWindow( m_hwndOK, - uLastAcceptState = SendMessage(GetUIItem(IDC_LICENSEAGREE), BM_GETCHECK, 0, 0) & BST_CHECKED + is ); + } } if (uMsg == WM_NOTIFY) { hwLicense=GetUIItem(IDC_EDIT1); @@ -659,9 +668,8 @@ static BOOL CALLBACK UninstProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l { if (uMsg == WM_INITDIALOG) { - SetUITextFromLang(IDC_INTROTEXT,LANG_UNINST_TEXT); - SetUITextFromLang(IDC_UNINSTFROM,LANG_UNINST_SUBTEXT); - SetUITextNT(IDC_EDIT1,state_install_directory); + SetUITextFromLang(IDC_UNINSTFROM,this_page->parms[1]); + SetUITextNT(IDC_EDIT1,g_usrvars[this_page->parms[4]]); } return HandleStaticBkColor(); } @@ -670,22 +678,33 @@ static BOOL CALLBACK UninstProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l static char * NSISCALL inttosizestr(int kb, char *str) { + char scalestr[32], byte[32]; char sh=20; char s=0; int scale=LANG_GIGA; if (kb < 1024) { sh=0; scale=LANG_KILO; } else if (kb < 1024*1024) { sh=10; scale=LANG_MEGA; } else if (GetVersion()&0x80000000) s='+';//only display the + on GB shown on win9x. - wsprintf(str+mystrlen(str),"%d.%d%s%s%c",kb>>sh,((kb*10)>>sh)%10,LANG_STR(scale),LANG_STR(LANG_BYTE),s); + wsprintf( + str+mystrlen(str), + "%d.%d%s%s%c", + kb>>sh, + ((kb*10)>>sh)%10, + GetNSISString(scalestr,scale), + GetNSISString(byte,LANG_BYTE), + s + ); return str; } static BOOL CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { + char *dir = g_usrvars[g_this_page->parms[4]]; + int browse_text = g_this_page->parms[3]; if (uMsg == WM_NOTIFY_INIGO_MONTOYA) { - GetUIText(IDC_DIR,state_install_directory,NSIS_MAX_STRLEN); - validate_filename(state_install_directory); + GetUIText(IDC_DIR,dir,NSIS_MAX_STRLEN); + validate_filename(dir); #ifdef NSIS_CONFIG_LOG build_g_logfile(); log_dolog = IsDlgButtonChecked(hwndDlg,IDC_CHECK1); @@ -697,14 +716,13 @@ static BOOL CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar if (GetAsyncKeyState(VK_SHIFT)&0x8000) { HWND h=GetUIItem(IDC_CHECK1); - my_SetWindowText(h,LANG_STR(LANG_LOG_INSTALL_PROCESS)); + SetUITextFromLang(IDC_CHECK1,LANG_LOG_INSTALL_PROCESS); ShowWindow(h,SW_SHOWNA); } #endif - SetUITextNT(IDC_DIR,state_install_directory); - SetUITextFromLang(IDC_INTROTEXT,LANG_DIR_TEXT); - SetUITextFromLang(IDC_BROWSE,LANG_BTN_BROWSE); - SetUITextFromLang(IDC_SELDIRTEXT,LANG_DIR_SUBTEXT); + SetUITextNT(IDC_DIR,dir); + SetUITextFromLang(IDC_BROWSE,this_page->parms[2]); + SetUITextFromLang(IDC_SELDIRTEXT,this_page->parms[1]); } if (uMsg == WM_COMMAND) { @@ -716,16 +734,15 @@ static BOOL CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar if (id == IDC_BROWSE) { char name[MAX_PATH]; - char str[256]; BROWSEINFO bi={0,}; ITEMIDLIST *idlist; GetUIText(IDC_DIR,name,MAX_PATH); - GetUIText(IDC_SELDIRTEXT,str,256); + //GetUIText(IDC_SELDIRTEXT,str,256); bi.hwndOwner = hwndDlg; bi.pszDisplayName = name; bi.lpfn=BrowseCallbackProc; bi.lParam=(LPARAM)hwndDlg; - bi.lpszTitle=str; + bi.lpszTitle=GetNSISStringTT(browse_text); #ifndef BIF_NEWDIALOGSTYLE #define BIF_NEWDIALOGSTYLE 0x0040 #endif @@ -742,10 +759,10 @@ static BOOL CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar m->lpVtbl->Release(m); } - if (g_inst_header->install_directory_auto_append) + if (g_header->install_directory_auto_append) { const char *p, *post_str=ps_tmpbuf; - process_string_fromtab(0,g_inst_header->install_directory_auto_append); + GetNSISStringTT(g_header->install_directory_auto_append); p=name+mystrlen(name)-mystrlen(post_str); if (p <= name || *CharPrev(name,p)!='\\' || lstrcmpi(p,post_str)) { @@ -765,10 +782,10 @@ static BOOL CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar int total=0, available=-1; DWORD spc,bps,fc,tc; - GetUIText(IDC_DIR,state_install_directory,NSIS_MAX_STRLEN); - is_valid_path=is_valid_instpath(state_install_directory); + GetUIText(IDC_DIR,dir,NSIS_MAX_STRLEN); + is_valid_path=is_valid_instpath(dir); - mystrcpy(s,state_install_directory); + mystrcpy(s,dir); if (s[1] == ':') s[3]=0; else if (*(WORD*)s == CHAR2_TO_WORD('\\','\\')) // \\ path { @@ -789,23 +806,23 @@ static BOOL CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar for (x = 0; x < num_sections; x ++) { #ifdef NSIS_CONFIG_COMPONENTPAGE - if (g_inst_section[x].flags&SF_SELECTED) + if (g_sections[x].flags&SF_SELECTED) #endif - total+=g_inst_section[x].size_kb; + total+=g_sections[x].size_kb; } if (LANG_STR_TAB(LANG_SPACE_REQ)) { - SetUITextNT(IDC_SPACEREQUIRED,inttosizestr(total,mystrcpy(s,LANG_STR(LANG_SPACE_REQ)))); + SetUITextNT(IDC_SPACEREQUIRED,inttosizestr(total,GetNSISString(s,LANG_SPACE_REQ))); if (available != -1) - SetUITextNT(IDC_SPACEAVAILABLE,inttosizestr(available,mystrcpy(s,LANG_STR(LANG_SPACE_AVAIL)))); + SetUITextNT(IDC_SPACEAVAILABLE,inttosizestr(available,GetNSISString(s,LANG_SPACE_AVAIL))); else SetUITextNT(IDC_SPACEAVAILABLE,""); } EnableWindow(m_hwndOK, - is_valid_path && (available >= total || available == -1) + is_valid_path && ((unsigned int)available >= (unsigned int)total) #ifdef NSIS_SUPPORT_CODECALLBACKS - && !ExecuteCodeSegment(g_inst_header->code_onVerifyInstDir,NULL) + && !ExecuteCodeSegment(g_header->code_onVerifyInstDir,NULL) #endif ); } @@ -837,7 +854,7 @@ static int NSISCALL SetChildrenStates(HWND hwTree, HTREEITEM hItem, int iChecked tvItem.stateMask = TVIS_STATEIMAGEMASK; TreeView_GetItem(hwTree, &tvItem); - pFlags = &(g_inst_section[tvItem.lParam].flags); + pFlags = &(g_sections[tvItem.lParam].flags); if (*pFlags & SF_RO) { @@ -894,7 +911,7 @@ static void NSISCALL SetParentState(HWND hwTree, HTREEITEM hItem) tvItem.hItem = hParent; TreeView_GetItem(hwTree, &tvItem); - iFlags = &(g_inst_section[tvItem.lParam].flags); + iFlags = &(g_sections[tvItem.lParam].flags); *iFlags &= ~(SF_SELECTED|SF_PSELECTED); if (iState == 2) @@ -967,7 +984,7 @@ static DWORD WINAPI newTreeWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l myitoa(g_usrvars[0], lParam); - ExecuteCodeSegment(g_inst_header->code_onMouseOverSection,NULL); + ExecuteCodeSegment(g_header->code_onMouseOverSection,NULL); mystrcpy(g_usrvars[0], g_tmp); } @@ -983,12 +1000,13 @@ static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar HWND hwndCombo1 = GetUIItem(IDC_COMBO1); HWND hwndTree1 = GetUIItem(IDC_TREE1); extern HWND g_SectionHack; + section *sections=g_sections; if (uMsg == WM_INITDIALOG) { int doLines=0; HTREEITEM Par; HBITMAP hBMcheck1; - int x, lastGoodX, i, doCombo=0; + int x, lastGoodX, i, noCombo=2; g_SectionHack=hwndDlg; @@ -996,7 +1014,6 @@ static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar hTreeItems=(HTREEITEM*)my_GlobalAlloc(sizeof(HTREEITEM)*num_sections); hBMcheck1=LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BITMAP1)); - SetUITextFromLang(IDC_INTROTEXT,LANG_COMP_TEXT); oldTreeWndProc=SetWindowLong(hwndTree1,GWL_WNDPROC,(DWORD)newTreeWndProc); @@ -1011,35 +1028,29 @@ static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar for (i = 0; i < NSIS_MAX_INST_TYPES+1; i++) { - if (g_inst_header->install_types[i]) + if (g_header->install_types[i]) { int j; - if (i != NSIS_MAX_INST_TYPES) doCombo++; - process_string_fromtab(g_tmp,g_inst_header->install_types[i]); - j=SendMessage(hwndCombo1,CB_ADDSTRING,0,(LPARAM)ps_tmpbuf); + if (i != NSIS_MAX_INST_TYPES) noCombo = 0; + GetNSISString(g_tmp,g_header->install_types[i]); + j=SendMessage(hwndCombo1,CB_ADDSTRING,0,(LPARAM)g_tmp); SendMessage(hwndCombo1,CB_SETITEMDATA,j,i); - if (i == g_flags.cur_insttype) + if (i == g_exec_flags.cur_insttype) SendMessage(hwndCombo1, CB_SETCURSEL, j, 0); } } - if (doCombo) - { + if (!noCombo) ShowWindow(hwndCombo1,SW_SHOW); - SetUITextFromLang(IDC_TEXT1,LANG_COMP_SUBTEXT(0)); - SetUITextFromLang(IDC_TEXT2,LANG_COMP_SUBTEXT(1)); - } - else - { - SetUITextFromLang(IDC_TEXT1,LANG_COMP_SUBTEXT(2)); - SetUITextFromLang(IDC_TEXT2,LANG_COMP_SUBTEXT(3)); - } + + SetUITextFromLang(IDC_TEXT1,this_page->parms[1+noCombo]); + SetUITextFromLang(IDC_TEXT2,this_page->parms[2+noCombo]); Par=NULL; for (lastGoodX = x = 0; x < num_sections; x ++) { - section *sec=g_inst_section+x; + section *sec=sections+x; if (sec->name_ptr) { @@ -1048,7 +1059,7 @@ static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar tv.hInsertAfter=TVI_LAST; tv.item.mask=TVIF_PARAM|TVIF_TEXT|TVIF_STATE; tv.item.lParam=x; - tv.item.pszText=process_string_fromtab(0,sec->name_ptr); + tv.item.pszText=GetNSISStringTT(sec->name_ptr); tv.item.stateMask=TVIS_STATEIMAGEMASK|TVIS_EXPANDED; { @@ -1092,7 +1103,7 @@ static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar } SendMessage(hwndTree1,WM_VSCROLL,SB_TOP,0); - uMsg = g_flags.insttype_changed ? WM_NOTIFY_INSTTYPE_CHANGE : WM_IN_UPDATEMSG; + uMsg = g_exec_flags.insttype_changed ? WM_NOTIFY_INSTTYPE_CHANGE : WM_IN_UPDATEMSG; } if (uMsg == WM_NOTIFY_SECTEXT) // update text { @@ -1103,13 +1114,13 @@ static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar if (tv.hItem=hTreeItems[x]) { tv.mask=TVIF_TEXT; - tv.pszText=process_string_fromtab(0,ns); + tv.pszText=GetNSISStringTT(ns); TreeView_SetItem(hwndTree1,&tv); } } if (uMsg == WM_NOTIFY_SECFLAGS) // change flags { - int flags = g_inst_section[wParam].flags; + int flags = sections[wParam].flags; TVITEM tvItem; if (!(tvItem.hItem = hTreeItems[wParam])) return 0; @@ -1131,7 +1142,7 @@ static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar LPNMHDR lpnmh = (LPNMHDR) lParam; if (uMsg == WM_TREEVIEW_KEYHACK || lpnmh->idFrom == IDC_TREE1) { - if (!(inst_flags&CH_FLAGS_NO_CUSTOM) && (uMsg == WM_TREEVIEW_KEYHACK || lpnmh->code == NM_CLICK)) + if (!(g_flags&CH_FLAGS_NO_CUSTOM) && (uMsg == WM_TREEVIEW_KEYHACK || lpnmh->code == NM_CLICK)) { TVITEM tvItem; @@ -1153,12 +1164,12 @@ static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar { if (iState == 2) // already checked { - g_inst_section[tvItem.lParam].flags&=~SF_SELECTED; + sections[tvItem.lParam].flags&=~SF_SELECTED; CheckTreeItem(hwndTree1,tvItem.hItem,0); } else { - g_inst_section[tvItem.lParam].flags|=SF_SELECTED; + sections[tvItem.lParam].flags|=SF_SELECTED; CheckTreeItem(hwndTree1,tvItem.hItem,1); } lParam = 0; @@ -1178,9 +1189,9 @@ static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar { LPNMTREEVIEW pnmtv = (LPNMTREEVIEW) lpnmh; if (pnmtv->action == TVE_EXPAND) - g_inst_section[pnmtv->itemNew.lParam].flags |= SF_EXPAND; + sections[pnmtv->itemNew.lParam].flags |= SF_EXPAND; else - g_inst_section[pnmtv->itemNew.lParam].flags &= ~SF_EXPAND; + sections[pnmtv->itemNew.lParam].flags &= ~SF_EXPAND; } } #endif//NSIS_SUPPORT_CODECALLBACKS && NSIS_CONFIG_ENHANCEDUI_SUPPORT @@ -1199,18 +1210,18 @@ static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar int whichcfg=SendMessage(hwndCombo1,CB_GETITEMDATA,t,0); if (uMsg == WM_NOTIFY_INSTTYPE_CHANGE) { - whichcfg = g_flags.cur_insttype; - g_flags.insttype_changed = 0; + whichcfg = g_exec_flags.cur_insttype; + g_exec_flags.insttype_changed = 0; } else lParam = 1; - if (whichcfg == CB_ERR || !(g_inst_header->install_types[whichcfg])) + if (whichcfg == CB_ERR || !(g_header->install_types[whichcfg])) whichcfg = NSIS_MAX_INST_TYPES; if (whichcfg != NSIS_MAX_INST_TYPES) // not custom { int x=num_sections; - section *t=g_inst_section; + section *t=sections; HTREEITEM *ht=hTreeItems; while (x--) { @@ -1240,7 +1251,7 @@ static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar SendMessage(hwndTree1,WM_VSCROLL,SB_TOP,0); } - g_flags.cur_insttype=whichcfg; + g_exec_flags.cur_insttype=whichcfg; uMsg = WM_IN_UPDATEMSG; } @@ -1256,12 +1267,12 @@ static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar { #if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_COMPONENTPAGE) if ( wParam ) - ExecuteCodeSegment(g_inst_header->code_onSelChange,NULL); + ExecuteCodeSegment(g_header->code_onSelChange,NULL); #endif//NSIS_SUPPORT_CODECALLBACKS && NSIS_CONFIG_COMPONENTPAGE - if (inst_flags & CH_FLAGS_COMP_ONLY_ON_CUSTOM) + if (g_flags & CH_FLAGS_COMP_ONLY_ON_CUSTOM) { - int c = (g_flags.cur_insttype == NSIS_MAX_INST_TYPES) << 3;// SW_SHOWNA=8, SW_HIDE=0 + int c = (g_exec_flags.cur_insttype == NSIS_MAX_INST_TYPES) << 3;// SW_SHOWNA=8, SW_HIDE=0 ShowWindow(hwndTree1, c); ShowWindow(GetUIItem(IDC_TEXT2), c); } @@ -1272,10 +1283,10 @@ static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar for (r = 0, cbi = 0; r < NSIS_MAX_INST_TYPES; r ++) { HTREEITEM *ht=hTreeItems; - section *t=g_inst_section; + section *t=sections; x=num_sections; - if (!g_inst_header->install_types[r]) continue; + if (!g_header->install_types[r]) continue; while (x--) { @@ -1295,7 +1306,7 @@ static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar cbi++; } - g_flags.cur_insttype=r; + g_exec_flags.cur_insttype=r; SendMessage(hwndCombo1,CB_SETCURSEL,cbi,0); } // end of typecheckshit @@ -1304,10 +1315,10 @@ static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar char s[128]; for (total=x=0; x < num_sections; x ++) { - if (g_inst_section[x].flags&SF_SELECTED) - total+=g_inst_section[x].size_kb; + if (sections[x].flags&SF_SELECTED) + total+=sections[x].size_kb; } - SetUITextNT(IDC_SPACEREQUIRED,inttosizestr(total,mystrcpy(s,LANG_STR(LANG_SPACE_REQ)))); + SetUITextNT(IDC_SPACEREQUIRED,inttosizestr(total,GetNSISString(s,LANG_SPACE_REQ))); } } @@ -1317,143 +1328,149 @@ static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar #endif//NSIS_CONFIG_VISIBLE_SUPPORT -int ui_st_updateflag=0x3; +int ui_st_updateflag=0x6; -void NSISCALL update_status_text_from_lang(int id, const char *text2) +void NSISCALL update_status_text(int strtab, const char *text) { - update_status_text(LANG_STR(id), text2); -} - -void NSISCALL update_status_text(const char *text1, const char *text2) -{ - static char tmp[NSIS_MAX_STRLEN]; - static LVITEM new_item = {LVIF_TEXT,0,0,0,0,tmp}; - if (insthwnd) + static char tmp[NSIS_MAX_STRLEN*2]; + LVITEM new_item; + HWND linsthwnd = insthwnd; + if (linsthwnd) { - if (mystrlen(text1)+mystrlen(text2) >= sizeof(tmp)) return; - wsprintf(tmp,"%s%s",text1,text2); - if ((ui_st_updateflag&1)) + int tmplen = mystrlen(tmp); + + if (!(ui_st_updateflag & 1)) + GetNSISString(tmp, strtab); + + if (text) { - // Changed by Amir Szekely 26th July 2002 - new_item.iItem=ListView_GetItemCount(insthwnd); - ListView_InsertItem(insthwnd, &new_item); - ListView_EnsureVisible(insthwnd, new_item.iItem, 0); + if (tmplen + mystrlen(text) >= sizeof(tmp)) return; + lstrcat(tmp, text); + } + + if ((ui_st_updateflag & 4)) my_SetWindowText(insthwnd2, tmp); + if ((ui_st_updateflag & 2)) + { + new_item.mask = LVIF_TEXT; + new_item.pszText = tmp; + new_item.iItem = ListView_GetItemCount(linsthwnd); + new_item.iSubItem = 0; + if (ui_st_updateflag & 1) + { + new_item.iItem--; + ListView_SetItem(linsthwnd, &new_item); + tmp[tmplen]=0; + } + else + ListView_InsertItem(linsthwnd, &new_item); + ListView_EnsureVisible(linsthwnd, new_item.iItem, 0); } - if ((ui_st_updateflag&2)) my_SetWindowText(insthwnd2,tmp); } } - static DWORD WINAPI install_thread(LPVOID p) { -#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT - if (g_is_uninstaller) + int m_inst_sec=0; + HWND progresswnd = (HWND)p; + +#if defined(NSIS_SUPPORT_ACTIVEXREG) || defined(NSIS_SUPPORT_CREATESHORTCUT) { - if (ExecuteCodeSegment(g_inst_uninstheader->code,g_progresswnd)) g_flags.abort++; + extern HRESULT g_hres; + g_hres|=OleInitialize(NULL); } - else - { #endif - int m_inst_sec=0; - while (m_inst_seclb_bg,lb_fg=g_inst_cmnheader->lb_fg; + int lb_bg=g_header->lb_bg,lb_fg=g_header->lb_fg; + int x=num_sections; insthwndbutton=GetUIItem(IDC_SHOWDETAILS); insthwnd2=GetUIItem(IDC_INTROTEXT); - insthwnd=GetUIItem(IDC_LIST1); -#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT - if (g_is_uninstaller) + linsthwnd=insthwnd=GetUIItem(IDC_LIST1); + + progress_bar_len=0; + progress_bar_pos=0; + + log_printf3("New install of \"%s\" to \"%s\"",GetNSISStringTT(LANG_NAME),state_install_directory); + while (x--) { - num=g_inst_uninstheader->code_size; + if (g_sections[x].flags&SF_SELECTED) + progress_bar_len+=g_sections[x].code_size; } - else -#endif - { - int x; - log_printf3("New install of \"%s\" to \"%s\"",LANG_STR(LANG_NAME),state_install_directory); - for (x=0; x < num_sections; x ++) - { -#ifdef NSIS_CONFIG_COMPONENTPAGE - if (g_inst_section[x].flags&SF_SELECTED) -#endif - num+=g_inst_section[x].code_size; - } - } - // Changed by Amir Szekely 26th July 2002 - ListView_InsertColumn(insthwnd, 0, &lvc); - GetClientRect(insthwnd,&r); - ListView_SetColumnWidth(insthwnd, 0, r.right-r.left-GetSystemMetrics(SM_CXHSCROLL)); + + ListView_InsertColumn(linsthwnd, 0, &lvc); + GetClientRect(linsthwnd,&r); + ListView_SetColumnWidth(linsthwnd, 0, r.right-r.left-GetSystemMetrics(SM_CXHSCROLL)); #define LVS_EX_LABELTIP 0x00004000 // listview unfolds partly hidden labels if it does not have infotip text - ListView_SetExtendedListViewStyleEx(insthwnd, LVS_EX_LABELTIP, LVS_EX_LABELTIP); + ListView_SetExtendedListViewStyleEx(linsthwnd, LVS_EX_LABELTIP, LVS_EX_LABELTIP); if (lb_bg >= 0) { - ListView_SetBkColor(insthwnd, lb_bg); - ListView_SetTextBkColor(insthwnd, lb_bg); + ListView_SetBkColor(linsthwnd, lb_bg); + ListView_SetTextBkColor(linsthwnd, lb_bg); } if (lb_fg >= 0) { - ListView_SetTextColor(insthwnd, lb_fg); + ListView_SetTextColor(linsthwnd, lb_fg); } - my_SetWindowText(insthwndbutton,LANG_STR(LANG_BTN_DETAILS)); - if (inst_flags&(CH_FLAGS_DETAILS_SHOWDETAILS|CH_FLAGS_DETAILS_NEVERSHOW)) + SetUITextFromLang(IDC_SHOWDETAILS,this_page->parms[1]); + if (g_flags&(CH_FLAGS_DETAILS_SHOWDETAILS|CH_FLAGS_DETAILS_NEVERSHOW)) { ShowWindow(insthwndbutton,SW_HIDE); - if (!(inst_flags&CH_FLAGS_DETAILS_NEVERSHOW)) ShowWindow(insthwnd,SW_SHOWNA); + if (!(g_flags&CH_FLAGS_DETAILS_NEVERSHOW)) ShowWindow(linsthwnd,SW_SHOWNA); else insthwndbutton=NULL; } - progress_bar_pos=0; - progress_bar_len=num; - g_progresswnd=GetUIItem(IDC_PROGRESS); - SendMessage(g_progresswnd,PBM_SETRANGE,0,MAKELPARAM(0,30000)); - if (inst_flags&CH_FLAGS_PROGRESS_COLORED) { - SendMessage(g_progresswnd,PBM_SETBARCOLOR,0,lb_fg); - SendMessage(g_progresswnd,PBM_SETBKCOLOR,0,lb_bg); + HWND progresswnd=GetUIItem(IDC_PROGRESS); + SendMessage(progresswnd,PBM_SETRANGE,0,MAKELPARAM(0,30000)); + if (g_flags&CH_FLAGS_PROGRESS_COLORED) + { + SendMessage(progresswnd,PBM_SETBARCOLOR,0,lb_fg); + SendMessage(progresswnd,PBM_SETBKCOLOR,0,lb_bg); + } } - EnableWindow(m_hwndOK,0); - return FALSE; } if (uMsg == WM_NOTIFY_START) { DWORD id; - CloseHandle(CreateThread(NULL,0,install_thread,0,0,&id)); + CloseHandle(CreateThread(NULL,0,install_thread,GetUIItem(IDC_PROGRESS),0,&id)); } if (uMsg == WM_COMMAND && LOWORD(wParam) == IDC_SHOWDETAILS) { - ShowWindow(GetUIItem(IDC_SHOWDETAILS),SW_HIDE); - SendMessage(insthwnd,WM_VSCROLL,SB_BOTTOM,0); - ShowWindow(insthwnd,SW_SHOWNA); + ShowWindow(insthwndbutton,SW_HIDE); + ShowWindow(linsthwnd,SW_SHOWNA); } if (uMsg == WM_NOTIFY_INSTPROC_DONE) { @@ -1465,8 +1482,8 @@ static BOOL CALLBACK InstProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa else { ShowWindow(g_hwnd,SW_SHOWNA); - if (!g_flags.abort) - update_status_text_from_lang(LANG_COMPLETED,""); + if (!g_exec_flags.abort) + update_status_text(g_this_page->parms[2],0); outernotify(1); } } @@ -1475,18 +1492,18 @@ static BOOL CALLBACK InstProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa //+++Currently this has no language support for the popup menu tex if (uMsg == WM_NOTIFY && ((NMHDR*)lParam)->code == NM_RCLICK) { - int count = ListView_GetItemCount(insthwnd); + int count = ListView_GetItemCount(linsthwnd); if (count > 0) { DWORD pos = GetMessagePos(); HMENU menu = CreatePopupMenu(); - AppendMenu(menu,MF_STRING,1,LANG_STR(LANG_COPYDETAILS)); + AppendMenu(menu,MF_STRING,1,GetNSISStringTT(LANG_COPYDETAILS)); if (1==TrackPopupMenu( menu, TPM_NONOTIFY|TPM_RETURNCMD, GET_X_LPARAM(pos), GET_Y_LPARAM(pos), - 0,insthwnd,0)) + 0,linsthwnd,0)) { char textBuf[1024]; int i,total = 1; // 1 for the null char @@ -1501,7 +1518,7 @@ static BOOL CALLBACK InstProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa i = count; while (i--) // Add 2 for the CR/LF combination that must follow every line. - total += 2+SendMessage(insthwnd,LVM_GETITEMTEXT,i,(LPARAM)&item); + total += 2+SendMessage(linsthwnd,LVM_GETITEMTEXT,i,(LPARAM)&item); // 2nd pass - store detail view strings on the clipboard // Clipboard MSDN docs say mem must be GMEM_MOVEABLE @@ -1512,7 +1529,7 @@ static BOOL CALLBACK InstProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa //endPtr = ptr+total-2; // -2 to allow for CR/LF i = 0; do { - ListView_GetItemText(insthwnd,i,0,ptr,total); + ListView_GetItemText(linsthwnd,i,0,ptr,total); while (*ptr) ptr++; *(WORD*)ptr = CHAR2_TO_WORD('\r','\n'); ptr+=2; diff --git a/Source/exehead/bgbg.c b/Source/exehead/bgbg.c index b5079e05..0b9bb705 100644 --- a/Source/exehead/bgbg.c +++ b/Source/exehead/bgbg.c @@ -8,8 +8,8 @@ #ifdef NSIS_SUPPORT_BGBG -#define c1 g_inst_cmnheader->bg_color1 -#define c2 g_inst_cmnheader->bg_color2 +#define c1 g_header->bg_color1 +#define c2 g_header->bg_color2 LRESULT CALLBACK BG_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { @@ -49,7 +49,7 @@ LRESULT CALLBACK BG_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) r.bottom+=4; } - if (g_inst_cmnheader->bg_textcolor != -1) + if (g_header->bg_textcolor != -1) { HFONT newFont, oldFont; newFont = CreateFont(40,0,0,0,FW_BOLD,TRUE,FALSE,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,"Garamond"); @@ -60,7 +60,7 @@ LRESULT CALLBACK BG_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) r.top=8; my_GetWindowText(hwnd,buf,sizeof(buf)); SetBkMode(hdc,TRANSPARENT); - SetTextColor(hdc,g_inst_cmnheader->bg_textcolor); + SetTextColor(hdc,g_header->bg_textcolor); oldFont = SelectObject(hdc,newFont); DrawText(hdc,buf,-1,&r,DT_TOP|DT_LEFT|DT_SINGLELINE|DT_NOPREFIX); SelectObject(hdc,oldFont); diff --git a/Source/exehead/config.h b/Source/exehead/config.h index 54a8709f..ec5e84c1 100644 --- a/Source/exehead/config.h +++ b/Source/exehead/config.h @@ -26,14 +26,18 @@ // really a big deal, but not usually needed). #define NSIS_MAX_STRLEN 1024 -// NSIS_MAX_INST_TYPES specified the maximum install types. +// NSIS_MAX_INST_TYPES define the maximum install types. // note that this should not exceed 32, ever. #define NSIS_MAX_INST_TYPES 32 +// NSIS_DEFAULT_LANG defines the default language id NSIS will use if nothing +// else is defined in the script. Default value is 1033 which is English. +#define NSIS_DEFAULT_LANG 1033 + // NSIS_CONFIG_UNINSTALL_SUPPORT enables the uninstaller // support. Comment it out if your installers don't need // uninstallers -// adds approximately 2kb. +// adds less than 1kb. #define NSIS_CONFIG_UNINSTALL_SUPPORT // NSIS_CONFIG_LICENSEPAGE enables support for the installer to @@ -54,7 +58,7 @@ #define NSIS_CONFIG_VISIBLE_SUPPORT // NSIS_CONFIG_ENHANCEDUI_SUPPORT enables support for CreateFont, -// SetBkColor (used by some UIs), SetBrandingImage, .onInitDialog, etc +// SetCtlColors (used by some UIs), SetBrandingImage, .onGUIInit, etc #define NSIS_CONFIG_ENHANCEDUI_SUPPORT // NSIS_CONFIG_COMPRESSION_SUPPORT enables support for making installers @@ -103,9 +107,9 @@ // NSIS_CONFIG_LOG enables the logging facility. // turning this on (by uncommenting it) adds about -// 3kb, but can be useful in debugging your installers. +// 4kb, but can be useful in debugging your installers. // NOT ENABLED BY DEFAULT. -// #define NSIS_CONFIG_LOG +//#define NSIS_CONFIG_LOG // NSIS_SUPPORT_BGBG enables support for the blue (well, whatever // color you want) gradient background window. @@ -253,7 +257,7 @@ #undef NSIS_SUPPORT_BGBG #endif #ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT - #undef NSIS_CONFIG_ENHANCEDUI_SUPPORT + #undef NSIS_CONFIG_ENHANCEDUI_SUPPORT #endif #endif @@ -354,18 +358,22 @@ #error NSIS_MAX_INST_TYPES > 32 #endif +#ifndef NSIS_DEFAULT_LANG + #define NSIS_DEFAULT_LANG 1033 +#endif + #ifndef INVALID_FILE_ATTRIBUTES #define INVALID_FILE_ATTRIBUTES ((DWORD)-1) #endif // This is the old static var count that occupies memory -// From $0 to $PLUGINSDIR -#define USER_VARS_COUNT 26 +// From $0 to $PLUGINSDIR, $_CLICK +#define USER_VARS_COUNT 28 #ifdef NSIS_SUPPORT_NAMED_USERVARS // This is the total number of old static var // From $0 to $HWNDPARENT -#define TOTAL_COMPATIBLE_STATIC_VARS_COUNT 36 +#define TOTAL_COMPATIBLE_STATIC_VARS_COUNT 37 #define VARS_SECTION_NAME ".ndata" diff --git a/Source/exehead/exec.c b/Source/exehead/exec.c index af6e92c7..72f29f41 100644 --- a/Source/exehead/exec.c +++ b/Source/exehead/exec.c @@ -24,7 +24,11 @@ typedef struct _stack_t { static stack_t *g_st; #endif -union installer_flags g_flags; +union exec_flags g_exec_flags; + +#if defined(NSIS_SUPPORT_ACTIVEXREG) || defined(NSIS_SUPPORT_CREATESHORTCUT) +HRESULT g_hres; +#endif #ifdef NSIS_SUPPORT_REGISTRYFUNCTIONS // based loosely on code from Tim Kosse @@ -63,8 +67,8 @@ int NSISCALL ExecuteCodeSegment(int pos, HWND hwndProgress) while (pos >= 0) { int rv; - if (g_inst_entry[pos].which == EW_RET) return 0; - rv=ExecuteEntry(g_inst_entry + pos); + if (g_entries[pos].which == EW_RET) return 0; + rv=ExecuteEntry(g_entries + pos); if (rv == EXEC_ERROR) return EXEC_ERROR; rv=resolveaddr(rv); @@ -91,22 +95,18 @@ int NSISCALL ExecuteCodeSegment(int pos, HWND hwndProgress) static char bufs[5][NSIS_MAX_STRLEN]; static int *parms; -static int NSISCALL process_string_fromparm_toint(int id_) +static int NSISCALL GetIntFromParm(int id_) { -#ifdef NSIS_SUPPORT_LANG_IN_STRINGS - return myatoi(process_string(GetStringFromStringTab(parms[id_]), 0)); -#else - return myatoi(process_string(GetStringFromStringTab(parms[id_]))); -#endif + return myatoi(GetNSISStringTT(parms[id_])); } // NB - USE CAUTION when rearranging code to make use of the new return value of // this function - be sure the parm being accessed is not modified before the call. // Use a negative number to get the string validated as a file name -static char * NSISCALL process_string_fromparm_tobuf(int id_) +static char * NSISCALL GetStringFromParm(int id_) { int id = id_ < 0 ? -id_ : id_; - char *result = process_string_fromtab(bufs[id >> 4], parms[id & 0xF]); + char *result = GetNSISString(bufs[id >> 4], parms[id & 0xF]); if (id_ < 0) validate_filename(result); return result; } @@ -139,9 +139,13 @@ static int NSISCALL ExecuteEntry(entry *entry_) // Saves 8 bytes // HWND mainHwnd = g_hwnd; // #define g_hwnd mainHwnd - + +#ifdef NSIS_CONFIG_COMPONENTPAGE HWND hwSectionHack = g_SectionHack; - +#endif + + int exec_error = 0; + parms = entry_->offsets; switch (which) @@ -151,9 +155,8 @@ static int NSISCALL ExecuteEntry(entry *entry_) return parm0; case EW_ABORT: { - char *buf0=process_string_fromparm_tobuf(0x00); - log_printf2("Aborting: \"%s\"",buf0); - update_status_text("",buf0); + log_printf2("Aborting: \"%s\"",GetStringFromParm(0x00)); + update_status_text(parm0,0); } return EXEC_ERROR; case EW_QUIT: @@ -168,7 +171,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) } case EW_UPDATETEXT: if (parm1) { - static int old_st_updateflag=3; + static int old_st_updateflag=6; if (parm1&8) ui_st_updateflag=old_st_updateflag; else { old_st_updateflag=ui_st_updateflag; @@ -177,14 +180,13 @@ static int NSISCALL ExecuteEntry(entry *entry_) } else { - char *buf3=process_string_fromparm_tobuf(0x30); - log_printf2("detailprint: %s",buf3); - update_status_text(buf3,""); + log_printf2("detailprint: %s",GetStringFromParm(0x00)); + update_status_text(parm0,0); } break; case EW_SLEEP: { - int x=process_string_fromparm_toint(0); + int x=GetIntFromParm(0); log_printf2("Sleep(%d)",x); Sleep(max(x,1)); } @@ -194,41 +196,41 @@ static int NSISCALL ExecuteEntry(entry *entry_) SetForegroundWindow(g_hwnd); break; case EW_SETFLAG: - g_flags.flags[parm0]=process_string_fromparm_toint(1); + g_exec_flags.flags[parm0]=GetIntFromParm(1); break; case EW_IFFLAG: { - int f=entry_->offsets[!g_flags.flags[parm2]]; - g_flags.flags[parm2]&=parm3; + int f=entry_->offsets[!g_exec_flags.flags[parm2]]; + g_exec_flags.flags[parm2]&=parm3; return f; } case EW_GETFLAG: - myitoa(var0,g_flags.flags[parm1]); + myitoa(var0,g_exec_flags.flags[parm1]); break; case EW_CHDETAILSVIEW: if (insthwndbutton) ShowWindow(insthwndbutton,parm1); if (insthwnd) ShowWindow(insthwnd,parm0); break; case EW_SETFILEATTRIBUTES: { - char *buf1=process_string_fromparm_tobuf(-0x10); + char *buf1=GetStringFromParm(-0x10); log_printf3("SetFileAttributes: \"%s\":%08X",buf1,parm1); if (!SetFileAttributes(buf1,parm1)) { - g_flags.exec_error++; + exec_error++; log_printf("SetFileAttributes failed."); } } break; case EW_CREATEDIR: { - char *buf1=process_string_fromparm_tobuf(-0x10); + char *buf1=GetStringFromParm(-0x10); log_printf3("CreateDirectory: \"%s\" (%d)",buf1,parm1); if (parm1) { - update_status_text_from_lang(LANG_OUTPUTDIR,buf1); + update_status_text(LANG_OUTPUTDIR,buf1); mystrcpy(state_output_directory,buf1); SetCurrentDirectory(buf1); } - else update_status_text_from_lang(LANG_CREATEDIR,buf1); + else update_status_text(LANG_CREATEDIR,buf1); { char *tp=CharNext(buf1); char *p=buf1; @@ -254,9 +256,9 @@ static int NSISCALL ExecuteEntry(entry *entry_) fd = file_exists(buf1); if (!fd) { if (!CreateDirectory(buf1,NULL)) - g_flags.exec_error++; + exec_error++; } - else if ((fd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) g_flags.exec_error++; + else if ((fd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) exec_error++; *p++ = c; } } @@ -265,7 +267,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) break; case EW_IFFILEEXISTS: { - char *buf0=process_string_fromparm_tobuf(0x00); + char *buf0=GetStringFromParm(0x00); if (file_exists(buf0)) { log_printf3("IfFileExists: file \"%s\" exists, jumping %d",buf0,parm1); @@ -277,8 +279,8 @@ static int NSISCALL ExecuteEntry(entry *entry_) #ifdef NSIS_SUPPORT_RENAME case EW_RENAME: { - char *buf1=process_string_fromparm_tobuf(-0x10); - char *buf2=process_string_fromparm_tobuf(-0x21); + char *buf1=GetStringFromParm(-0x10); + char *buf2=GetStringFromParm(-0x21); mystrcpy(buf3,buf1); if (mystrlen(buf1)+mystrlen(buf2) < NSIS_MAX_STRLEN-3) { @@ -288,7 +290,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) log_printf2("Rename: %s",buf3); if (MoveFile(buf1,buf2)) { - update_status_text_from_lang(LANG_RENAME,buf3); + update_status_text(LANG_RENAME,buf3); } else { @@ -296,16 +298,16 @@ static int NSISCALL ExecuteEntry(entry *entry_) if (parm2 && file_exists(buf1)) { #ifdef NSIS_SUPPORT_REBOOT - g_flags.exec_reboot++; + g_exec_flags.exec_reboot++; #endif MoveFileOnReboot(buf1,buf2); - update_status_text_from_lang(LANG_RENAMEONREBOOT,buf3); + update_status_text(LANG_RENAMEONREBOOT,buf3); log_printf2("Rename on reboot: %s",buf3); } else #endif { - g_flags.exec_error++; + exec_error++; log_printf2("Rename failed: %s",buf3); } } @@ -317,10 +319,10 @@ static int NSISCALL ExecuteEntry(entry *entry_) { char *fp; char *p=var0; - char *buf0=process_string_fromparm_tobuf(0x01); + char *buf0=GetStringFromParm(0x01); if (!GetFullPathName(buf0,NSIS_MAX_STRLEN,p,&fp)) { - g_flags.exec_error++; + exec_error++; *p=0; } else if (fp>buf0 && *fp) @@ -332,7 +334,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) } else { - g_flags.exec_error++; + exec_error++; *p=0; } } @@ -343,10 +345,10 @@ static int NSISCALL ExecuteEntry(entry *entry_) { char *fp; char *p=var0; - char *buf0=process_string_fromparm_tobuf(-0x01); + char *buf0=GetStringFromParm(-0x01); if (!SearchPath(NULL,buf0,NULL,NSIS_MAX_STRLEN,p,&fp)) { - g_flags.exec_error++; + exec_error++; p[0]=0; } } @@ -354,8 +356,8 @@ static int NSISCALL ExecuteEntry(entry *entry_) case EW_GETTEMPFILENAME: { char *textout=var0; - if (!my_GetTempFileName(textout, process_string_fromparm_tobuf(-0x11))) - g_flags.exec_error++; + if (!my_GetTempFileName(textout, GetStringFromParm(-0x11))) + exec_error++; } break; #endif @@ -364,11 +366,11 @@ static int NSISCALL ExecuteEntry(entry *entry_) { HANDLE hOut; int ret; - char *buf3=process_string_fromparm_tobuf(0x31); + char *buf3=GetStringFromParm(0x31); #define overwriteflag parm0 // Modified by ramon 23 May 2003 - log_printf4("File: overwriteflag=%d, allowskipfilesflag=%d, name=\"%s\"",overwriteflag,parm5&MB_ABORTRETRYIGNORE,buf3); + log_printf4("File: overwriteflag=%d, allowskipfilesflag=%d, name=\"%s\"",overwriteflag,(parm0>>2)&MB_ABORTRETRYIGNORE,buf3); if (validpathspec(buf3)) { mystrcpy(buf0,buf3); @@ -376,12 +378,6 @@ static int NSISCALL ExecuteEntry(entry *entry_) else lstrcat(addtrailingslash(mystrcpy(buf0,state_output_directory)),buf3); validate_filename(buf0); _tryagain: - if (!overwriteflag) - { - int attr=GetFileAttributes(buf0); - if (attr & FILE_ATTRIBUTE_READONLY) - SetFileAttributes(buf0,attr^FILE_ATTRIBUTE_READONLY); - } if (overwriteflag == 3) // check date and time { WIN32_FIND_DATA *ffd=file_exists(buf0); @@ -391,42 +387,52 @@ static int NSISCALL ExecuteEntry(entry *entry_) overwriteflag=(CompareFileTime(&ffd->ftLastWriteTime,(FILETIME*)(entry_->offsets+3)) >= 0); // if first one is newer, then don't overwrite } } + if (!overwriteflag) + { + int attr=GetFileAttributes(buf0); + if (attr & FILE_ATTRIBUTE_READONLY) + SetFileAttributes(buf0,attr^FILE_ATTRIBUTE_READONLY); + } hOut=myOpenFile(buf0,GENERIC_WRITE,(overwriteflag==1)?CREATE_NEW:CREATE_ALWAYS); if (hOut == INVALID_HANDLE_VALUE) { if (overwriteflag) { - update_status_text_from_lang(LANG_SKIPPED,buf3); - if (overwriteflag==2) g_flags.exec_error++; + update_status_text(LANG_SKIPPED,buf3); + if (overwriteflag==2) g_exec_flags.exec_error++; log_printf3("File: skipped: \"%s\" (overwriteflag=%d)",buf0,overwriteflag); break; } log_printf2("File: error creating \"%s\"",buf0); - mystrcpy(buf2,g_usrvars[0]);//save $0 + mystrcpy(buf2,g_usrvars[0]); //save $0 mystrcpy(g_usrvars[0],buf0); - process_string_fromtab(buf1,parm5&MB_ABORTRETRYIGNORE?LANG_FILEERR:LANG_FILEERR_NOIGNORE); + GetNSISString(buf1,parm5); mystrcpy(g_usrvars[0],buf2); // restore $0 // Modified by ramon 23 May 2003 - switch (my_MessageBox(buf1, parm5)) + switch (my_MessageBox(buf1, parm0>>2)) { case IDRETRY: log_printf("File: error, user retry"); goto _tryagain; case IDIGNORE: log_printf("File: error, user cancel"); - g_flags.exec_error++; + g_exec_flags.exec_error++; return 0; default: log_printf("File: error, user abort"); - update_status_text_from_lang(LANG_CANTWRITE,buf0); + update_status_text(LANG_CANTWRITE,buf0); return EXEC_ERROR; } } - update_status_text_from_lang(LANG_EXTRACT,buf3); - ret=GetCompressedDataFromDataBlock(parm2,hOut); + update_status_text(LANG_EXTRACT,buf3); + { + ui_st_updateflag ^= 1; + ret=GetCompressedDataFromDataBlock(parm2,hOut); + ui_st_updateflag ^= 1; + } log_printf3("File: wrote %d to \"%s\"",ret,buf0); @@ -439,11 +445,12 @@ static int NSISCALL ExecuteEntry(entry *entry_) { if (ret == -2) { - wsprintf(buf0,"%s%s",LANG_STR(LANG_ERRORWRITING),buf3); + GetNSISString(buf0,LANG_ERRORWRITING); + lstrcat(buf0,buf3); } else { - mystrcpy(buf0,LANG_STR(LANG_ERRORDECOMPRESSING)); + GetNSISString(buf0,LANG_ERRORDECOMPRESSING); } log_printf2("%s",buf0); my_MessageBox(buf0,MB_OK|MB_ICONSTOP); @@ -461,7 +468,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) { HANDLE h; WIN32_FIND_DATA fd; - char *buf1=process_string_fromparm_tobuf(0x10); + char *buf1=GetStringFromParm(0x10); mystrcpy(buf0,buf1); log_printf2("Delete: \"%s\"",buf0); trimslashtoend(buf0); @@ -478,7 +485,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) if (DeleteFile(buf1)) { log_printf2("Delete: DeleteFile(\"%s\")",buf1); - update_status_text_from_lang(LANG_DELETEFILE,buf1); + update_status_text(LANG_DELETEFILE,buf1); } else { @@ -486,16 +493,16 @@ static int NSISCALL ExecuteEntry(entry *entry_) if (parm1) { #ifdef NSIS_SUPPORT_REBOOT - g_flags.exec_reboot++; + g_exec_flags.exec_reboot++; #endif log_printf2("Delete: DeleteFile on Reboot(\"%s\")",buf1); - update_status_text_from_lang(LANG_DELETEONREBOOT,buf1); + update_status_text(LANG_DELETEONREBOOT,buf1); MoveFileOnReboot(buf1,NULL); } else #endif { - g_flags.exec_error++; + exec_error++; } } } @@ -509,7 +516,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) case EW_MESSAGEBOX: // MessageBox { int v; - char *buf3=process_string_fromparm_tobuf(0x31); + char *buf3=GetStringFromParm(0x31); log_printf3("MessageBox: %d,\"%s\"",parm0,buf3); v=my_MessageBox(buf3,parm0); if (v) @@ -523,37 +530,37 @@ static int NSISCALL ExecuteEntry(entry *entry_) return parm5; } } - else g_flags.exec_error++; + else exec_error++; } break; #endif//NSIS_SUPPORT_MESSAGEBOX #ifdef NSIS_SUPPORT_RMDIR case EW_RMDIR: { - char *buf0=process_string_fromparm_tobuf(0x00); + char *buf0=GetStringFromParm(0x00); log_printf2("RMDir: \"%s\"",buf0); if (lastchar(buf0)=='\\') trimslashtoend(buf0); doRMDir(buf0,parm1); - if (file_exists(buf0) && parm1!=2) g_flags.exec_error++; - else update_status_text_from_lang(LANG_REMOVEDIR, buf0); + if (file_exists(buf0) && parm1!=2) exec_error++; + else update_status_text(LANG_REMOVEDIR, buf0); } break; #endif//NSIS_SUPPORT_RMDIR #ifdef NSIS_SUPPORT_STROPTS case EW_STRLEN: { - char *buf0=process_string_fromparm_tobuf(0x01); + char *buf0=GetStringFromParm(0x01); myitoa(var0,mystrlen(buf0)); } break; case EW_ASSIGNVAR: { - int newlen=process_string_fromparm_toint(2); - int start=process_string_fromparm_toint(3); + int newlen=GetIntFromParm(2); + int start=GetIntFromParm(3); int l; char *p=var0; - char *buf0=process_string_fromparm_tobuf(0x01); + char *buf0=GetStringFromParm(0x01); *p=0; if (!parm2 || newlen) { @@ -575,8 +582,8 @@ static int NSISCALL ExecuteEntry(entry *entry_) } break; case EW_STRCMP: { - char *buf2=process_string_fromparm_tobuf(0x20); - char *buf3=process_string_fromparm_tobuf(0x31); + char *buf2=GetStringFromParm(0x20); + char *buf3=GetStringFromParm(0x31); if (!lstrcmpi(buf2,buf3)) return parm2; } return parm3; @@ -585,12 +592,12 @@ static int NSISCALL ExecuteEntry(entry *entry_) case EW_READENVSTR: { char *p=var0; - char *buf0=process_string_fromparm_tobuf(0x01); + char *buf0=GetStringFromParm(0x01); if (parm2) { if (!GetEnvironmentVariable(buf0,p,NSIS_MAX_STRLEN)) { - g_flags.exec_error++; + exec_error++; *p=0; } } @@ -606,8 +613,8 @@ static int NSISCALL ExecuteEntry(entry *entry_) case EW_INTCMP: { int v,v2; - v=process_string_fromparm_toint(0); - v2=process_string_fromparm_toint(1); + v=GetIntFromParm(0); + v2=GetIntFromParm(1); if (!parm5) { // signed if (vtext); @@ -674,7 +681,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) if (!s) { log_printf("Pop: stack empty"); - g_flags.exec_error++; + exec_error++; break; } mystrcpy(var0,s->text); @@ -684,7 +691,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) else { s=(stack_t*)my_GlobalAlloc(sizeof(stack_t)); - process_string_fromtab(s->text,parm0); + GetNSISString(s->text,parm0); s->next=g_st; g_st=s; } @@ -696,23 +703,23 @@ static int NSISCALL ExecuteEntry(entry *entry_) case EW_SENDMESSAGE: { int v; - int b3=(int)process_string_fromparm_tobuf(0x33); - int b4=(int)process_string_fromparm_tobuf(0x44); + int b3=(int)GetStringFromParm(0x33); + int b4=(int)GetStringFromParm(0x44); if (!(parm5&1)) b3=myatoi((char*)b3); if (!(parm5&2)) b4=myatoi((char*)b4); if (which == EW_SENDMESSAGE) { - HWND hwnd=(HWND)process_string_fromparm_toint(1); - int msg=process_string_fromparm_toint(2); + HWND hwnd=(HWND)GetIntFromParm(1); + int msg=GetIntFromParm(2); - if (parm5>>2) g_flags.exec_error += !SendMessageTimeout(hwnd,msg,b3,b4,SMTO_NORMAL,parm5>>2,(LPDWORD)&v); + if (parm5>>2) exec_error += !SendMessageTimeout(hwnd,msg,b3,b4,SMTO_NORMAL,parm5>>2,(LPDWORD)&v); else v=SendMessage(hwnd,msg,b3,b4); } else { - char *buf0=process_string_fromparm_tobuf(0x01); - char *buf1=process_string_fromparm_tobuf(0x12); + char *buf0=GetStringFromParm(0x01); + char *buf1=GetStringFromParm(0x12); v=(int)FindWindowEx((HWND)b3,(HWND)b4,buf0[0]?buf0:NULL,buf1[0]?buf1:NULL); } @@ -721,35 +728,32 @@ static int NSISCALL ExecuteEntry(entry *entry_) } break; case EW_ISWINDOW: - if (IsWindow((HWND)process_string_fromparm_toint(0))) return parm1; + if (IsWindow((HWND)GetIntFromParm(0))) return parm1; return parm2; #ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT case EW_GETDLGITEM: myitoa( var0, (int)GetDlgItem( - (HWND)process_string_fromparm_toint(1), - process_string_fromparm_toint(2) + (HWND)GetIntFromParm(1), + GetIntFromParm(2) ) ); break; - case EW_GETWINTEXT: - my_GetWindowText( - (HWND)process_string_fromparm_toint(1), - var0, - NSIS_MAX_STRLEN - ); - break; - case EW_SETBKCOLOR: + case EW_SETCTLCOLORS: { - DeleteObject( - (HGDIOBJ)SetWindowLong( - (HWND)process_string_fromparm_toint(3), - GWL_USERDATA, - // three times 4 bytes (UINT, COLORREF [=DWORD], LONG) - parm1==-1?parm1:(int)CreateBrushIndirect((LPLOGBRUSH)entry_->offsets) - ) - ); + ctlcolors *c = (ctlcolors *)(g_blocks[NB_CTLCOLORS].offset + parm1); + + if (c->flags & CC_TEXT_SYS) + c->text = GetSysColor(c->text); + if (c->flags & CC_BK_SYS) + c->bk.lbColor = GetSysColor(c->bk.lbColor); + if (c->flags & CC_BKB) + c->bkb = CreateBrushIndirect(&c->bk); + + c->flags &= ~(CC_BK_SYS|CC_TEXT_SYS|CC_BKB); + + SetWindowLong((HWND) GetIntFromParm(0), GWL_USERDATA, (long) c); } break; case EW_SETBRANDINGIMAGE: @@ -760,40 +764,41 @@ static int NSISCALL ExecuteEntry(entry *entry_) GetClientRect(hwImage, &r); hImage=LoadImage( 0, - process_string_fromparm_tobuf(0x00), + GetStringFromParm(0x00), IMAGE_BITMAP, parm2?r.right:0, parm2?r.bottom:0, LR_LOADFROMFILE ); - DeleteObject((HGDIOBJ)SetWindowLong(hwImage,GWL_USERDATA,(LONG)hImage)); - SendMessage( + hImage = (HANDLE)SendMessage( hwImage, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hImage ); + // delete old image + if (hImage) DeleteObject(hImage); } break; case EW_CREATEFONT: { static LOGFONT f; - f.lfHeight=-MulDiv(process_string_fromparm_toint(2),GetDeviceCaps(GetDC(g_hwnd),LOGPIXELSY),72); - f.lfWeight=process_string_fromparm_toint(3); + f.lfHeight=-MulDiv(GetIntFromParm(2),GetDeviceCaps(GetDC(g_hwnd),LOGPIXELSY),72); + f.lfWeight=GetIntFromParm(3); f.lfItalic=parm4&1; f.lfUnderline=parm4&2; f.lfStrikeOut=parm4&4; f.lfCharSet=DEFAULT_CHARSET; - process_string_fromtab(f.lfFaceName,parm1); + GetNSISString(f.lfFaceName,parm1); myitoa(var0,(int)CreateFontIndirect(&f)); } break; case EW_SHOWWINDOW: if (parm2) log_printf("HideWindow"); if (!parm3) - ShowWindow((HWND)process_string_fromparm_toint(0),process_string_fromparm_toint(1)); + ShowWindow((HWND)GetIntFromParm(0),GetIntFromParm(1)); else - EnableWindow((HWND)process_string_fromparm_toint(0),process_string_fromparm_toint(1)); + EnableWindow((HWND)GetIntFromParm(0),GetIntFromParm(1)); break; #endif//NSIS_CONFIG_ENHANCEDUI_SUPPORT #endif//NSIS_SUPPORT_HWNDS @@ -801,16 +806,16 @@ static int NSISCALL ExecuteEntry(entry *entry_) case EW_SHELLEXEC: // this uses improvements of Andras Varga { int x; - char *buf0=process_string_fromparm_tobuf(0x00); - char *buf1=process_string_fromparm_tobuf(0x11); - char *buf2=process_string_fromparm_tobuf(0x22); + char *buf0=GetStringFromParm(0x00); + char *buf1=GetStringFromParm(0x11); + char *buf2=GetStringFromParm(0x22); wsprintf(buf3,"%s %s",buf0,buf1); - update_status_text_from_lang(LANG_EXECSHELL, buf3); + update_status_text(LANG_EXECSHELL, buf3); x=(int)ShellExecute(g_hwnd,buf0[0]?buf0:NULL,buf1,buf2[0]?buf2:NULL,state_output_directory,parm3); if (x < 33) { log_printf5("ExecShell: warning: error (\"%s\": file:\"%s\" params:\"%s\")=%d",buf0,buf1,buf2,x); - g_flags.exec_error++; + exec_error++; } else { @@ -823,9 +828,9 @@ static int NSISCALL ExecuteEntry(entry *entry_) case EW_EXECUTE: { HANDLE hProc; - char *buf0=process_string_fromparm_tobuf(0x00); + char *buf0=GetStringFromParm(0x00); log_printf2("Exec: command=\"%s\"",buf0); - update_status_text_from_lang(LANG_EXECUTE,buf0); + update_status_text(LANG_EXECUTE,buf0); hProc=myCreateProcess(buf0,state_output_directory); @@ -844,13 +849,13 @@ static int NSISCALL ExecuteEntry(entry *entry_) GetExitCodeProcess(hProc, &lExitCode); if (parm2>=0) myitoa(var2,lExitCode); - else if (lExitCode) g_flags.exec_error++; + else if (lExitCode) exec_error++; } CloseHandle( hProc ); } else { - g_flags.exec_error++; + exec_error++; log_printf2("Exec: failed createprocess (\"%s\")",buf0); } } @@ -865,7 +870,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) WIN32_FIND_DATA *ffd; char *highout=var1; char *lowout=var2; - char *buf0=process_string_fromparm_tobuf(0x00); + char *buf0=GetStringFromParm(0x00); ffd=file_exists(buf0); if (ffd) @@ -876,7 +881,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) else { *lowout=*highout=0; - g_flags.exec_error++; + exec_error++; } } break; @@ -890,10 +895,10 @@ static int NSISCALL ExecuteEntry(entry *entry_) DWORD t[4]; // our two members are the 3rd and 4th.. VS_FIXEDFILEINFO *pvsf1=(VS_FIXEDFILEINFO*)t; DWORD d; - char *buf1=process_string_fromparm_tobuf(-0x10); + char *buf1=GetStringFromParm(-0x10); s1=GetFileVersionInfoSize(buf1,&d); *lowout=*highout=0; - g_flags.exec_error++; + exec_error++; if (s1) { void *b1; @@ -906,7 +911,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) myitoa(highout,pvsf1->dwFileVersionMS); myitoa(lowout,pvsf1->dwFileVersionLS); - g_flags.exec_error--; + exec_error--; } GlobalFree(b1); } @@ -917,25 +922,26 @@ static int NSISCALL ExecuteEntry(entry *entry_) #ifdef NSIS_SUPPORT_ACTIVEXREG case EW_REGISTERDLL: { - HRESULT hres=OleInitialize(NULL); - g_flags.exec_error++; - if (hres == S_FALSE || hres == S_OK) + exec_error++; + if (SUCCEEDED(g_hres)) { HANDLE h; - char *buf1=process_string_fromparm_tobuf(-0x10); - char *buf0=process_string_fromparm_tobuf(0x01); + char *buf1=GetStringFromParm(-0x10); + char *buf0=GetStringFromParm(0x01); - h=LoadLibrary(buf1); + h=GetModuleHandle(buf1); + if (!h) + h=LoadLibrary(buf1); if (h) { FARPROC funke = GetProcAddress(h,buf0); if (funke) { - g_flags.exec_error--; + exec_error--; if (parm2) { - update_status_text_from_lang(parm2,buf1); - if (funke()) g_flags.exec_error++; + update_status_text(parm2,buf1); + if (funke()) exec_error++; } else { @@ -951,22 +957,20 @@ static int NSISCALL ExecuteEntry(entry *entry_) } else { - update_status_text_from_lang(LANG_CANNOTFINDSYMBOL,buf0); + update_status_text(LANG_CANNOTFINDSYMBOL,buf0); log_printf3("Error registering DLL: %s not found in %s",buf0,buf1); } - if (!parm3) while (FreeLibrary(h)); - // saves 2 bytes - FreeLibrary((HANDLE)((unsigned long)h&(unsigned long)parm3)); + if (!parm3) FreeLibrary(h); } else { - update_status_text_from_lang(LANG_COULDNOTLOAD,buf1); + update_status_text(LANG_COULDNOTLOAD,buf1); log_printf2("Error registering DLL: Could not load %s",buf1); } - OleUninitialize(); } else { - update_status_text_from_lang(LANG_NOOLE,buf1); + update_status_text(LANG_NOOLE,buf1); log_printf("Error registering DLL: Could not initialize OLE"); } } @@ -975,62 +979,55 @@ static int NSISCALL ExecuteEntry(entry *entry_) #ifdef NSIS_SUPPORT_CREATESHORTCUT case EW_CREATESHORTCUT: { - char *buf2=process_string_fromparm_tobuf(-0x20); - char *buf1=process_string_fromparm_tobuf(0x11); - char *buf0=process_string_fromparm_tobuf(0x02); - char *buf3=process_string_fromparm_tobuf(-0x33); - char *buf4=process_string_fromparm_tobuf(0x45); + char *buf2=GetStringFromParm(-0x20); + char *buf1=GetStringFromParm(0x11); + char *buf0=GetStringFromParm(0x02); + char *buf3=GetStringFromParm(-0x33); + char *buf4=GetStringFromParm(0x45); HRESULT hres; - int rv=1; IShellLink* psl; log_printf8("CreateShortCut: out: \"%s\", in: \"%s %s\", icon: %s,%d, sw=%d, hk=%d", buf2,buf1,buf0,buf3,parm4&0xff,(parm4&0xff00)>>8,parm4>>16); - hres=OleInitialize(NULL); - if (hres == S_FALSE || hres == S_OK) { + hres = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, + &IID_IShellLink, (void **) &psl); + if (SUCCEEDED(hres)) + { + IPersistFile* ppf; - hres = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, - &IID_IShellLink, (void **) &psl); + hres = psl->lpVtbl->QueryInterface(psl,&IID_IPersistFile, (void **) &ppf); if (SUCCEEDED(hres)) { - IPersistFile* ppf; - hres = psl->lpVtbl->QueryInterface(psl,&IID_IPersistFile, (void **) &ppf); - if (SUCCEEDED(hres)) - { + hres = psl->lpVtbl->SetPath(psl,buf1); + psl->lpVtbl->SetWorkingDirectory(psl,state_output_directory); + if ((parm4&0xff00)>>8) psl->lpVtbl->SetShowCmd(psl,(parm4&0xff00)>>8); + psl->lpVtbl->SetHotkey(psl,(unsigned short)(parm4>>16)); + if (buf3[0]) psl->lpVtbl->SetIconLocation(psl,buf3,parm4&0xff); + psl->lpVtbl->SetArguments(psl,buf0); + psl->lpVtbl->SetDescription(psl,buf4); - hres = psl->lpVtbl->SetPath(psl,buf1); - psl->lpVtbl->SetWorkingDirectory(psl,state_output_directory); - if ((parm4&0xff00)>>8) psl->lpVtbl->SetShowCmd(psl,(parm4&0xff00)>>8); - psl->lpVtbl->SetHotkey(psl,(unsigned short)(parm4>>16)); - if (buf3[0]) psl->lpVtbl->SetIconLocation(psl,buf3,parm4&0xff); - psl->lpVtbl->SetArguments(psl,buf0); - psl->lpVtbl->SetDescription(psl,buf4); - - if (SUCCEEDED(hres)) - { - WCHAR wsz[1024]; - MultiByteToWideChar(CP_ACP, 0, buf2, -1, wsz, 1024); - hres=ppf->lpVtbl->Save(ppf,(const WCHAR*)wsz,TRUE); - if (SUCCEEDED(hres)) rv=0; - } - ppf->lpVtbl->Release(ppf); - } - psl->lpVtbl->Release(psl); + if (SUCCEEDED(hres)) + { + WCHAR wsz[1024]; + MultiByteToWideChar(CP_ACP, 0, buf2, -1, wsz, 1024); + hres=ppf->lpVtbl->Save(ppf,(const WCHAR*)wsz,TRUE); + } + ppf->lpVtbl->Release(ppf); } - OleUninitialize(); + psl->lpVtbl->Release(psl); } - if (rv) + if (FAILED(hres)) { - g_flags.exec_error++; - update_status_text_from_lang(LANG_ERRORCREATINGSHORTCUT,buf2); + exec_error++; + update_status_text(LANG_ERRORCREATINGSHORTCUT,buf2); } else { - update_status_text_from_lang(LANG_CREATESHORTCUT,buf2); + update_status_text(LANG_CREATESHORTCUT,buf2); } } break; @@ -1040,26 +1037,27 @@ static int NSISCALL ExecuteEntry(entry *entry_) { int res; SHFILEOPSTRUCT op; - char *buf0=process_string_fromparm_tobuf(0x00); - char *buf1=process_string_fromparm_tobuf(0x11); + char *buf0=GetStringFromParm(0x00); + char *buf1=GetStringFromParm(0x11); log_printf3("CopyFiles \"%s\"->\"%s\"",buf0,buf1); op.hwnd=g_hwnd; op.wFunc=FO_COPY; buf0[mystrlen(buf0)+1]=0; buf1[mystrlen(buf1)+1]=0; - wsprintf(buf2,"%s%s",LANG_STR(LANG_COPYTO),buf1); + GetNSISString(buf2,LANG_COPYTO); + lstrcat(buf2,buf1); op.pFrom=buf0; op.pTo=buf1; op.lpszProgressTitle=buf2; op.fFlags=parm2; - update_status_text("",buf2); + update_status_text(0,buf2); res=SHFileOperation(&op); if (res) { // some of these changes were from Edgewise (wiked_edge@yahoo.com) - update_status_text_from_lang(LANG_COPYFAILED,""); - g_flags.exec_error++; + update_status_text(LANG_COPYFAILED,0); + exec_error++; } } break; @@ -1068,10 +1066,10 @@ static int NSISCALL ExecuteEntry(entry *entry_) case EW_REBOOT: if (parm0!=0xbadf00d) { - my_MessageBox(LANG_STR(LANG_INSTCORRUPTED),MB_OK|MB_ICONSTOP); + my_MessageBox(GetNSISStringTT(LANG_INSTCORRUPTED),MB_OK|MB_ICONSTOP); return EXEC_ERROR; } - g_flags.exec_error++; + g_exec_flags.exec_error++; { HANDLE h=LoadLibrary("advapi32.dll"); if (h) @@ -1117,32 +1115,32 @@ static int NSISCALL ExecuteEntry(entry *entry_) #endif if (parm0) { - sec=process_string_fromparm_tobuf(0x00); + sec=GetStringFromParm(0x00); } if (parm1) { - key=process_string_fromparm_tobuf(0x11); + key=GetStringFromParm(0x11); } if (parm4) { - str=process_string_fromparm_tobuf(0x22); + str=GetStringFromParm(0x22); } - buf3=process_string_fromparm_tobuf(-0x33); + buf3=GetStringFromParm(-0x33); log_printf5("WriteINIStr: wrote [%s] %s=%s in %s",buf0,buf1,buf2,buf3); - if (!WritePrivateProfileString(sec,key,str,buf3)) g_flags.exec_error++; + if (!WritePrivateProfileString(sec,key,str,buf3)) exec_error++; } break; case EW_READINISTR: { const char *errstr="!N~"; char *p=var0; - char *buf0=process_string_fromparm_tobuf(0x01); - char *buf1=process_string_fromparm_tobuf(0x12); - char *buf2=process_string_fromparm_tobuf(-0x23); + char *buf0=GetStringFromParm(0x01); + char *buf1=GetStringFromParm(0x12); + char *buf2=GetStringFromParm(-0x23); GetPrivateProfileString(buf0,buf1,errstr,p,NSIS_MAX_STRLEN-1,buf2); if (*((int*)errstr) == *((int*)p)) { - g_flags.exec_error++; + exec_error++; p[0]=0; } } @@ -1152,23 +1150,23 @@ static int NSISCALL ExecuteEntry(entry *entry_) case EW_DELREG: { int rootkey=parm0; - char *buf3=process_string_fromparm_tobuf(0x31); - g_flags.exec_error++; + char *buf3=GetStringFromParm(0x31); + exec_error++; if (!parm3) { HKEY hKey; if (RegOpenKeyEx((HKEY)rootkey,buf3,0,KEY_SET_VALUE,&hKey) == ERROR_SUCCESS) { - char *buf0=process_string_fromparm_tobuf(0x02); + char *buf0=GetStringFromParm(0x02); log_printf4("DeleteRegValue: %d\\%s\\%s",rootkey,buf3,buf0); - if (RegDeleteValue(hKey,buf0) == ERROR_SUCCESS) g_flags.exec_error--; + if (RegDeleteValue(hKey,buf0) == ERROR_SUCCESS) exec_error--; RegCloseKey(hKey); } } else { log_printf3("DeleteRegKey: %d\\%s",rootkey,buf3); - if (myRegDeleteKeyEx((HKEY)rootkey,buf3,parm3&2) == ERROR_SUCCESS) g_flags.exec_error--; + if (myRegDeleteKeyEx((HKEY)rootkey,buf3,parm3&2) == ERROR_SUCCESS) exec_error--; } } break; @@ -1177,22 +1175,22 @@ static int NSISCALL ExecuteEntry(entry *entry_) HKEY hKey; int rootkey=parm0; int type=parm4; - char *buf1=process_string_fromparm_tobuf(0x12); - char *buf3=process_string_fromparm_tobuf(0x31); - g_flags.exec_error++; + char *buf1=GetStringFromParm(0x12); + char *buf3=GetStringFromParm(0x31); + exec_error++; if (RegCreateKey((HKEY)rootkey,buf3,&hKey) == ERROR_SUCCESS) { if (type <= 1) { - char *buf2=process_string_fromparm_tobuf(0x23); - if (RegSetValueEx(hKey,buf1,0,type==1?REG_SZ:REG_EXPAND_SZ,buf2,mystrlen(buf2)+1) == ERROR_SUCCESS) g_flags.exec_error--; + char *buf2=GetStringFromParm(0x23); + if (RegSetValueEx(hKey,buf1,0,type==1?REG_SZ:REG_EXPAND_SZ,buf2,mystrlen(buf2)+1) == ERROR_SUCCESS) exec_error--; log_printf5("WriteRegStr: set %d\\%s\\%s to %s",rootkey,buf3,buf1,buf2); } else if (type == 2) { DWORD l; - l=process_string_fromparm_toint(3); - if (RegSetValueEx(hKey,buf1,0,REG_DWORD,(unsigned char*)&l,4) == ERROR_SUCCESS) g_flags.exec_error--; + l=GetIntFromParm(3); + if (RegSetValueEx(hKey,buf1,0,REG_DWORD,(unsigned char*)&l,4) == ERROR_SUCCESS) exec_error--; log_printf5("WriteRegDWORD: set %d\\%s\\%s to %d",rootkey,buf3,buf1,l); } else if (type == 3) @@ -1200,7 +1198,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) int len=GetCompressedDataFromDataBlockToMemory(parm3, buf2, NSIS_MAX_STRLEN); if (len >= 0) { - if (RegSetValueEx(hKey,buf1,0,REG_BINARY,buf2,len) == ERROR_SUCCESS) g_flags.exec_error--; + if (RegSetValueEx(hKey,buf1,0,REG_BINARY,buf2,len) == ERROR_SUCCESS) exec_error--; } log_printf5("WriteRegBin: set %d\\%s\\%s with %d bytes",rootkey,buf3,buf1,len); @@ -1215,8 +1213,8 @@ static int NSISCALL ExecuteEntry(entry *entry_) HKEY hKey; char *p=var0; int rootkey=parm1; - char *buf0=process_string_fromparm_tobuf(0x02); // buf0 == subkey - char *buf1=process_string_fromparm_tobuf(0x13); // buf1 == key name + char *buf0=GetStringFromParm(0x02); // buf0 == subkey + char *buf1=GetStringFromParm(0x13); // buf1 == key name p[0]=0; if (RegOpenKeyEx((HKEY)rootkey,buf0,0,KEY_READ,&hKey) == ERROR_SUCCESS) { @@ -1227,28 +1225,28 @@ static int NSISCALL ExecuteEntry(entry *entry_) (t != REG_DWORD && t != REG_SZ && t != REG_EXPAND_SZ)) { p[0]=0; - g_flags.exec_error++; + exec_error++; } else { if (t==REG_DWORD) { - if (!parm4) g_flags.exec_error++; + if (!parm4) exec_error++; myitoa(p,*((DWORD*)p)); } - else if (parm4) g_flags.exec_error++; + else if (parm4) exec_error++; } RegCloseKey(hKey); } - else g_flags.exec_error++; + else exec_error++; } break; case EW_REGENUM: { HKEY key; char *p=var0; - int b=process_string_fromparm_toint(3); - char *buf1=process_string_fromparm_tobuf(0x12); + int b=GetIntFromParm(3); + char *buf1=GetStringFromParm(0x12); p[0]=0; if (RegOpenKeyEx((HKEY)parm1,buf1,0,KEY_READ,&key) == ERROR_SUCCESS) { @@ -1258,7 +1256,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) p[NSIS_MAX_STRLEN-1]=0; RegCloseKey(key); } - else g_flags.exec_error++; + else exec_error++; } break; @@ -1274,12 +1272,12 @@ static int NSISCALL ExecuteEntry(entry *entry_) { HANDLE h; char *handleout=var3; - char *buf1=process_string_fromparm_tobuf(-0x10); + char *buf1=GetStringFromParm(-0x10); h=myOpenFile(buf1,parm1,parm2); if (h == INVALID_HANDLE_VALUE) { *handleout=0; - g_flags.exec_error++; + exec_error++; } else { @@ -1294,16 +1292,16 @@ static int NSISCALL ExecuteEntry(entry *entry_) char *t=var0; if (parm2) { - ((unsigned char *)buf1)[0]=process_string_fromparm_toint(1)&0xff; + ((unsigned char *)buf1)[0]=GetIntFromParm(1)&0xff; l=1; } else { - l=mystrlen(process_string_fromparm_tobuf(0x11)); + l=mystrlen(GetStringFromParm(0x11)); } if (!*t || !WriteFile((HANDLE)myatoi(t),buf1,l,&dw,NULL)) { - g_flags.exec_error++; + exec_error++; } } break; @@ -1313,7 +1311,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) DWORD dw; int rpos=0; char *hptr=var0; - int maxlen=process_string_fromparm_toint(2); + int maxlen=GetIntFromParm(2); if (maxlen<1) break; if (maxlen > NSIS_MAX_STRLEN-1) maxlen=NSIS_MAX_STRLEN-1; if (*hptr) @@ -1342,7 +1340,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) } } textout[rpos]=0; - if (!rpos) g_flags.exec_error++; + if (!rpos) exec_error++; } break; case EW_FSEEK: @@ -1350,7 +1348,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) char *t=var0; if (*t) { - DWORD v=SetFilePointer((HANDLE)myatoi(t),process_string_fromparm_toint(1),NULL,parm2); + DWORD v=SetFilePointer((HANDLE)myatoi(t),GetIntFromParm(1),NULL,parm2); if (parm3>=0) { @@ -1378,7 +1376,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) } else { - g_flags.exec_error++; + exec_error++; *textout=0; } @@ -1390,13 +1388,13 @@ static int NSISCALL ExecuteEntry(entry *entry_) char *handleout=var2; HANDLE h; WIN32_FIND_DATA fd; - char *buf0=process_string_fromparm_tobuf(0x00); + char *buf0=GetStringFromParm(0x00); h=FindFirstFile(buf0,&fd); if (h == INVALID_HANDLE_VALUE) { *handleout=0; *textout=0; - g_flags.exec_error++; + exec_error++; } else { @@ -1411,7 +1409,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) { int ret=-666; HANDLE hFile; - char *buf0=process_string_fromparm_tobuf(0x00); + char *buf0=GetStringFromParm(0x00); if (validpathspec(buf0)) { @@ -1423,7 +1421,6 @@ static int NSISCALL ExecuteEntry(entry *entry_) } validate_filename(buf1); - hFile=myOpenFile(buf1,GENERIC_WRITE,CREATE_ALWAYS); if (hFile != INVALID_HANDLE_VALUE) { @@ -1432,25 +1429,23 @@ static int NSISCALL ExecuteEntry(entry *entry_) filebuf=(unsigned char *)my_GlobalAlloc(filehdrsize); if (filebuf) { - //int fixoffs=0; DWORD lout; - SetSelfFilePointer(0,FILE_BEGIN); + SetSelfFilePointer(0); ReadSelfFile((char*)filebuf,filehdrsize); - if (g_inst_header->uninstdata_offset != -1) { unsigned char* seeker; - unsigned char* unicon_data = seeker = (unsigned char*)my_GlobalAlloc(g_inst_header->uninsticon_size); + unsigned char* unicon_data = seeker = (unsigned char*)my_GlobalAlloc(g_header->uninsticon_size); if (unicon_data) { - GetCompressedDataFromDataBlockToMemory(g_inst_header->uninstdata_offset, - unicon_data,g_inst_header->uninsticon_size); + GetCompressedDataFromDataBlockToMemory(g_header->uninstdata_offset, + unicon_data,g_header->uninsticon_size); while (*seeker) { - DWORD dwSize, dwOffset; - dwSize = *(DWORD*)seeker; - seeker += sizeof(DWORD); - dwOffset = *(DWORD*)seeker; - seeker += sizeof(DWORD); - mini_memcpy(filebuf+dwOffset, seeker, dwSize); - seeker += dwSize; + struct icondata { + DWORD dwSize; + DWORD dwOffset; + } id = *(struct icondata *) seeker; + seeker += sizeof(struct icondata); + mini_memcpy(filebuf+id.dwOffset, seeker, id.dwSize); + seeker += id.dwSize; } GlobalFree(unicon_data); } @@ -1462,14 +1457,16 @@ static int NSISCALL ExecuteEntry(entry *entry_) CloseHandle(hFile); } log_printf3("created uninstaller: %d, \"%s\"",ret,buf1); - if (ret < 0) { - update_status_text_from_lang(LANG_ERRORCREATING,buf0); - DeleteFile(buf1); - g_flags.exec_error++; + int str = LANG_CREATEDUNINST; + if (ret < 0) + { + str = LANG_ERRORCREATING; + DeleteFile(buf1); + exec_error++; + } + update_status_text(str,buf1); } - else - update_status_text_from_lang(LANG_CREATEDUNINST,buf0); } break; #endif//NSIS_CONFIG_UNINSTALL_SUPPORT @@ -1484,7 +1481,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) } else { - char *buf0=process_string_fromparm_tobuf(0x01); + char *buf0=GetStringFromParm(0x01); log_printf2("%s",buf0); } break; @@ -1492,17 +1489,17 @@ static int NSISCALL ExecuteEntry(entry *entry_) #ifdef NSIS_CONFIG_COMPONENTPAGE case EW_SECTIONSET: { - int x=process_string_fromparm_toint(0); + int x=GetIntFromParm(0); if ((unsigned int)x < (unsigned int)num_sections) { - section *sec=g_inst_section+x; + section *sec=g_sections+x; if (parm1>=0) // get something { int res=((int*)sec)[parm1]; if (!parm1) { // getting text - process_string_fromtab(var2,res); + GetNSISString(var2,res); } else { @@ -1516,7 +1513,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) if (parm1) { // not setting text, get int - parm2=process_string_fromparm_toint(2); + parm2=GetIntFromParm(2); } else { @@ -1531,33 +1528,36 @@ static int NSISCALL ExecuteEntry(entry *entry_) } } } - else g_flags.exec_error++; - } + else exec_error++; + } break; case EW_INSTTYPESET: { - int x=process_string_fromparm_toint(0); + int x=GetIntFromParm(0); if (parm3) { - g_flags.insttype_changed++; + g_exec_flags.insttype_changed++; SendMessage(hwSectionHack,WM_NOTIFY_INSTTYPE_CHANGE,0,0); } else if ((unsigned int)x < (unsigned int)NSIS_MAX_INST_TYPES) { if (parm2) // set text { - g_inst_header->install_types[x] = parm1; + g_header->install_types[x] = parm1; } else // get text { - process_string_fromtab(var1,g_inst_header->install_types[x]); + GetNSISString(var1,g_header->install_types[x]); } } - else g_flags.exec_error++; + else exec_error++; } break; #endif//NSIS_CONFIG_COMPONENTPAGE } + + g_exec_flags.exec_error += exec_error; + return 0; } diff --git a/Source/exehead/exec.h b/Source/exehead/exec.h index f18ebc97..1a0ba1bd 100644 --- a/Source/exehead/exec.h +++ b/Source/exehead/exec.h @@ -1,7 +1,7 @@ #ifndef _EXEC_H_ #define _EXEC_H_ -extern union installer_flags g_flags; +extern union exec_flags g_exec_flags; int NSISCALL ExecuteCodeSegment(int pos, HWND hwndProgress); // returns 0 on success diff --git a/Source/exehead/fileform.c b/Source/exehead/fileform.c index 07843fb1..453d9d34 100644 --- a/Source/exehead/fileform.c +++ b/Source/exehead/fileform.c @@ -4,6 +4,8 @@ #include "state.h" #include "resource.h" #include "lang.h" +#include "ui.h" +#include "exec.h" #ifdef NSIS_CONFIG_COMPRESSION_SUPPORT #ifdef NSIS_COMPRESS_USE_ZLIB @@ -23,11 +25,12 @@ #endif//NSIS_COMPRESS_USE_BZIP2 #endif//NSIS_CONFIG_COMPRESSION_SUPPORT -#include "ui.h" +struct block_header g_blocks[BLOCKS_NUM]; +header *g_header; +int g_flags; +int g_filehdrsize; +int g_is_uninstaller; -char *g_db_strtab; - -static int g_db_offset; HANDLE g_db_hFile; #if defined(NSIS_CONFIG_COMPRESSION_SUPPORT) && defined(NSIS_COMPRESS_WHOLE) @@ -46,24 +49,42 @@ BOOL CALLBACK verProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) if (uMsg == WM_INITDIALOG) { SetTimer(hwndDlg,1,250,NULL); - msg = (char*)lParam; + msg = (char *) lParam; uMsg = WM_TIMER; } - if (uMsg == WM_TIMER) + if (uMsg == WM_TIMER +#ifdef NSIS_COMPRESS_WHOLE + || uMsg == WM_DESTROY +#endif + ) { static char bt[64]; - wsprintf(bt,msg,MulDiv(m_pos,100,m_length)); + int percent=MulDiv(m_pos,100,m_length); +#ifdef NSIS_COMPRESS_WHOLE + if (msg) +#endif + { + wsprintf(bt,msg,percent); - my_SetWindowText(hwndDlg,bt); - my_SetDialogItemText(hwndDlg,IDC_STR,bt); + my_SetWindowText(hwndDlg,bt); + my_SetDialogItemText(hwndDlg,IDC_STR,bt); + + ShowWindow(hwndDlg, SW_SHOW); + } + +#ifdef NSIS_COMPRESS_WHOLE + if (ui_st_updateflag & 1) + { + wsprintf(bt, "... %d%%", percent); + update_status_text(0, bt); + } +#endif } return 0; } #endif//NSIS_CONFIG_CRC_SUPPORT || NSIS_COMPRESS_WHOLE #endif//NSIS_CONFIG_VISIBLE_SUPPORT -int inst_flags; - #ifdef NSIS_CONFIG_COMPRESSION_SUPPORT static z_stream g_inflate_stream; #endif @@ -84,11 +105,14 @@ const char * NSISCALL loadHeaders(int cl_flags) void *data; firstheader h; + header *header; + + HANDLE db_hFile; GetModuleFileName(g_hInstance, state_exe_directory, NSIS_MAX_STRLEN); - g_db_hFile = myOpenFile(state_exe_directory, GENERIC_READ, OPEN_EXISTING); - if (g_db_hFile == INVALID_HANDLE_VALUE) + g_db_hFile = db_hFile = myOpenFile(state_exe_directory, GENERIC_READ, OPEN_EXISTING); + if (db_hFile == INVALID_HANDLE_VALUE) { return _LANG_CANTOPENSELF; } @@ -97,7 +121,7 @@ const char * NSISCALL loadHeaders(int cl_flags) trimslashtoend(state_exe_directory); - left = m_length = GetFileSize(g_db_hFile,NULL); + left = m_length = GetFileSize(db_hFile,NULL); while (left > 0) { static char temp[512]; @@ -160,7 +184,7 @@ const char * NSISCALL loadHeaders(int cl_flags) #ifdef NSIS_CONFIG_VISIBLE_SUPPORT #ifdef NSIS_CONFIG_SILENT_SUPPORT - else if (cl_flags & FH_FLAGS_SILENT == 0) + else if ((cl_flags & FH_FLAGS_SILENT) == 0) #endif//NSIS_CONFIG_SILENT_SUPPORT { if (hwnd) @@ -200,7 +224,7 @@ const char * NSISCALL loadHeaders(int cl_flags) if (do_crc) { int fcrc; - SetSelfFilePointer(m_pos, FILE_BEGIN); + SetSelfFilePointer(m_pos); if (!ReadSelfFile(&fcrc, sizeof(int)) || crc != fcrc) return _LANG_INVALIDCRC; } @@ -218,10 +242,10 @@ const char * NSISCALL loadHeaders(int cl_flags) if (dbd_hFile == INVALID_HANDLE_VALUE) return _LANG_ERRORWRITINGTEMP; } - dbd_srcpos = SetSelfFilePointer(g_filehdrsize + sizeof(firstheader), FILE_BEGIN); + dbd_srcpos = SetSelfFilePointer(g_filehdrsize + sizeof(firstheader)); dbd_fulllen = dbd_srcpos - sizeof(h) + h.length_of_all_following_data - ((cl_flags & FH_FLAGS_NO_CRC) ? 0 : sizeof(int)); #else - SetSelfFilePointer(g_filehdrsize + sizeof(firstheader), FILE_BEGIN); + SetSelfFilePointer(g_filehdrsize + sizeof(firstheader)); #endif if (GetCompressedDataFromDataBlockToMemory(-1, data, h.length_of_header) != h.length_of_header) @@ -230,40 +254,35 @@ const char * NSISCALL loadHeaders(int cl_flags) return _LANG_INVALIDCRC; } -#if !defined(NSIS_COMPRESS_WHOLE) || !defined(NSIS_CONFIG_COMPRESSION_SUPPORT) - g_db_offset = SetSelfFilePointer(0,FILE_CURRENT); -#else - g_db_offset = dbd_pos; -#endif + header = g_header = data; - g_inst_combinedheader = data; - - inst_flags = g_inst_cmnheader->flags; #ifdef NSIS_CONFIG_SILENT_SUPPORT - if (cl_flags & FH_FLAGS_SILENT) inst_flags |= CH_FLAGS_SILENT; + if (cl_flags & FH_FLAGS_SILENT) + header->flags |= CH_FLAGS_SILENT; + + g_exec_flags.silent = header->flags & (CH_FLAGS_SILENT | CH_FLAGS_SILENT_LOG); #endif + g_flags = header->flags; + #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT if (h.flags & FH_FLAGS_UNINSTALL) - { g_is_uninstaller++; - g_inst_page = (page *) (g_inst_uninstheader + 1); - } - else #endif - { - g_inst_section=(section *) (g_inst_header + 1); - num_sections=g_inst_header->num_sections; - g_inst_page=(page *) (g_inst_section + num_sections); - } - g_inst_entry = (entry *) (g_inst_page + g_inst_cmnheader->num_pages); - g_db_strtab = (char *) (g_inst_entry + g_inst_cmnheader->num_entries); - return 0; -} -const char * NSISCALL GetStringFromStringTab(int offs) -{ - return g_db_strtab+(offs < 0 ? LANG_STR_TAB(offs) : offs); + crc = BLOCKS_NUM; + while (crc--) + header->blocks[crc].offset += (int)data; + +#ifdef NSIS_COMPRESS_WHOLE + header->blocks[NB_DATA].offset = dbd_pos; +#else + header->blocks[NB_DATA].offset = SetFilePointer(db_hFile,0,NULL,FILE_CURRENT); +#endif + + mini_memcpy(&g_blocks, &header->blocks, sizeof(g_blocks)); + + return 0; } #define IBUFSIZE 16384 @@ -285,16 +304,7 @@ int NSISCALL _dodecomp(int offset, HANDLE hFileOut, char *outbuf, int outbuflen) if (offset>=0) { - /* - int lp=SetSelfFilePointer(0,FILE_CURRENT); - if (lp > g_db_offset+offset) - { - char buf[1023]; - wsprintf(buf,"going from %d to %d",lp,g_db_offset+offset); - MessageBox(NULL,buf,"seeking back",MB_OK); - } - */ - SetSelfFilePointer(g_db_offset+offset,FILE_BEGIN); + SetSelfFilePointer(g_blocks[NB_DATA].offset+offset); } if (!ReadSelfFile((LPVOID)&input_len,sizeof(int))) return -3; @@ -302,8 +312,12 @@ int NSISCALL _dodecomp(int offset, HANDLE hFileOut, char *outbuf, int outbuflen) #ifdef NSIS_CONFIG_COMPRESSION_SUPPORT if (input_len & 0x80000000) // compressed { + char progress[64]; + int input_len_total; + DWORD ltc = GetTickCount(), tc; + inflateReset(&g_inflate_stream); - input_len &= 0x7fffffff; // take off top bit. + input_len_total = input_len &= 0x7fffffff; // take off top bit. while (input_len > 0) { @@ -328,6 +342,14 @@ int NSISCALL _dodecomp(int offset, HANDLE hFileOut, char *outbuf, int outbuflen) u=(char*)g_inflate_stream.next_out - outbuffer; + tc = GetTickCount(); + if (tc - ltc > 200 || !input_len) + { + wsprintf(progress, "... %d%%", MulDiv(input_len_total - input_len, 100, input_len_total)); + update_status_text(0, progress); + ltc = tc; + } + if (!u) break; if (!outbuf) @@ -386,7 +408,7 @@ static int NSISCALL __ensuredata(int amount) int needed=amount-(dbd_size-dbd_pos); if (needed>0) { - SetSelfFilePointer(dbd_srcpos,FILE_BEGIN); + SetSelfFilePointer(dbd_srcpos); SetFilePointer(dbd_hFile,dbd_size,NULL,FILE_BEGIN); m_length=needed; m_pos=0; @@ -402,9 +424,9 @@ static int NSISCALL __ensuredata(int amount) { DWORD r,t; #ifdef NSIS_CONFIG_VISIBLE_SUPPORT - if (g_inst_cmnheader) + if (g_header) #ifdef NSIS_CONFIG_SILENT_SUPPORT - if (!(inst_flags&(CH_FLAGS_SILENT|CH_FLAGS_SILENT_LOG))) + if (!g_exec_flags.silent) #endif { if (hwnd) { @@ -412,13 +434,13 @@ static int NSISCALL __ensuredata(int amount) m_pos=m_length-(amount-(dbd_size-dbd_pos)); while (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) DispatchMessage(&msg); } - else if (g_hwnd && GetTickCount() > verify_time) + else if (GetTickCount() > verify_time) hwnd = CreateDialogParam( g_hInstance, MAKEINTRESOURCE(IDD_VERIFY), 0, verProc, - (LPARAM)_LANG_UNPACKING + g_hwnd ? 0 : (LPARAM)_LANG_UNPACKING ); } #endif//NSIS_CONFIG_VISIBLE_SUPPORT @@ -458,7 +480,7 @@ int NSISCALL _dodecomp(int offset, HANDLE hFileOut, char *outbuf, int outbuflen) int retval; if (offset>=0) { - dbd_pos=g_db_offset+offset; + dbd_pos=g_blocks[NB_DATA].offset+offset; SetFilePointer(dbd_hFile,dbd_pos,NULL,FILE_BEGIN); } retval=__ensuredata(sizeof(int)); @@ -499,7 +521,7 @@ BOOL NSISCALL ReadSelfFile(LPVOID lpBuffer, DWORD nNumberOfBytesToRead) return ReadFile(g_db_hFile,lpBuffer,nNumberOfBytesToRead,&rd,NULL) && (rd == nNumberOfBytesToRead); } -DWORD NSISCALL SetSelfFilePointer(LONG lDistanceToMove, DWORD dwMoveMethod) +DWORD NSISCALL SetSelfFilePointer(LONG lDistanceToMove) { - return SetFilePointer(g_db_hFile,lDistanceToMove,NULL,dwMoveMethod); + return SetFilePointer(g_db_hFile,lDistanceToMove,NULL,FILE_BEGIN); } diff --git a/Source/exehead/fileform.h b/Source/exehead/fileform.h index 7cf12c87..696a7f11 100644 --- a/Source/exehead/fileform.h +++ b/Source/exehead/fileform.h @@ -4,22 +4,23 @@ #define _FILEFORM_H_ -// stored in file: -// exehead (~34k) -// firstheader (~28 bytes) -// hdrinfo (4 bytes describing length/compression):: -// (if install) -// header (~228 bytes) -// sections (20 bytes each) -// (if uninstall) -// uninstall_header (~116 bytes) -// pages (12 bytes each) -// entries (24 bytes each) -// string table -// language tables -// datablock -// (hdrinfo+datablock is at least 512 bytes if CRC enabled) +// * the installer is compsed of the following parts: +// exehead (~34kb) +// firstheader (struct firstheader) +// * headers (compressed together): +// header (struct header) +// * nsis blocks (described in header->blocks) +// pages (struct page) +// section headers (struct section) +// entries/instructions (struct entry) +// strings (null seperated) +// language tables (language id, dialog offset, language strings) +// colors (struct color) +// data block (files and uninstaller data) +// * not compressed // CRC (optional - 4 bytes) +// +// headers + datablock is at least 512 bytes if CRC enabled #define MAX_ENTRY_OFFSETS 6 @@ -92,8 +93,7 @@ enum #ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT EW_GETDLGITEM, // GetDlgItem: 3: [outputvar, dialog, item_id] - EW_GETWINTEXT, // GetWindowText: 2: [outputvar, hwnd] - EW_SETBKCOLOR, // SerBkColor: 2: [hwnd, color] + EW_SETCTLCOLORS, // SerCtlColors: 3: [hwnd, pointer to struct colors] EW_SETBRANDINGIMAGE, // SetBrandingImage: 1: [Bitmap file] EW_CREATEFONT, // CreateFont: 5: [handle output, face name, height, weight, flags] EW_SHOWWINDOW, // ShowWindow: 2: [hwnd, show state] @@ -211,96 +211,6 @@ typedef struct int length_of_all_following_data; } firstheader; -// Strings common to both installers and uninstallers -typedef struct -{ - int name; // name of installer - - // unprocessed strings -#ifdef NSIS_CONFIG_VISIBLE_SUPPORT - int branding; - int backbutton; - int nextbutton; - int cancelbutton; - int showdetailsbutton; - int closebutton; // "Close" - int completed; - - int copy_details; - - int byte; - int kilo; - int mega; - int giga; - - // processed strings - int subcaptions[5]; -#endif - int caption; // name of installer + " Setup" or whatever. - -#ifdef NSIS_SUPPORT_FILE - int fileerrtext; - int fileerrtext_noignore; -#endif - -#if defined(NSIS_SUPPORT_DELETE) || defined(NSIS_SUPPORT_RMDIR) || defined(NSIS_SUPPORT_FILE) - int cant_write; -#endif -#ifdef NSIS_SUPPORT_RMDIR - int remove_dir; -#endif -#ifdef NSIS_SUPPORT_COPYFILES - int copy_failed; - int copy_to; -#endif -#ifdef NSIS_SUPPORT_ACTIVEXREG - int registering; - int unregistering; - int symbol_not_found; - int could_not_load; - int no_ole; - // not used anywhere - int err_reg_dll; -#endif -#ifdef NSIS_SUPPORT_CREATESHORTCUT - int create_shortcut; - int err_creating_shortcut; -#endif -#ifdef NSIS_SUPPORT_DELETE - int del_file; -#ifdef NSIS_SUPPORT_MOVEONREBOOT - int del_on_reboot; -#endif -#endif -#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT - int created_uninst; - int err_creating; -#endif -#ifdef NSIS_SUPPORT_SHELLEXECUTE - int exec_shell; -#endif -#ifdef NSIS_SUPPORT_EXECUTE - int exec; -#endif -#ifdef NSIS_SUPPORT_MOVEONREBOOT - int rename_on_reboot; -#endif -#ifdef NSIS_SUPPORT_RENAME - int rename; -#endif -#ifdef NSIS_SUPPORT_FILE - int extract; - int err_writing; - int err_decompressing; - int skipped; -#endif - int inst_corrupted; - int output_dir; - int create_dir; -#ifdef NSIS_CONFIG_LOG - int log_install_process; -#endif -} common_strings; - // Flags for common_header.flags #define CH_FLAGS_DETAILS_SHOWDETAILS 1 #define CH_FLAGS_DETAILS_NEVERSHOW 2 @@ -316,25 +226,54 @@ typedef struct #define CH_FLAGS_COMP_ONLY_ON_CUSTOM 256 #define CH_FLAGS_NO_CUSTOM 512 #endif -#ifdef NSIS_CONFIG_LICENSEPAGE - #define CH_FLAGS_LICENSE_FORCE_SELECTION 1024 + +// nsis blocks +struct block_header { + int offset; + int num; +}; + +enum { +#ifdef NSIS_CONFIG_VISIBLE_SUPPORT + NB_PAGES, #endif + NB_SECTIONS, + NB_ENTRIES, + NB_STRINGS, + NB_LANGTABLES, + NB_CTLCOLORS, + NB_DATA, + + BLOCKS_NUM +}; // Settings common to both installers and uninstallers typedef struct { - int language_tables_num; // number of strings tables in array - int language_table_size; // size of each language table + int flags; // CH_FLAGS_* + struct block_header blocks[BLOCKS_NUM]; - int num_entries; // total number of entries - int num_string_bytes; // total number of bytes taken by strings - - int num_pages; // number of used pages (including custom pages) + // InstallDirRegKey stuff + int install_reg_rootkey; + // these two are not processed! + int install_reg_key_ptr, install_reg_value_ptr; #ifdef NSIS_SUPPORT_BGBG int bg_color1, bg_color2, bg_textcolor; #endif - int lb_bg, lb_fg, license_bg; + +#ifdef NSIS_CONFIG_VISIBLE_SUPPORT + // installation log window colors + int lb_bg, lb_fg; +#endif + + // langtable size + int langtable_size; + +#ifdef NSIS_CONFIG_LICENSEPAGE + // license background color + int license_bg; +#endif//NSIS_CONFIG_LICENSEPAGE #ifdef NSIS_SUPPORT_CODECALLBACKS // .on* calls @@ -346,69 +285,6 @@ typedef struct int code_onGUIInit; int code_onGUIEnd; #endif -#endif//NSIS_SUPPORT_CODECALLBACKS - - int flags; // CH_FLAGS_* -} common_header; - -// Strings specific to installers -typedef struct -{ - // these first strings are literals (should not be encoded) -#ifdef NSIS_CONFIG_VISIBLE_SUPPORT - int browse; // "Browse..." - int installbutton; // "Install" - int spacerequired; // "Space required: " - int spaceavailable; // "Space available: " - int custom; // Custom - int text; // directory page text - int dirsubtext; // directory text2 -#ifdef NSIS_CONFIG_COMPONENTPAGE - int componenttext; // component page text - int componentsubtext[4]; -#endif -#ifdef NSIS_CONFIG_LICENSEPAGE - int licensetext; // license page text - int licensedata; // license text - int licensebutton; // license button text - int licensebuttonagree; // agree check box/radio button - int licensebuttondisagree; // disagree check box/radio button -#endif//NSIS_CONFIG_LICENSEPAGE -#else - int foo; -#endif -} installer_strings; - -// Settings specific to installers -typedef struct -{ - // common settings - common_header common; - - int install_reg_rootkey; - // these two are not processed! - int install_reg_key_ptr, install_reg_value_ptr; - -#ifdef NSIS_CONFIG_COMPONENTPAGE - int install_types[NSIS_MAX_INST_TYPES+1]; -#endif - -#ifdef NSIS_CONFIG_LICENSEPAGE - int license_bg; // license background color -#endif//NSIS_CONFIG_LICENSEPAGE - - int install_directory_ptr; // default install dir. - int install_directory_auto_append; // auto append part - -#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT - int uninstdata_offset; // -1 if no uninst data. - int uninsticon_size; -#endif - - int num_sections; // total number of sections - -#ifdef NSIS_SUPPORT_CODECALLBACKS - // .on* calls int code_onVerifyInstDir; #ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT int code_onMouseOverSection; @@ -417,26 +293,20 @@ typedef struct int code_onSelChange; #endif//NSIS_CONFIG_COMPONENTPAGE #endif//NSIS_SUPPORT_CODECALLBACKS + +#ifdef NSIS_CONFIG_COMPONENTPAGE + int install_types[NSIS_MAX_INST_TYPES+1]; +#endif + + int install_directory_ptr; // default install dir. + int install_directory_auto_append; // auto append part + +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT + int uninstdata_offset; // -1 if no uninst data. + int uninsticon_size; +#endif } header; -// Strings specific to uninstallers -typedef struct -{ - int uninstbutton; - int uninstalltext; - int uninstalltext2; -} uninstall_strings; - -// Settings specific to uninstallers -typedef struct -{ - // common settings - common_header common; - - int code; - int code_size; -} uninstall_header; - // used for section->flags #define SF_SELECTED 1 #define SF_SUBSEC 2 @@ -462,36 +332,77 @@ typedef struct int offsets[MAX_ENTRY_OFFSETS]; // count and meaning of offsets depend on 'which' } entry; +// page window proc enum { - NSIS_PAGE_CUSTOM = -1, #ifdef NSIS_CONFIG_LICENSEPAGE - NSIS_PAGE_LICENSE, + PWP_LICENSE, #endif #ifdef NSIS_CONFIG_COMPONENTPAGE - NSIS_PAGE_SELCOM, + PWP_SELCOM, #endif - NSIS_PAGE_DIR, - NSIS_PAGE_INSTFILES, - NSIS_PAGE_COMPLETED, + PWP_DIR, + PWP_INSTFILES, #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT - NSIS_PAGE_UNINST + PWP_UNINST, #endif + PWP_COMPLETED, + PWP_CUSTOM }; +// page flags +#define PF_BACK_ENABLE 256 +#define PF_NEXT_ENABLE 2 +#define PF_CANCEL_ENABLE 4 +#define PF_BACK_SHOW 8 // must be SW_SHOWNA, don't change +#define PF_LICENSE_STREAM 16 +#define PF_LICENSE_FORCE_SELECTION 32 +#define PF_LICENSE_NO_FORCE_SELECTION 64 +#define PF_LICENSE_SELECTED 1 // must be 1 +#define PF_NO_NEXT_FOCUS 128 +#define PF_PAGE_EX 512 + typedef struct { - int id; // index in the pages array + int dlg_id; // dialog resource id + int wndproc_id; + #ifdef NSIS_SUPPORT_CODECALLBACKS - int prefunc; // called before the page is created, or if custom to show the it. Allows to skip the page using Abort. - int showfunc; // function to do stuff right before page is shown - int leavefunc; // function to do stuff after the page is shown + // called before the page is created, or if custom to show the page + // use Abort to skip the page + int prefunc; + // called right before page is shown + int showfunc; + // called when the user leaves to the next page + // use Abort to force the user to stay on this page + int leavefunc; #endif //NSIS_SUPPORT_CODECALLBACKS - int caption; // caption tab + + int flags; + + int caption; + int back; int next; - int button_states; + int clicknext; + int cancel; + + int parms[5]; } page; +#define CC_TEXT 1 +#define CC_TEXT_SYS 2 +#define CC_BK 4 +#define CC_BK_SYS 8 +#define CC_BKB 16 + +typedef struct { + COLORREF text; + LOGBRUSH bk; + HBRUSH bkb; + int bkmode; + int flags; +} ctlcolors; + // the following are only used/implemented in exehead, not makensis. int NSISCALL isheader(firstheader *h); // returns 0 on not header, length_of_datablock on success @@ -510,9 +421,8 @@ int NSISCALL _dodecomp(int offset, HANDLE hFileOut, char *outbuf, int outbuflen) extern HANDLE g_db_hFile; extern int g_quit_flag; -const char * NSISCALL GetStringFromStringTab(int offs); BOOL NSISCALL ReadSelfFile(LPVOID lpBuffer, DWORD nNumberOfBytesToRead); -DWORD NSISCALL SetSelfFilePointer(LONG lDistanceToMove, DWORD dwMoveMethod); +DWORD NSISCALL SetSelfFilePointer(LONG lDistanceToMove); // $0..$9, $INSTDIR, etc are encoded as ASCII bytes starting from this value. // Added by ramon 3 jun 2003 @@ -539,7 +449,7 @@ DWORD NSISCALL SetSelfFilePointer(LONG lDistanceToMove, DWORD dwMoveMethod); #endif #endif -union installer_flags { +union exec_flags { struct { int autoclose; int all_user_var; @@ -550,8 +460,39 @@ union installer_flags { #endif int cur_insttype; int insttype_changed; +#ifdef NSIS_CONFIG_SILENT_SUPPORT + int silent; +#endif }; int flags[1]; }; +#ifdef EXEHEAD +extern struct block_header g_blocks[BLOCKS_NUM]; +extern header *g_header; +extern int g_flags; +extern int g_filehdrsize; +extern int g_is_uninstaller; + +#define g_pages ((page*)g_blocks[NB_PAGES].offset) +#define g_sections ((section*)g_blocks[NB_SECTIONS].offset) +#define num_sections (g_blocks[NB_SECTIONS].num) +#define g_entries ((entry*)g_blocks[NB_ENTRIES].offset) +/*extern int num_sections; + +//extern int g_autoclose; +extern void *g_inst_combinedheader; +extern page *g_inst_page; +extern section *g_inst_section; +extern entry *g_inst_entry; + +#define g_inst_header ((header *)g_inst_combinedheader) +#define g_inst_cmnheader ((common_header *)g_inst_combinedheader) + +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT +#define g_inst_uninstheader ((uninstall_header *)g_inst_combinedheader) +extern int g_is_uninstaller; +#endif*/ +#endif + #endif //_FILEFORM_H_ diff --git a/Source/exehead/lang.h b/Source/exehead/lang.h index aa5c6389..32ecdc61 100644 --- a/Source/exehead/lang.h +++ b/Source/exehead/lang.h @@ -24,99 +24,43 @@ #define _LANG_GENERIC_ERROR "NSIS ERROR" +#define LANG_STR_TAB(x) cur_langtable[-((int)x+1)] -// Changed by Amir Szekely 3rd August 2002 -// Now supports more than one language in each installer - -// Modified by Dave Laundon 10th August 2002 -// In many places, these strings are now referenced by an ID (just their offsets -// into the (common|installer|uninstall)_strings structures) through *_from_lang -// and *FromLang functions - removing code-costly references to the -// cur_(common|install|uninstall)_strings_table globals. Common strings are -// identified by IDs >=0 and install/uninstall strings by IDs <0. What's more, -// these IDs fall between -128 to +127 and compile to tiny 2-byte PUSH <8-bit> -// instructions when being passed to the functions. - -// Please note that all LANG_* define the offset not the string itself. -// To get the string itself use process_string_fromtab, GetStringFromStringTab or LANG_STR(). - -#define LANG_STR(x) GetStringFromStringTab(x) -#define LANG_STR_TAB(x) cur_language_table[-((int)x+1)] - -#define INSTALL_STR(x) (~((sizeof(common_strings) + FIELD_OFFSET(installer_strings, x)) / sizeof(int))) - -// Installer specific strings -#define LANG_BTN_BROWSE (INSTALL_STR(browse)) -#define LANG_BTN_INSTALL (INSTALL_STR(installbutton)) -#define LANG_SPACE_REQ (INSTALL_STR(spacerequired)) -#define LANG_SPACE_AVAIL (INSTALL_STR(spaceavailable)) -#define LANG_COMP_CUSTOM (INSTALL_STR(custom)) -#define LANG_DIR_TEXT (INSTALL_STR(text)) -#define LANG_DIR_SUBTEXT (INSTALL_STR(dirsubtext)) -#define LANG_COMP_TEXT (INSTALL_STR(componenttext)) -#define LANG_COMP_SUBTEXT(x) (INSTALL_STR(componentsubtext[x])) -#define LANG_LICENSE_TEXT (INSTALL_STR(licensetext)) -#define LANG_LICENSE_DATA (INSTALL_STR(licensedata)) -#define LANG_BTN_LICENSE (INSTALL_STR(licensebutton)) -#define LANG_BTN_LICENSE_AGREE (INSTALL_STR(licensebuttonagree)) -#define LANG_BTN_LICENSE_DISAGREE (INSTALL_STR(licensebuttondisagree)) - -#define UNINSTALL_STR(x) (~((sizeof(common_strings) + FIELD_OFFSET(uninstall_strings, x)) / sizeof(int))) - -// Uninstall specific strings -#define LANG_BTN_UNINST (UNINSTALL_STR(uninstbutton)) -#define LANG_UNINST_TEXT (UNINSTALL_STR(uninstalltext)) -#define LANG_UNINST_SUBTEXT (UNINSTALL_STR(uninstalltext2)) - -#define COMMON_STR(x) (~(FIELD_OFFSET(common_strings, x) / sizeof(int))) - -// Common strings -#define LANG_BTN_NEXT (COMMON_STR(nextbutton)) -#define LANG_BTN_BACK (COMMON_STR(backbutton)) -#define LANG_BRANDING (COMMON_STR(branding)) -#define LANG_BTN_CANCEL (COMMON_STR(cancelbutton)) -#define LANG_BTN_DETAILS (COMMON_STR(showdetailsbutton)) -#define LANG_COMPLETED (COMMON_STR(completed)) -#define LANG_BTN_CLOSE (COMMON_STR(closebutton)) -#define LANG_NAME (COMMON_STR(name)) -#define LANG_CAPTION (COMMON_STR(caption)) -#define LANG_SUBCAPTION(x) (COMMON_STR(subcaptions[x])) -#define LANG_INSTCORRUPTED (COMMON_STR(inst_corrupted)) -#define LANG_COPYDETAILS (COMMON_STR(copy_details)) -#define LANG_LOG_INSTALL_PROCESS (COMMON_STR(log_install_process)) -#define LANG_BYTE (COMMON_STR(byte)) -#define LANG_KILO (COMMON_STR(kilo)) -#define LANG_MEGA (COMMON_STR(mega)) -#define LANG_GIGA (COMMON_STR(giga)) - -// instruction strings -#define LANG_FILEERR (COMMON_STR(fileerrtext)) -#define LANG_FILEERR_NOIGNORE (COMMON_STR(fileerrtext_noignore)) -#define LANG_DELETEFILE (COMMON_STR(del_file)) -#define LANG_DLLREGERROR (COMMON_STR(err_reg_dll)) -#define LANG_REMOVEDIR (COMMON_STR(remove_dir)) -#define LANG_OUTPUTDIR (COMMON_STR(output_dir)) -#define LANG_CREATEDIR (COMMON_STR(create_dir)) -#define LANG_RENAME (COMMON_STR(rename)) -#define LANG_RENAMEONREBOOT (COMMON_STR(rename_on_reboot)) -#define LANG_SKIPPED (COMMON_STR(skipped)) -#define LANG_CANTWRITE (COMMON_STR(cant_write)) -#define LANG_EXTRACT (COMMON_STR(extract)) -#define LANG_ERRORWRITING (COMMON_STR(err_writing)) -#define LANG_ERRORDECOMPRESSING (COMMON_STR(err_decompressing)) -#define LANG_DELETEONREBOOT (COMMON_STR(del_on_reboot)) -#define LANG_EXECSHELL (COMMON_STR(exec_shell)) -#define LANG_EXECUTE (COMMON_STR(exec)) -#define LANG_CANNOTFINDSYMBOL (COMMON_STR(symbol_not_found)) -#define LANG_COULDNOTLOAD (COMMON_STR(could_not_load)) -#define LANG_NOOLE (COMMON_STR(no_ole)) -#define LANG_ERRORCREATINGSHORTCUT (COMMON_STR(err_creating_shortcut)) -#define LANG_CREATESHORTCUT (COMMON_STR(create_shortcut)) -#define LANG_COPYTO (COMMON_STR(copy_to)) -#define LANG_COPYFAILED (COMMON_STR(copy_failed)) -#define LANG_ERRORCREATING (COMMON_STR(err_creating)) -#define LANG_CREATEDUNINST (COMMON_STR(created_uninst)) -#define LANG_REGISTERING (COMMON_STR(registering)) -#define LANG_UNREGISTERING (COMMON_STR(unregistering)) +#define LANG_BRANDING -1 +#define LANG_CAPTION -2 +#define LANG_NAME -3 +#define LANG_SPACE_AVAIL -4 +#define LANG_SPACE_REQ -5 +#define LANG_CANTWRITE -6 +#define LANG_COPYFAILED -7 +#define LANG_COPYTO -8 +#define LANG_CANNOTFINDSYMBOL -9 +#define LANG_COULDNOTLOAD -10 +#define LANG_CREATEDIR -11 +#define LANG_CREATESHORTCUT -12 +#define LANG_CREATEDUNINST -13 +#define LANG_DELETEFILE -14 +#define LANG_DELETEONREBOOT -15 +#define LANG_ERRORCREATINGSHORTCUT -16 +#define LANG_ERRORCREATING -17 +#define LANG_ERRORDECOMPRESSING -18 +#define LANG_DLLREGERROR -19 +#define LANG_EXECSHELL -20 +#define LANG_EXECUTE -21 +#define LANG_EXTRACT -22 +#define LANG_ERRORWRITING -23 +#define LANG_INSTCORRUPTED -24 +#define LANG_NOOLE -25 +#define LANG_OUTPUTDIR -26 +#define LANG_REMOVEDIR -27 +#define LANG_RENAMEONREBOOT -28 +#define LANG_RENAME -29 +#define LANG_SKIPPED -30 +#define LANG_COPYDETAILS -31 +#define LANG_LOG_INSTALL_PROCESS -32 +#define LANG_BYTE -33 +#define LANG_KILO -34 +#define LANG_MEGA -35 +#define LANG_GIGA -36 #endif//_NSIS_LANG_H_ diff --git a/Source/exehead/resource.h b/Source/exehead/resource.h index 9b1233dc..df080c82 100644 --- a/Source/exehead/resource.h +++ b/Source/exehead/resource.h @@ -8,6 +8,8 @@ #define IDC_BACK 3 #define IDD_LICENSE 102 +#define IDD_LICENSE_FSRB 108 +#define IDD_LICENSE_FSCB 109 #define IDI_ICON2 103 #define IDD_DIR 103 #define IDD_SELCOM 104 @@ -15,7 +17,7 @@ #define IDD_INSTFILES 106 #define IDD_UNINST 107 #define IDD_VERIFY 111 -#define IDB_BITMAP1 109 +#define IDB_BITMAP1 110 #define IDC_EDIT1 1000 #define IDC_BROWSE 1001 #define IDC_PROGRESS 1004 diff --git a/Source/exehead/resource.rc b/Source/exehead/resource.rc index e4807741..b8c3eeb9 100644 --- a/Source/exehead/resource.rc +++ b/Source/exehead/resource.rc @@ -28,57 +28,97 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_LICENSEPAGE) #if defined(APSTUDIO_INVOKED) -IDD_LICENSE$(NSIS_CONFIG_LICENSEPAGE) DIALOGEX DISCARDABLE 0, 0, 266, 130 +IDD_LICENSE$(NSIS_CONFIG_LICENSEPAGE) DIALOGEX 0, 0, 266, 130 #else -IDD_LICENSE DIALOGEX DISCARDABLE 0, 0, 266, 130 +IDD_LICENSE DIALOGEX 0, 0, 266, 130 #endif -STYLE DS_CONTROL | DS_SHELLFONT | WS_CHILD -FONT 8, "MS Shell Dlg" +STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - ICON IDI_ICON2,IDC_ULICON,0,0,20,20 + ICON IDI_ICON2,IDC_ULICON,0,0,22,20 LTEXT "",IDC_INTROTEXT,25,0,241,23 CONTROL "",IDC_EDIT1,"RichEdit20A",WS_BORDER | WS_VSCROLL | 0x804,0,24,266,105 END #endif +#if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_LICENSEPAGE) +#if defined(APSTUDIO_INVOKED) +IDD_LICENSE_FSRB$(NSIS_CONFIG_LICENSEPAGE) DIALOG DISCARDABLE 0, 0, 266, 130 +#else +IDD_LICENSE_FSRB DIALOG DISCARDABLE 0, 0, 266, 130 +#endif +STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CAPTION +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_ICON2,1031,0,0,22,20 + LTEXT "",IDC_INTROTEXT,25,0,241,23 + CONTROL "",IDC_EDIT1,"RichEdit20A",WS_BORDER | WS_VSCROLL | + 0x804,0,24,266,85 + CONTROL "",IDC_LICENSEDISAGREE,"Button",BS_AUTORADIOBUTTON | + WS_TABSTOP,0,120,266,9 + CONTROL "",IDC_LICENSEAGREE,"Button",BS_AUTORADIOBUTTON | + WS_TABSTOP,0,110,266,9 +END +#endif + +#if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_LICENSEPAGE) +#if defined(APSTUDIO_INVOKED) +IDD_LICENSE_FSCB$(NSIS_CONFIG_LICENSEPAGE) DIALOG DISCARDABLE 0, 0, 266, 130 +#else +IDD_LICENSE_FSCB DIALOG DISCARDABLE 0, 0, 266, 130 +#endif +STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CAPTION +FONT 8, "MS Shell Dlg" +BEGIN + ICON IDI_ICON2,1031,0,0,22,20 + LTEXT "",IDC_INTROTEXT,25,0,241,23 + CONTROL "",IDC_EDIT1,"RichEdit20A",WS_BORDER | WS_VSCROLL | + 0x804,0,24,266,95 + CONTROL "",IDC_LICENSEAGREE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,0,120,266,9 +END +#endif + #if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_VISIBLE_SUPPORT) #if defined(APSTUDIO_INVOKED) -IDD_DIR$(NSIS_CONFIG_VISIBLE_SUPPORT) DIALOGEX DISCARDABLE 0, 0, 266, 130 +IDD_DIR$(NSIS_CONFIG_VISIBLE_SUPPORT) DIALOGEX 0, 0, 266, 130 #else -IDD_DIR DIALOGEX DISCARDABLE 0, 0, 266, 130 +IDD_DIR DIALOGEX 0, 0, 266, 130 #endif -STYLE DS_CONTROL | DS_SHELLFONT | WS_CHILD -FONT 8, "MS Shell Dlg" +STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN EDITTEXT IDC_DIR,8,49,187,12,ES_AUTOHSCROLL PUSHBUTTON "",IDC_BROWSE,202,48,55,14 - ICON IDI_ICON2,IDC_ULICON,0,0,20,20 - CONTROL "",IDC_SELDIRTEXT,"Static",SS_LEFTNOWORDWRAP, - 0,36,265,8 - CONTROL "",IDC_SPACEAVAILABLE,"Static",SS_LEFTNOWORDWRAP,0,122,265,8 + ICON IDI_ICON2,IDC_ULICON,0,0,22,20 + + CONTROL "",IDC_SPACEAVAILABLE,"Static",SS_LEFTNOWORDWRAP,0,122, + 265,8 CONTROL "",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | - WS_TABSTOP,8,65,118,10 - CONTROL "",IDC_SPACEREQUIRED,"Static",SS_LEFTNOWORDWRAP,0,111,265,8 + WS_TABSTOP,8,71,118,10 + CONTROL "",IDC_SPACEREQUIRED,"Static",SS_LEFTNOWORDWRAP,0,111, + 265,8 LTEXT "",IDC_INTROTEXT,25,0,241,34 + GROUPBOX "",IDC_SELDIRTEXT,1,38,264,30 END #endif #if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_COMPONENTPAGE) #if defined(APSTUDIO_INVOKED) -IDD_SELCOM$(NSIS_CONFIG_COMPONENTPAGE) DIALOGEX DISCARDABLE 0, 0, 266, 130 +IDD_SELCOM$(NSIS_CONFIG_COMPONENTPAGE) DIALOGEX 0, 0, 266, 130 #else -IDD_SELCOM DIALOGEX DISCARDABLE 0, 0, 266, 130 +IDD_SELCOM DIALOGEX 0, 0, 266, 130 #endif -STYLE DS_CONTROL | DS_SHELLFONT | WS_CHILD -FONT 8, "MS Shell Dlg" +STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - COMBOBOX IDC_COMBO1,114,25,152,102,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP | NOT WS_VISIBLE - ICON IDI_ICON2,IDC_ULICON,0,0,21,20 + COMBOBOX IDC_COMBO1,114,25,152,102,CBS_DROPDOWNLIST | NOT + WS_VISIBLE | WS_VSCROLL | WS_TABSTOP + ICON IDI_ICON2,IDC_ULICON,0,0,22,20 LTEXT "",IDC_TEXT2,0,40,108,65 CONTROL "",IDC_TEXT1,"Static",SS_LEFTNOWORDWRAP,0,27,108,8 - CONTROL "",IDC_SPACEREQUIRED,"Static",SS_LEFT,0,111,111,18 + LTEXT "",IDC_SPACEREQUIRED,0,111,111,18,NOT WS_GROUP LTEXT "",IDC_INTROTEXT,25,0,241,25 CONTROL "",IDC_TREE1,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP | @@ -88,53 +128,55 @@ END #if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_VISIBLE_SUPPORT) #if defined(APSTUDIO_INVOKED) -IDD_INST$(NSIS_CONFIG_VISIBLE_SUPPORT) DIALOGEX DISCARDABLE 0, 0, 280, 162 +IDD_INST$(NSIS_CONFIG_VISIBLE_SUPPORT) DIALOGEX 0, 0, 280, 162 #else -IDD_INST DIALOGEX DISCARDABLE 0, 0, 280, 162 +IDD_INST DIALOGEX 0, 0, 280, 162 #endif -STYLE DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_BORDER -FONT 8, "MS Shell Dlg" +STYLE DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | + WS_SYSMENU +FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - PUSHBUTTON "",IDC_BACK,171,142,50,14,WS_GROUP | NOT WS_VISIBLE + PUSHBUTTON "",IDC_BACK,171,142,50,14,NOT WS_VISIBLE | WS_GROUP PUSHBUTTON "",IDOK,223,142,50,14 PUSHBUTTON "",IDCANCEL,7,142,50,14 - CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ | WS_GROUP,7,138,267,1 - CONTROL "",IDC_CHILDRECT,"Static",SS_BLACKRECT | NOT WS_VISIBLE | WS_GROUP, - 7,6,266,130 - CTEXT "",IDC_VERSTR,59,145,108,8,WS_DISABLED | WS_GROUP + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ | WS_GROUP,7,138, + 267,1 + CONTROL "",IDC_CHILDRECT,"Static",SS_BLACKRECT | NOT WS_VISIBLE | + WS_GROUP,7,6,266,130 + CTEXT "",IDC_VERSTR,59,145,108,8,WS_DISABLED END #endif #if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_VISIBLE_SUPPORT) #if defined(APSTUDIO_INVOKED) -IDD_INSTFILES$(NSIS_CONFIG_VISIBLE_SUPPORT) DIALOGEX DISCARDABLE 0, 0, 266, 130 +IDD_INSTFILES$(NSIS_CONFIG_VISIBLE_SUPPORT) DIALOGEX 0, 0, 266, 130 #else -IDD_INSTFILES DIALOGEX DISCARDABLE 0, 0, 266, 130 +IDD_INSTFILES DIALOGEX 0, 0, 266, 130 #endif -STYLE DS_CONTROL | DS_SHELLFONT | WS_CHILD -FONT 8, "MS Shell Dlg" +STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - CONTROL "",IDC_PROGRESS,"msctls_progress32",WS_BORDER,24,10,241,11 - CONTROL "",IDC_INTROTEXT,"Static",SS_LEFTNOWORDWRAP, - 24,0,241,8 + CONTROL "",IDC_PROGRESS,"msctls_progress32",WS_BORDER,24,10,241, + 11 + CONTROL "",IDC_INTROTEXT,"Static",SS_LEFTNOWORDWRAP,24,0,241,8 CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_NOCOLUMNHEADER | NOT WS_VISIBLE | WS_BORDER | WS_TABSTOP,0,25,265,104 - ICON IDI_ICON2,IDC_ULICON,0,0,20,20 + ICON IDI_ICON2,IDC_ULICON,0,0,22,20 PUSHBUTTON "",IDC_SHOWDETAILS,0,28,60,14,NOT WS_TABSTOP END #endif #if defined(APSTUDIO_INVOKED) || defined(_NSIS_CONFIG_UNINSTDLG) #if defined(APSTUDIO_INVOKED) -IDD_UNINST$(_NSIS_CONFIG_UNINSTDLG) DIALOGEX DISCARDABLE 0, 0, 266, 130 +IDD_UNINST$(_NSIS_CONFIG_UNINSTDLG) DIALOGEX 0, 0, 266, 130 #else -IDD_UNINST DIALOGEX DISCARDABLE 0, 0, 266, 130 +IDD_UNINST DIALOGEX 0, 0, 266, 130 #endif -STYLE DS_CONTROL | DS_SHELLFONT | WS_CHILD -FONT 8, "MS Shell Dlg" +STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - ICON IDI_ICON2,IDC_ULICON,0,1,20,20 + ICON IDI_ICON2,IDC_ULICON,0,1,22,20 LTEXT "",IDC_UNINSTFROM,0,45,55,8 EDITTEXT IDC_EDIT1,56,43,209,12,ES_AUTOHSCROLL | ES_READONLY LTEXT "",IDC_INTROTEXT,25,0,241,34 @@ -143,12 +185,12 @@ END #if defined(APSTUDIO_INVOKED) || defined(_NSIS_CONFIG_VERIFYDIALOG) #if defined(APSTUDIO_INVOKED) -IDD_VERIFY$(_NSIS_CONFIG_VERIFYDIALOG) DIALOGEX DISCARDABLE 0, 0, 162, 22 +IDD_VERIFY$(_NSIS_CONFIG_VERIFYDIALOG) DIALOGEX 0, 0, 162, 22 #else -IDD_VERIFY DIALOGEX DISCARDABLE 0, 0, 162, 22 +IDD_VERIFY DIALOGEX 0, 0, 162, 22 #endif -STYLE DS_MODALFRAME | DS_SHELLFONT | DS_CENTER | WS_POPUP | WS_VISIBLE -FONT 8, "MS Shell Dlg" +STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP +FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN CTEXT "",IDC_STR,7,7,148,8 END diff --git a/Source/exehead/state.h b/Source/exehead/state.h index 26089951..3beff527 100644 --- a/Source/exehead/state.h +++ b/Source/exehead/state.h @@ -1,33 +1,22 @@ #ifdef NSIS_SUPPORT_NAMED_USERVARS extern NSIS_STRING g_usrvars[TOTAL_COMPATIBLE_STATIC_VARS_COUNT]; - #define state_command_line g_usrvars[20] - #define state_install_directory g_usrvars[21] - #define state_output_directory g_usrvars[22] - #define state_exe_directory g_usrvars[23] - #define state_language g_usrvars[24] - #ifdef NSIS_CONFIG_PLUGIN_SUPPORT - #define state_plugins_dir g_usrvars[25] - #endif - #define state_temp_dir g_usrvars[32] #else - extern char temp_directory[NSIS_MAX_STRLEN]; extern char g_usrvars[USER_VARS_COUNT][NSIS_MAX_STRLEN]; - extern char *state_command_line; - extern char *state_install_directory; - extern char *state_output_directory; - extern char *state_exe_directory; - extern char *state_language; - #ifdef NSIS_CONFIG_PLUGIN_SUPPORT - extern char *state_plugins_dir; - #endif - #define state_temp_dir temp_directory +#endif + +#define state_command_line g_usrvars[20] +#define state_install_directory g_usrvars[21] +#define state_output_directory g_usrvars[22] +#define state_exe_directory g_usrvars[23] +#define state_language g_usrvars[24] +#define state_temp_dir g_usrvars[25] +#define state_click_next g_usrvars[26] +#ifdef NSIS_CONFIG_PLUGIN_SUPPORT + #define state_plugins_dir g_usrvars[27] #endif extern char g_caption[NSIS_MAX_STRLEN*2]; extern HWND g_hwnd; -extern int g_filehdrsize; extern HANDLE g_hInstance; extern HWND insthwnd,insthwndbutton; -extern HICON g_hIcon; - -extern int inst_flags; \ No newline at end of file +extern HICON g_hIcon; \ No newline at end of file diff --git a/Source/exehead/ui.h b/Source/exehead/ui.h index 2dc4e540..34889620 100644 --- a/Source/exehead/ui.h +++ b/Source/exehead/ui.h @@ -1,29 +1,11 @@ #ifndef _UI_H_ #define _UI_H_ -// Added by Amir Szekely 3rd August 2002 -extern char *language_tables; -extern int *cur_language_table; +extern int *cur_langtable; int NSISCALL ui_doinstall(void); -void NSISCALL update_status_text_from_lang(int id, const char *text2); -void NSISCALL update_status_text(const char *text1, const char *text2); +void NSISCALL update_status_text(int strtab, const char *text2); extern int ui_st_updateflag; -extern int num_sections; - -//extern int g_autoclose; -extern void *g_inst_combinedheader; -extern page *g_inst_page; -extern section *g_inst_section; -extern entry *g_inst_entry; - -#define g_inst_header ((header *)g_inst_combinedheader) -#define g_inst_cmnheader ((common_header *)g_inst_combinedheader) - -#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT -#define g_inst_uninstheader ((uninstall_header *)g_inst_combinedheader) -extern int g_is_uninstaller; -#endif #ifdef NSIS_CONFIG_LOG void NSISCALL build_g_logfile(void); diff --git a/Source/exehead/util.c b/Source/exehead/util.c index e74035c8..89554a8d 100644 --- a/Source/exehead/util.c +++ b/Source/exehead/util.c @@ -37,6 +37,7 @@ char g_log_file[1024]; #ifdef NSIS_CONFIG_PLUGIN_SUPPORT char *state_plugins_dir=g_usrvars[25]; #endif + char *state_plugins_dir=g_usrvars[36]; #endif HANDLE g_hInstance; @@ -109,7 +110,7 @@ void NSISCALL doRMDir(char *buf, int flags) // 1 - recurse, 2 - rebootok else if (!RemoveDirectory(buf) && flags&2) { log_printf2("Remove folder on reboot: %s",buf); #ifdef NSIS_SUPPORT_REBOOT - g_flags.exec_reboot++; + g_exec_flags.exec_reboot++; #endif MoveFileOnReboot(buf,0); } @@ -163,7 +164,7 @@ int NSISCALL is_valid_instpath(char *s) { int ivp=0; // if CH_FLAGS_NO_ROOT_DIR is set, req is 0, which means rootdirs are not allowed. - int req=!(inst_flags&CH_FLAGS_NO_ROOT_DIR); + int req=!(g_flags&CH_FLAGS_NO_ROOT_DIR); if (*(WORD*)s == CHAR2_TO_WORD('\\','\\')) // \\ path { if (lastchar(s)!='\\') ivp++; @@ -243,7 +244,7 @@ char * NSISCALL my_GetTempFileName(char *buf, const char *dir) BOOL NSISCALL MoveFileOnReboot(LPCTSTR pszExisting, LPCTSTR pszNew) { BOOL fOk = 0; - HMODULE hLib=LoadLibrary("kernel32.dll"); + HMODULE hLib=GetModuleHandle("kernel32.dll"); if (hLib) { typedef BOOL (WINAPI *mfea_t)(LPCSTR lpExistingFileName,LPCSTR lpNewFileName,DWORD dwFlags); @@ -253,7 +254,6 @@ BOOL NSISCALL MoveFileOnReboot(LPCTSTR pszExisting, LPCTSTR pszNew) { fOk=mfea(pszExisting, pszNew, MOVEFILE_DELAY_UNTIL_REBOOT|MOVEFILE_REPLACE_EXISTING); } - FreeLibrary(hLib); } if (!fOk) @@ -270,7 +270,7 @@ BOOL NSISCALL MoveFileOnReboot(LPCTSTR pszExisting, LPCTSTR pszNew) if (pszNew) { // create the file if it's not already there to prevent GetShortPathName from failing - CloseHandle(myOpenFile(pszNew, 0, CREATE_NEW)); + CloseHandle(myOpenFile(pszNew,0,CREATE_NEW)); GetShortPathName(pszNew,tmpbuf,1024); } // wininit is used as a temporary here @@ -307,11 +307,11 @@ BOOL NSISCALL MoveFileOnReboot(LPCTSTR pszExisting, LPCTSTR pszNew) char *pszNextSec = mystrstr(pszFirstRenameLine,"\n["); if (pszNextSec) { - int l=dwFileSize - (pszNextSec - pszWinInit); - void* data=(void*)my_GlobalAlloc(l); - mini_memcpy(data, pszNextSec, l); - mini_memcpy(pszNextSec + cchRenameLine, data, l); - GlobalFree((HGLOBAL)data); + char *p = ++pszNextSec; + while (p < pszWinInit + dwFileSize) { + p[cchRenameLine] = *p; + p++; + } dwRenameLinePos = pszNextSec - pszWinInit; } @@ -351,21 +351,11 @@ void NSISCALL myRegGetStr(HKEY root, const char *sub, const char *name, char *ou } } -char ps_tmpbuf[NSIS_MAX_STRLEN*2]; - -char * NSISCALL process_string_fromtab(char *out, int offs) +void NSISCALL myitoa(char *s, int d) { -#ifdef NSIS_SUPPORT_LANG_IN_STRINGS - char *p=process_string(GetStringFromStringTab(offs), 0); -#else - char *p=process_string(GetStringFromStringTab(offs)); -#endif - if (!out) return p; - return lstrcpyn(out,p,NSIS_MAX_STRLEN); + wsprintf(s,"%d",d); } -void NSISCALL myitoa(char *s, int d) { wsprintf(s,"%d",d); } - int NSISCALL myatoi(char *s) { unsigned int v=0; @@ -419,18 +409,20 @@ int NSISCALL mystrlen(const char *in) return lstrlen(in); } -// Dave Laundon's simplified process_string -#ifdef NSIS_SUPPORT_LANG_IN_STRINGS -char * NSISCALL process_string(const char *in, int iStartIdx ) -#else -char * NSISCALL process_string(const char *in) -#endif +char ps_tmpbuf[NSIS_MAX_STRLEN*2]; + +// Based on Dave Laundon's simplified process_string +char * NSISCALL GetNSISString(char *outbuf, int strtab) { -#ifdef NSIS_SUPPORT_LANG_IN_STRINGS - char *out = ps_tmpbuf+iStartIdx; -#else - char *out = ps_tmpbuf; -#endif + char *in = (char*)GetNSISStringNP(GetNSISTab(strtab)); + char *out; + if (outbuf >= ps_tmpbuf && outbuf < ps_tmpbuf+sizeof(ps_tmpbuf)) + { + out = outbuf; + outbuf = 0; + } + else + out = ps_tmpbuf; while (*in && out - ps_tmpbuf < NSIS_MAX_STRLEN) { int nVarIdx = (unsigned char)*in++; @@ -446,9 +438,9 @@ char * NSISCALL process_string(const char *in) #ifdef NSIS_SUPPORT_LANG_IN_STRINGS else if (nVarIdx == LANG_CODES_START) { - nVarIdx = *(short*)in; in+=sizeof(WORD); - process_string(GetStringFromStringTab(nVarIdx), out-ps_tmpbuf); - out+=mystrlen(out); + nVarIdx = *(short*)in; in+=sizeof(short); + GetNSISString(out, nVarIdx); + out+=mystrlen(out); } #endif else @@ -485,22 +477,24 @@ char * NSISCALL process_string(const char *in) case VAR_CODES_START + 23: // OUTDIR case VAR_CODES_START + 24: // EXEDIR case VAR_CODES_START + 25: // LANGUAGE - case VAR_CODES_START + 26: // PLUGINSDIR + case VAR_CODES_START + 26: // TEMP + case VAR_CODES_START + 27: // _CLICK + case VAR_CODES_START + 28: // PLUGINSDIR mystrcpy(out, g_usrvars[nVarIdx - (VAR_CODES_START + 1)]); break; - case VAR_CODES_START + 27: // PROGRAMFILES + case VAR_CODES_START + 29: // PROGRAMFILES smwcvesf[41]=0; myRegGetStr(HKEY_LOCAL_MACHINE, smwcvesf, "ProgramFilesDir", out); if (!*out) mystrcpy(out, "C:\\Program Files"); break; - case VAR_CODES_START + 28: // SMPROGRAMS - case VAR_CODES_START + 29: // SMSTARTUP - case VAR_CODES_START + 30: // DESKTOP - case VAR_CODES_START + 31: // STARTMENU - case VAR_CODES_START + 32: // QUICKLAUNCH + case VAR_CODES_START + 30: // SMPROGRAMS + case VAR_CODES_START + 31: // SMSTARTUP + case VAR_CODES_START + 32: // DESKTOP + case VAR_CODES_START + 33: // STARTMENU + case VAR_CODES_START + 34: // QUICKLAUNCH { static const char *tab[]={ "Programs", @@ -510,9 +504,9 @@ char * NSISCALL process_string(const char *in) "AppData" }; static char name[20]="Common "; - const char *name_=tab[nVarIdx-(VAR_CODES_START+28)]; + const char *name_=tab[nVarIdx-(VAR_CODES_START+30)]; mystrcpy(name+7,name_); - f=g_flags.all_user_var & (nVarIdx != VAR_CODES_START + 32); + f=g_exec_flags.all_user_var & (nVarIdx != VAR_CODES_START + 34); again: @@ -529,7 +523,7 @@ char * NSISCALL process_string(const char *in) mystrcpy(out,temp_directory); } - if (nVarIdx == VAR_CODES_START + 32) { + if (nVarIdx == VAR_CODES_START + 34) { lstrcat(out, "\\Microsoft\\Internet Explorer\\Quick Launch"); f = GetFileAttributes(out); if (f != (DWORD)-1 && (f & FILE_ATTRIBUTE_DIRECTORY)) @@ -538,24 +532,25 @@ char * NSISCALL process_string(const char *in) else break; } - case VAR_CODES_START + 33: // TEMP + case VAR_CODES_START + 35: // TEMP mystrcpy(out,temp_directory); break; - case VAR_CODES_START + 34: // WINDIR + case VAR_CODES_START + 36: // WINDIR GetWindowsDirectory(out, NSIS_MAX_STRLEN); break; - case VAR_CODES_START + 35: // SYSDIR + case VAR_CODES_START + 37: // SYSDIR GetSystemDirectory(out, NSIS_MAX_STRLEN); break; - #if VAR_CODES_START + 35 >= 255 + #if VAR_CODES_START + 37 >= 255 #error "Too many variables! Extend VAR_CODES_START!" #endif } // switch // validate the directory name - if (nVarIdx > 21+VAR_CODES_START ) { // only if not $0 to $R9, $CMDLINE, or $HWNDPARENT + if (nVarIdx > 21+VAR_CODES_START && nVarIdx != VAR_CODES_START+27) { + // only if not $0 to $R9, $CMDLINE, $HWNDPARENT, or $_CLICK // ($LANGUAGE can't have trailing backslash anyway...) validate_filename(out); } @@ -574,18 +569,18 @@ char * NSISCALL process_string(const char *in) nVarIdx = (*(WORD*)in & 0x0FFF)-1; in+=sizeof(WORD); switch (nVarIdx) // The order of this list must match that in ..\strlist.cpp (err, build.cpp -J) { - case 26: // PROGRAMFILES + case 28: // PROGRAMFILES smwcvesf[41]=0; myRegGetStr(HKEY_LOCAL_MACHINE, smwcvesf, "ProgramFilesDir", out); if (!*out) mystrcpy(out, "C:\\Program Files"); break; - case 27: // SMPROGRAMS - case 28: // SMSTARTUP - case 29: // DESKTOP - case 30: // STARTMENU - case 31: // QUICKLAUNCH + case 29: // SMPROGRAMS + case 30: // SMSTARTUP + case 31: // DESKTOP + case 32: // STARTMENU + case 33: // QUICKLAUNCH { static const char *tab[]={ "Programs", @@ -595,9 +590,9 @@ char * NSISCALL process_string(const char *in) "AppData" }; static char name[20]="Common "; - const char *name_=tab[nVarIdx-27]; + const char *name_=tab[nVarIdx-29]; mystrcpy(name+7,name_); - f=g_flags.all_user_var & (nVarIdx != 31); + f=g_exec_flags.all_user_var & (nVarIdx != 33); again: @@ -614,7 +609,7 @@ char * NSISCALL process_string(const char *in) mystrcpy(out,state_temp_dir); } - if (nVarIdx == 31) { + if (nVarIdx == 33) { lstrcat(out, "\\Microsoft\\Internet Explorer\\Quick Launch"); f = GetFileAttributes(out); if (f != (DWORD)-1 && (f & FILE_ATTRIBUTE_DIRECTORY)) @@ -623,15 +618,15 @@ char * NSISCALL process_string(const char *in) else break; } - case 33: // WINDIR + case 34: // WINDIR GetWindowsDirectory(out, NSIS_MAX_STRLEN); break; - case 34: // SYSDIR + case 35: // SYSDIR GetSystemDirectory(out, NSIS_MAX_STRLEN); break; - case 35: // HWNDPARENT + case 36: // HWNDPARENT myitoa(out, (unsigned int)g_hwnd); break; @@ -639,17 +634,18 @@ char * NSISCALL process_string(const char *in) mystrcpy(out, g_usrvars[nVarIdx]); } // switch // validate the directory name - if (nVarIdx > 21 && nVarIdx < TOTAL_COMPATIBLE_STATIC_VARS_COUNT ) { // only if not $0 to $R9, $CMDLINE, or $HWNDPARENT and not great than $SYSDIR + if (nVarIdx > 20 && nVarIdx < TOTAL_COMPATIBLE_STATIC_VARS_COUNT && nVarIdx != 26) { + // only if not $0 to $R9, $CMDLINE or $_CLICK and not great than $HWNDPARENT // ($LANGUAGE can't have trailing backslash anyway...) validate_filename(out); } out+=mystrlen(out); } // == VAR_CODES_START #ifdef NSIS_SUPPORT_LANG_IN_STRINGS - else if ( nVarIdx == LANG_CODES_START ) + else if (nVarIdx == LANG_CODES_START) { - nVarIdx = *(short*)in; in+=sizeof(WORD); - process_string(GetStringFromStringTab(nVarIdx), out-ps_tmpbuf); + nVarIdx = *(short*)in; in+=sizeof(short); + GetNSISString(out, nVarIdx); out+=mystrlen(out); } #endif @@ -660,6 +656,8 @@ char * NSISCALL process_string(const char *in) #endif } // while *out = 0; + if (outbuf) + return lstrcpyn(outbuf, ps_tmpbuf, NSIS_MAX_STRLEN); return ps_tmpbuf; } diff --git a/Source/exehead/util.h b/Source/exehead/util.h index fb054382..b04d4991 100644 --- a/Source/exehead/util.h +++ b/Source/exehead/util.h @@ -1,12 +1,10 @@ #include "config.h" extern char ps_tmpbuf[NSIS_MAX_STRLEN*2]; -#ifdef NSIS_SUPPORT_LANG_IN_STRINGS -char * NSISCALL process_string(const char *in, int iStartIdx); -#else -char * NSISCALL process_string(const char *in); -#endif -char * NSISCALL process_string_fromtab(char *out, int offs); +char * NSISCALL GetNSISString(char *outbuf, int strtab); +#define GetNSISStringTT(strtab) GetNSISString(0, (strtab)) +#define GetNSISStringNP(strtab) ((const char *)g_blocks[NB_STRINGS].offset+(strtab)) +#define GetNSISTab(strtab) (strtab < 0 ? LANG_STR_TAB(strtab) : strtab) void NSISCALL myRegGetStr(HKEY root, const char *sub, const char *name, char *out); int NSISCALL myatoi(char *s); void NSISCALL myitoa(char *s, int d); diff --git a/Source/lang.cpp b/Source/lang.cpp index 3e7c409e..79f1f94c 100644 --- a/Source/lang.cpp +++ b/Source/lang.cpp @@ -4,290 +4,307 @@ #include "build.h" #include "DialogTemplate.h" #include "exehead\resource.h" -#include "exehead\lang.h" extern const char *NSIS_VERSION; -char *english_strings[] = { - "Nullsoft Install System %s", - "%s Setup", - "%s Uninstall", - ": License Agreement", - ": Installation Options", - ": Installation Folder", - ": Installing", - ": Completed", - ": Confirmation", - ": Uninstalling", - ": Completed", - "< &Back", - "&Next >", - "I &Agree", - "I &accept the terms in the License Agreement", - "I &do not accept the terms in the License Agreement", - "&Install", - "&Uninstall", - "Cancel", - "&Close", - "B&rowse...", - "Show &details", - "Name", - "Completed", - "Custom", - "Select the type of install:", - "Select components to install:", - "Or, select the optional components you wish to install:", - "Select the folder to install %s in:", - "Space available: ", - "Space required: ", - "Uninstalling from:", - "Error opening file for writing: \r\n\t\"$0\"\r\nHit abort to abort installation,\r\nretry to retry writing the file, or\r\nignore to skip this file", - "Error opening file for writing: \r\n\t\"$0\"\r\nHit retry to retry writing the file, or\r\ncancel to abort installation", - "Can't write: ", - "Copy failed", - "Copy to ", - "Registering: ", - "Unregistering: ", - "Could not find symbol: ", - "Could not load: ", - "Create folder: ", - "Create shortcut: ", - "Created uninstaller: ", - "Delete file: ", - "Delete on reboot: ", - "Error creating shortcut: ", - "Error creating: ", - "Error decompressing data! Corrupted installer?", - "Error registering DLL", - "ExecShell: ", - "Execute: ", - "Extract: ", - "Extract: error writing to file ", - "Installer corrupted: invalid opcode", - "No OLE for: ", - "Output folder: ", - "Remove folder: ", - "Rename on reboot: ", - "Rename: ", - "Skipped: ", - "Copy Details To Clipboard", - "Log install process", - "B", - "K", - "M", - "G" +// Default English strings. Should match NSIS_DEFAULT_LANG +// Do not change the first string in every item, it's the LangString +// name for usage in scripts. + +typedef enum { + NONE_STATIC = 0, + INSTALL_STATIC = 1, + UNINSTALL_STATIC = 2, + BOTH_STATIC = 3 +} STATICID; + +struct { + char *szLangStringName; + char *szDefault; + STATICID eStaticID; +} NLFStrings[NLF_STRINGS] = { + {"^Branding", "Nullsoft Install System %s", BOTH_STATIC}, + {"^SetupCaption", "$(^Name) Setup", INSTALL_STATIC}, + {"^UninstallCaption", "$(^Name) Uninstall", UNINSTALL_STATIC}, + {"^LicenseSubCaption", ": License Agreement", NONE_STATIC}, + {"^ComponentsSubCaption", ": Installation Options", NONE_STATIC}, + {"^DirSubCaption", ": Installation Folder", NONE_STATIC}, + {"^InstallingSubCaption", ": Installing", NONE_STATIC}, + {"^CompletedSubCaption", ": Completed", NONE_STATIC}, + {"^UnComponentsSubCaption", ": Uninstallation Options", NONE_STATIC}, + {"^UnDirSubCaption", ": Uninstallation Folder", NONE_STATIC}, + {"^ConfirmSubCaption", ": Confirmation", NONE_STATIC}, + {"^UninstallingSubCaption", ": Uninstalling", NONE_STATIC}, + {"^UnCompletedSubCaption", ": Completed", NONE_STATIC}, + {"^BackBtn", "< &Back", NONE_STATIC}, + {"^NextBtn", "&Next >", NONE_STATIC}, + {"^AgreeBtn", "I &Agree", NONE_STATIC}, + {"^AcceptBtn", "I &accept the terms in the License Agreement", NONE_STATIC}, + {"^DontAcceptBtn", "I &do not accept the terms in the License Agreement", NONE_STATIC}, + {"^InstallBtn", "&Install", NONE_STATIC}, + {"^UninstallBtn", "&Uninstall", NONE_STATIC}, + {"^CancelBtn", "Cancel", NONE_STATIC}, + {"^CloseBtn", "&Close", NONE_STATIC}, + {"^BrowseBtn", "B&rowse...", NONE_STATIC}, + {"^ShowDetailsBtn", "Show &details", NONE_STATIC}, + {"^ClickNext", "Click Next to continue.", NONE_STATIC}, + {"^ClickInstall", "Click Install to start the installation.", NONE_STATIC}, + {"^ClickUninstall", "Click Uninstall to start the uninstallation.", NONE_STATIC}, + {"^Name", "Name", BOTH_STATIC}, + {"^Completed", "Completed", NONE_STATIC}, + {"^LicenseText", "Please review the license agreement before installing $(^Name). If you accept all terms of the agreement, click I Agree.", NONE_STATIC}, + {"^LicenseTextCB", "Please review the license agreement before installing $(^Name). If you accept all terms of the agreement, click the check box below. $_CLICK", NONE_STATIC}, + {"^LicesnseTextRB", "Please review the license agreement before installing $(^Name). If you accept all terms of the agreement, select the first option below. $_CLICK", NONE_STATIC}, + {"^UnLicenseText", "Please review the license agreement before uninstalling $(^Name). If you accept all terms of the agreement, click I Agree.", NONE_STATIC}, + {"^UnLicenseTextCB", "Please review the license agreement before uninstalling $(^Name). If you accept all terms of the agreement, click the check box below. $_CLICK", NONE_STATIC}, + {"^UnLicesnseTextRB", "Please review the license agreement before uninstalling $(^Name). If you accept all terms of the agreement, select the first option below. $_CLICK", NONE_STATIC}, + {"^LicenseData", 0, NONE_STATIC}, // virtual - not processed + {"^Custom", "Custom", NONE_STATIC}, + {"^ComponentsText", "Check the components you want to install and uncheck the components you don't want to install. $_CLICK", NONE_STATIC}, + {"^ComponentsSubText1", "Select the type of install:", NONE_STATIC}, + {"^ComponentsSubText2_NoInstTypes", "Select components to install:", NONE_STATIC}, + {"^ComponentsSubText2", "Or, select the optional components you wish to install:", NONE_STATIC}, + {"^UnComponentsText", "Check the components you want to uninstall and uncheck the components you don't want to uninstall. $_CLICK", NONE_STATIC}, + {"^UnComponentsSubText1", "Select the type of uninstall:", NONE_STATIC}, + {"^UnComponentsSubText2_NoInstTypes", "Select components to uninstall:", NONE_STATIC}, + {"^UnComponentsSubText2", "Or, select the optional components you wish to uninstall:", NONE_STATIC}, + {"^DirText", "Setup will install $(^Name) in the following folder. To install in a different folder, click Browse and select another folder. $_CLICK", NONE_STATIC}, + {"^DirSubText", "Destination Folder", NONE_STATIC}, + {"^DirBrowseText", "Select the folder to install $(^Name) in:", NONE_STATIC}, + {"^UnDirText", "Setup will uninstall $(^Name) from the following folder. To uninstall from a different folder, click Browse and select another folder. $_CLICK", NONE_STATIC}, + {"^UnDirSubText", "", NONE_STATIC}, + {"^UnDirBrowseText", "Select the folder to uninstall $(^Name) from:", NONE_STATIC}, + {"^SpaceAvailable", "Space available: ", BOTH_STATIC}, + {"^SpaceRequired", "Space required: ", BOTH_STATIC}, + {"^UninstallingText", "This wizard will uninstall $(^Name) from your computer. $_CLICK", NONE_STATIC}, + {"^UninstallingSubText", "Uninstalling from:", NONE_STATIC}, + {"^FileError", "Error opening file for writing: \r\n\t\"$0\"\r\nHit abort to abort installation,\r\nretry to retry writing the file, or\r\nignore to skip this file", NONE_STATIC}, + {"^FileError_NoIgnore", "Error opening file for writing: \r\n\t\"$0\"\r\nHit retry to retry writing the file, or\r\ncancel to abort installation", NONE_STATIC}, + {"^CantWrite", "Can't write: ", BOTH_STATIC}, + {"^CopyFailed", "Copy failed", BOTH_STATIC}, + {"^CopyTo", "Copy to ", BOTH_STATIC}, + {"^Registering", "Registering: ", NONE_STATIC}, + {"^Unregistering", "Unregistering: ", NONE_STATIC}, + {"^SymbolNotFound", "Could not find symbol: ", BOTH_STATIC}, + {"^CouldNotLoad", "Could not load: ", BOTH_STATIC}, + {"^CreateFolder", "Create folder: ", BOTH_STATIC}, + {"^CreateShortcut", "Create shortcut: ", BOTH_STATIC}, + {"^CreatedUninstaller", "Created uninstaller: ", BOTH_STATIC}, + {"^Delete", "Delete file: ", BOTH_STATIC}, + {"^DeleteOnReboot", "Delete on reboot: ", BOTH_STATIC}, + {"^ErrorCreatingShortcut", "Error creating shortcut: ", BOTH_STATIC}, + {"^ErrorCreating", "Error creating: ", BOTH_STATIC}, + {"^ErrorDecompressing", "Error decompressing data! Corrupted installer?", BOTH_STATIC}, + {"^ErrorRegistering", "Error registering DLL", BOTH_STATIC}, + {"^ExecShell", "ExecShell: ", BOTH_STATIC}, + {"^Exec", "Execute: ", BOTH_STATIC}, + {"^Extract", "Extract: ", BOTH_STATIC}, + {"^ErrorWriting", "Extract: error writing to file ", BOTH_STATIC}, + {"^InvalidOpcode", "Installer corrupted: invalid opcode", BOTH_STATIC}, + {"^NoOLE", "No OLE for: ", BOTH_STATIC}, + {"^OutputFolder", "Output folder: ", BOTH_STATIC}, + {"^RemoveFolder", "Remove folder: ", BOTH_STATIC}, + {"^RenameOnReboot", "Rename on reboot: ", BOTH_STATIC}, + {"^Rename", "Rename: ", BOTH_STATIC}, + {"^Skipped", "Skipped: ", BOTH_STATIC}, + {"^CopyDetails", "Copy Details To Clipboard", BOTH_STATIC}, + {"^LogInstall", "Log install process", BOTH_STATIC}, + {"^Byte", "B", BOTH_STATIC}, + {"^Kilo", "K", BOTH_STATIC}, + {"^Mega", "M", BOTH_STATIC}, + {"^Giga", "G", BOTH_STATIC}, + {"^RTL", "0", NONE_STATIC} }; -StringTable* CEXEBuild::GetTable(LANGID &lang) { - lang=lang?lang:last_used_lang; - last_used_lang=lang; - StringTable *table = 0; - for (unsigned int i = 0; i < string_tables.size(); i++) { - if (lang == string_tables[i]->lang_id) { - table = string_tables[i]; +void CEXEBuild::InitLangTables() { + keep_ref = false; + + for (int i = 0; i < NLF_STRINGS; i++) { + NLFRefs[i].iRef = 0; + NLFRefs[i].iUnRef = 0; + +#ifdef NSIS_CONFIG_LOG + if (i == NLF_NAME) { + NLFRefs[i].iRef++; + NLFRefs[i].iUnRef++; + } +#endif + + if (NLFStrings[i].eStaticID & INSTALL_STATIC) { + set_uninstall_mode(0); + DefineLangString(NLFStrings[i].szLangStringName); + } + +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT + if (NLFStrings[i].eStaticID & UNINSTALL_STATIC) { + set_uninstall_mode(1); + DefineLangString(NLFStrings[i].szLangStringName); + } +#endif + } + + set_uninstall_mode(0); + + keep_ref = true; +} + +LanguageTable* CEXEBuild::GetLangTable(LANGID &lang) { + int nlt = lang_tables.getlen() / sizeof(LanguageTable); + LanguageTable *nla = (LanguageTable*)lang_tables.get(); + + lang = lang ? lang : last_used_lang; + last_used_lang = lang; + LanguageTable *table = 0; + + for (int i = 0; i < nlt; i++) { + if (lang == nla[i].lang_id) { + table = &nla[i]; break; } } if (!table) { - table = new StringTable; - if (!table) { - ERROR_MSG("Internal compiler error #12345: malloc(%d) failed\n",sizeof(StringTable)); - return 0; - } - table->dlg_offset = 0; - memset(&(table->common), 0, sizeof(common_strings)); - memset(&(table->ucommon), 0, sizeof(common_strings)); - memset(&(table->installer), 0, sizeof(installer_strings)); - memset(&(table->uninstall), 0, sizeof(uninstall_strings)); - table->nlf = 0; + LanguageTable newtable; - table->lang_id = lang; + newtable.lang_id = lang; + newtable.dlg_offset = 0; + memset(&newtable.nlf, 0, sizeof(NLF)); - table->user_strings.set_zeroing(1); - table->user_strings.resize(build_userlangstrings.getnum()*sizeof(int)); + newtable.lang_strings = new StringsArray; - table->user_ustrings.set_zeroing(1); - table->user_ustrings.resize(ubuild_userlangstrings.getnum()*sizeof(int)); - - string_tables.push_back(table); + lang_tables.add(&newtable, sizeof(LanguageTable)); + table = (LanguageTable*)lang_tables.get() + nlt; } return table; } -int CEXEBuild::SetString(char *string, int id, int process, LANGID lang/*=0*/) { - StringTable *table = GetTable(lang); +int CEXEBuild::DefineLangString(char *name, int process/*=-1*/) { + int index, uindex, pos, ret, sn; + pos = build_langstrings.get(name, &sn, &index, &uindex); + if (pos < 0) { + pos = build_langstrings.add(name); + } + +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT + if (!uninstall_mode) { +#endif + if (index < 0) { + index = build_langstring_num++; + } + ret = -index - 1; +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT + } + else { + if (uindex < 0) { + uindex = ubuild_langstring_num++; + } + ret = -uindex - 1; + } +#endif + + build_langstrings.set(pos, index, uindex, process); + + // set reference count for NLF strings + if (keep_ref && name[0] == '^') { + for (int i = 0; i < NLF_STRINGS; i++) { + if (!strcmp(name, NLFStrings[i].szLangStringName)) { +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT + if (uninstall_mode) + NLFRefs[i].iUnRef++; + else +#endif + NLFRefs[i].iRef++; + + break; + } + } + } + + return ret; +} + +int CEXEBuild::DefineInnerLangString(int id, int process/*=-1*/) { + bool old_keep_ref = keep_ref; + + // set reference count for NLF strings + if (keep_ref) { +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT + if (uninstall_mode) + NLFRefs[id].iUnRef++; + else +#endif + NLFRefs[id].iRef++; + + keep_ref = false; + } + + int ret = DefineLangString(NLFStrings[id].szLangStringName, process); + + keep_ref = old_keep_ref; + + return ret; +} + +int CEXEBuild::SetLangString(char *name, LANGID lang, char *string) { + if (!string || !name) return PS_ERROR; + + LanguageTable *table = GetLangTable(lang); if (!table) return PS_ERROR; - return SetString(string, id, process, table); -} -int CEXEBuild::SetString(char *string, int id, int process, StringTable *table) { - int *str = 0; - int *ustr = 0; -#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT - #define HANDLE_STRING_C(id,strname) case id: str=&(table->strname); ustr=&(table->u##strname); break; -#else - #define HANDLE_STRING_C(id,strname) HANDLE_STRING_I(id,strname) -#endif - #define HANDLE_STRING_I(id,strname) case id: str=&(table->strname); break; -#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT - #define HANDLE_STRING_U(id,strname) case id: ustr=&(table->strname); break; -#endif - switch (id) { -#ifdef NSIS_CONFIG_VISIBLE_SUPPORT - HANDLE_STRING_C(NLF_COMPLETED, common.completed); - HANDLE_STRING_C(NLF_BTN_NEXT, common.nextbutton); - HANDLE_STRING_C(NLF_BTN_BACK, common.backbutton); - HANDLE_STRING_C(NLF_BRANDING, common.branding); - HANDLE_STRING_C(NLF_BTN_CANCEL, common.cancelbutton); - HANDLE_STRING_C(NLF_BTN_CLOSE, common.closebutton); - HANDLE_STRING_C(NLF_BTN_DETAILS, common.showdetailsbutton); - HANDLE_STRING_I(NLF_CAPTION, common.caption); - HANDLE_STRING_I(NLF_SUBCAPTION_LICENSE, common.subcaptions[0]); - HANDLE_STRING_I(NLF_SUBCAPTION_OPTIONS, common.subcaptions[1]); - HANDLE_STRING_I(NLF_SUBCAPTION_DIR, common.subcaptions[2]); - HANDLE_STRING_I(NLF_SUBCAPTION_INSTFILES, common.subcaptions[3]); - HANDLE_STRING_I(NLF_SUBCAPTION_COMPLETED, common.subcaptions[4]); - HANDLE_STRING_I(NLF_BTN_INSTALL, installer.installbutton); - HANDLE_STRING_I(NLF_BTN_BROWSE, installer.browse); -#ifdef NSIS_CONFIG_COMPONENTPAGE - HANDLE_STRING_I(NLF_COMP_SUBTEXT1, installer.componentsubtext[0]); - HANDLE_STRING_I(NLF_COMP_SUBTEXT2, installer.componentsubtext[1]); - HANDLE_STRING_I(SLANG_COMP_TEXT, installer.componenttext); -#endif -#ifdef NSIS_CONFIG_LICENSEPAGE - HANDLE_STRING_I(NLF_BTN_LICENSE, installer.licensebutton); - HANDLE_STRING_I(NLF_BTN_LICENSE_AGREE, installer.licensebuttonagree); - HANDLE_STRING_I(NLF_BTN_LICENSE_DISAGREE, installer.licensebuttondisagree); - HANDLE_STRING_I(SLANG_LICENSE_TEXT, installer.licensetext); - HANDLE_STRING_I(SLANG_LICENSE_DATA, installer.licensedata); -#endif - HANDLE_STRING_I(SLANG_DIR_TEXT, installer.text); - HANDLE_STRING_I(NLF_COMP_CUSTOM, installer.custom); - HANDLE_STRING_I(NLF_DIR_SUBTEXT, installer.dirsubtext); - HANDLE_STRING_I(NLF_SPACE_AVAIL, installer.spaceavailable); - HANDLE_STRING_I(NLF_SPACE_REQ, installer.spacerequired); -#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT - HANDLE_STRING_U(NLF_UCAPTION, ucommon.caption); - HANDLE_STRING_U(NLF_USUBCAPTION_CONFIRM, ucommon.subcaptions[0]); - HANDLE_STRING_U(NLF_USUBCAPTION_INSTFILES, ucommon.subcaptions[1]); - HANDLE_STRING_U(NLF_USUBCAPTION_COMPLETED, ucommon.subcaptions[2]); - HANDLE_STRING_U(NLF_BTN_UNINSTALL, uninstall.uninstbutton); - HANDLE_STRING_U(NLF_UNINST_SUBTEXT, uninstall.uninstalltext2); - HANDLE_STRING_U(SLANG_UNINST_TEXT, uninstall.uninstalltext); -#endif + int sn; -#endif //NSIS_CONFIG_VISIBLE_SUPPORT + int pos = build_langstrings.get(name, &sn); + if (pos < 0) + pos = build_langstrings.add(name, &sn); - HANDLE_STRING_C(SLANG_NAME, common.name); - -#ifdef NSIS_SUPPORT_FILE - HANDLE_STRING_C(NLF_FILE_ERROR, common.fileerrtext); - HANDLE_STRING_C(NLF_FILE_ERROR_NOIGNORE, common.fileerrtext_noignore); -#endif - - default: - ERROR_MSG("Error: string doesn't exist or is not changeable (%d)\n", id); - return PS_ERROR; - } - - if (str) *str = add_string_main(string,process); -#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT - if (ustr) *ustr = add_string_uninst(string,process); -#endif + if (table->lang_strings->set(sn, string)) + return PS_WARNING; return PS_OK; } -int CEXEBuild::GetUserString(char *name) { - LangStringList *user_strings_list = 0; +int CEXEBuild::SetInnerString(int id, char *string) { + if ((unsigned int)id >= NLF_STRINGS || !string) return PS_ERROR; - if (strnicmp(name,"un.",3)) { - user_strings_list=&build_userlangstrings; - } - else { - user_strings_list=&ubuild_userlangstrings; - } + int ret = PS_OK; - SetUserString(name, 0, 0, 0); + const char *ps = UserInnerStrings.get(id); + if (ps && *ps) + ret = PS_WARNING; - return user_strings_list->get(name); + UserInnerStrings.set(id, string); + + return ret; } -int CEXEBuild::SetUserString(char *name, LANGID lang, char *string, int process/*=1*/) { - StringTable *table = 0; - if (string) { - table = GetTable(lang); - if (!table) return PS_ERROR; - } - - TinyGrowBuf *user_strings = 0; - LangStringList *user_strings_list = 0; - bool uninst; - if (!(uninst = !strnicmp(name,"un.",3))) { - if (string) user_strings=&table->user_strings; - user_strings_list=&build_userlangstrings; - } - else { - if (string) user_strings=&table->user_ustrings; - user_strings_list=&ubuild_userlangstrings; - } - - int idx = user_strings_list->get(name); - if (idx < 0) { - // if lang string doesn't exist yet - idx = user_strings_list->add(name); - unsigned int new_size = user_strings_list->getnum() * sizeof(int); - for (unsigned int i = 0; i < string_tables.size(); i++) { - if (uninst) string_tables[i]->user_ustrings.resize(new_size); - else string_tables[i]->user_strings.resize(new_size); - } - } - - if (string) - ((int*)user_strings->get())[idx] = uninst ? add_string_uninst(string,process) : add_string_main(string,process); - - return PS_OK; -} - -bool CEXEBuild::_IsSet(int *str, LANGID lang) { - if (!str) return false; - lang = lang?lang:build_nlfs.size()?build_nlfs[build_nlfs.size()-1]->m_wLangId:0; - lang = lang?lang:string_tables.size()?string_tables[0]->lang_id:1033; // Default is English (1033) - unsigned int i; - for (i = 0; i < string_tables.size(); i++) { - if (lang == string_tables[i]->lang_id) { - break; - } - } - if (i == string_tables.size()) return false; - if (*(int*)(int(str)-int(string_tables[0])+int(string_tables[i]))) return true; - return false; -} - -int CEXEBuild::WriteStringTables() { +int CEXEBuild::GenerateLangTables() { int i; + LanguageTable *lt = (LanguageTable*)lang_tables.get(); SCRIPT_MSG("Generating language tables... "); // If we have no tables (user didn't set any string and didn't load any NLF) create the default one - if (!string_tables.size()) { - LANGID lang = 1033; - StringTable *table = GetTable(lang); + if (!lang_tables.getlen()) { + LANGID lang = NSIS_DEFAULT_LANG; + LanguageTable *table = GetLangTable(lang); if (!table) return PS_ERROR; + + lt = (LanguageTable*)lang_tables.get(); } // Fill tables with defaults (if needed) and with instruction strings // Create language specific resources (currently only dialogs with different fonts) - int st_num = string_tables.size(); + int num_lang_tables = lang_tables.getlen() / sizeof(LanguageTable); // if there is one string table then there is no need for two sets of dialogs - int cur_offset = st_num == 1 ? 0 : 100; - for (i = 0; i < st_num; i++) + int cur_offset = num_lang_tables == 1 ? 0 : 100; + for (i = 0; i < num_lang_tables; i++) { - FillStringTable(string_tables[i]); - if (string_tables[i]->nlf && string_tables[i]->nlf->m_szFont) + if (lt[i].nlf.m_bLoaded && (lt[i].nlf.m_szFont || lt[i].nlf.m_bRTL)) { - string_tables[i]->dlg_offset = cur_offset; + SCRIPT_MSG("RTLing...\n"); + lt[i].dlg_offset = cur_offset; + + char *font = lt[i].nlf.m_szFont; try { init_res_editor(); @@ -295,18 +312,21 @@ int CEXEBuild::WriteStringTables() { #define ADD_FONT(id) { \ BYTE* dlg = res_editor->GetResource(RT_DIALOG, MAKEINTRESOURCE(id), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)); \ if (dlg) { \ - CDialogTemplate td(dlg,string_tables[i]->nlf->m_uCodePage); \ + CDialogTemplate td(dlg,lt[i].nlf.m_uCodePage); \ free(dlg); \ - td.SetFont(string_tables[i]->nlf->m_szFont, string_tables[i]->nlf->m_iFontSize); \ + if (font) td.SetFont(font, lt[i].nlf.m_iFontSize); \ + if (lt[i].nlf.m_bRTL) td.ConvertToRTL(); \ DWORD dwSize; \ dlg = td.Save(dwSize); \ - res_editor->UpdateResource(RT_DIALOG, MAKEINTRESOURCE(id+cur_offset), string_tables[i]->lang_id, dlg, dwSize); \ + res_editor->UpdateResource(RT_DIALOG, MAKEINTRESOURCE(id+cur_offset), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), dlg, dwSize); \ free(dlg); \ } \ } #ifdef NSIS_CONFIG_LICENSEPAGE ADD_FONT(IDD_LICENSE); + ADD_FONT(IDD_LICENSE_FSRB); + ADD_FONT(IDD_LICENSE_FSCB); #endif ADD_FONT(IDD_DIR); #ifdef NSIS_CONFIG_COMPONENTPAGE @@ -323,7 +343,7 @@ int CEXEBuild::WriteStringTables() { #undef ADD_FONT } catch (exception& err) { - ERROR_MSG("Error while applying NLF font for %s: %s\n", err.what()); + ERROR_MSG("Error while applying NLF font/RTL for %s: %s\n", err.what()); return PS_ERROR; } @@ -331,365 +351,219 @@ int CEXEBuild::WriteStringTables() { } } - // check for missing LangStrings - int userstrings_num = build_userlangstrings.getnum(); - for (i = 0; i < userstrings_num; i++) { - int counter = 0; - for (int j = 0; j < st_num; j++) { - counter += !((int*)string_tables[j]->user_strings.get())[i]; + // Add language tables into their datablock + int j, l, cnt, tabsset; + struct langstring* lang_strings; + + i = num_lang_tables; + while (i--) { + build_langtables.add(<[i].lang_id, sizeof(LANGID)); + build_langtables.add(<[i].dlg_offset, sizeof(int)); + + int *lst = (int *)((char *)build_langtables.get() + build_langtables.getlen()); + cnt = 0; + tabsset = 1; + + // write langstrings + while (tabsset) { + FillLanguageTable(<[i]); + + int lastcnt = cnt; + cnt = 0; + tabsset = 0; + + lang_strings = build_langstrings.sort_index(&l); + + for (j = 0; j < l; j++) { + if (lang_strings[j].index >= 0) { + if (cnt >= lastcnt || !lst[lang_strings[j].index]) { + const char *str = lt[i].lang_strings->get(lang_strings[j].sn); + int tab = 0; + + const char *lsn = build_langstrings.offset2name(lang_strings[j].name); + + if (!str || !*str) { + if (lsn[0] != '^') + warning("LangString \"%s\" is not set in language table of language %d", lsn, lt[i].lang_id); + } + else { + char fn[1024]; + sprintf(fn, "LangString %s", lsn); + curfilename = fn; + linecnt = lt[i].lang_id; + + tab = add_string(str, lang_strings[j].process); + tabsset++; + + curfilename = 0; + } + + if (cnt < lastcnt) + lst[lang_strings[j].index] = tab; + else + build_langtables.add(&tab, sizeof(int)); + } + + cnt++; + } + } } - if (counter) { - char *name=build_userlangstrings.idx2name(i); - if (!name) continue; - warning("LangString \"%s\" is not present in all language tables!", name); + + // optimize langstrings and check for recursion + TinyGrowBuf rec; + for (j = 0; j < build_langstring_num; j++) { + while (lst[j] < 0) { + for (int k = 0; k < rec.getlen() / sizeof(int); k++) { + if (((int*)rec.get())[k] == lst[j]) { + const char *name = "(unnamed)"; + for (k = 0; k < l; k++) { + if (lang_strings[k].index == j) { + name = build_langstrings.offset2name(lang_strings[k].name); + } + } + ERROR_MSG("Error: LangString %s is recursive!\n", name); + return PS_ERROR; + } + } + rec.add(&lst[j], sizeof(int)); + lst[j] = lst[-lst[j] - 1]; + } + rec.resize(0); } } - int userustrings_num = ubuild_userlangstrings.getnum(); - for (i = 0; i < userustrings_num; i++) { - int counter = 0; - for (int j = 0; j < st_num; j++) { - counter += !((int*)string_tables[j]->user_ustrings.get())[i]; + build_header.blocks[NB_LANGTABLES].num = num_lang_tables; + build_header.langtable_size = build_langtables.getlen() / num_lang_tables; + +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT + set_uninstall_mode(1); + + i = num_lang_tables; + while (i--) { + ubuild_langtables.add(<[i].lang_id, sizeof(LANGID)); + ubuild_langtables.add(<[i].dlg_offset, sizeof(int)); + + int *lst = (int *)((char *)ubuild_langtables.get() + ubuild_langtables.getlen()); + cnt = 0; + tabsset = 1; + + int h = 0; + + // write langstrings + while (tabsset) { + FillLanguageTable(<[i]); + + int lastcnt = cnt; + cnt = 0; + tabsset = 0; + + if (h++ > 10) { + return PS_ERROR; + } + + lang_strings = build_langstrings.sort_uindex(&l); + + for (j = 0; j < l; j++) { + if (lang_strings[j].uindex >= 0) { + if (cnt >= lastcnt || !lst[lang_strings[j].uindex]) { + const char *str = lt[i].lang_strings->get(lang_strings[j].sn); + int tab = 0; + + const char *lsn = build_langstrings.offset2name(lang_strings[j].name); + + if (!str || !*str) { + if (lsn[0] != '^') + warning("LangString \"%s\" is not set in language table of language %d", lsn, lt[i].lang_id); + } + else { + char fn[1024]; + sprintf(fn, "LangString %s", lsn); + curfilename = fn; + linecnt = lt[i].lang_id; + + tab = add_string(str, lang_strings[j].process); + tabsset++; + + curfilename = 0; + } + + if (cnt < lastcnt) + lst[lang_strings[j].uindex] = tab; + else + ubuild_langtables.add(&tab, sizeof(int)); + } + + cnt++; + } + } } - if (counter) { - char *name=ubuild_userlangstrings.idx2name(i); - if (!name) continue; - warning("LangString \"%s\" is not present in all language tables!", name); + + // optimize langstrings and check for recursion + TinyGrowBuf rec; + for (j = 0; j < ubuild_langstring_num; j++) { + while (lst[j] < 0) { + for (int k = 0; k < rec.getlen() / sizeof(int); k++) { + if (((int*)rec.get())[k] == lst[j]) { + const char *name = "(unnamed)"; + for (k = 0; k < l; k++) { + if (lang_strings[k].uindex == j) { + name = build_langstrings.offset2name(lang_strings[k].name); + } + } + ERROR_MSG("Error: LangString %s is recursive!\n", name); + return PS_ERROR; + } + } + rec.add(&lst[j], sizeof(int)); + lst[j] = lst[-lst[j] - 1]; + } + rec.resize(0); } } - // Add string tables into their datablock - for (i = 0; i < st_num; i++) { - build_langtables.add(&string_tables[i]->lang_id, sizeof(LANGID)); - build_langtables.add(&string_tables[i]->dlg_offset, sizeof(int)); - build_langtables.add(&string_tables[i]->common, sizeof(common_strings)); - build_langtables.add(&string_tables[i]->installer, sizeof(installer_strings)); - if (build_userlangstrings.getnum()) - build_langtables.add(string_tables[i]->user_strings.get(), string_tables[i]->user_strings.getlen()); - } - build_header.common.language_tables_num = st_num; - build_header.common.language_table_size = build_langtables.getlen() / st_num; + build_uninst.blocks[NB_LANGTABLES].num = num_lang_tables; + build_uninst.langtable_size = ubuild_langtables.getlen() / num_lang_tables; - for (i = 0; i < st_num; i++) { - ubuild_langtables.add(&string_tables[i]->lang_id, sizeof(LANGID)); - ubuild_langtables.add(&string_tables[i]->dlg_offset, sizeof(int)); - ubuild_langtables.add(&string_tables[i]->ucommon, sizeof(common_strings)); - ubuild_langtables.add(&string_tables[i]->uninstall, sizeof(uninstall_strings)); - if (ubuild_userlangstrings.getnum()) - ubuild_langtables.add(string_tables[i]->user_ustrings.get(), string_tables[i]->user_ustrings.getlen()); - } - build_uninst.common.language_tables_num = st_num; - build_uninst.common.language_table_size = ubuild_langtables.getlen() / st_num; + set_uninstall_mode(0); +#endif + SCRIPT_MSG("Done!\n"); return PS_OK; } -void CEXEBuild::FillStringTable(StringTable *table, NLF *nlf/*=0*/) { - if (!nlf) { - for (unsigned int i = 0; i < build_nlfs.size(); i++) { - if (build_nlfs[i]->m_wLangId == table->lang_id) { - nlf = table->nlf = build_nlfs[i]; - break; - } - } - } - -#define str(id) (nlf?nlf->GetString(id):english_strings[id]) - -#ifdef NSIS_CONFIG_COMPONENTPAGE - // if component page, do component strings: - if (table->installer.componenttext) - { - int x; - int iscp=0; - for (x = 0; x < build_header.num_sections&&!iscp; x ++) - { - section *sec = &((section*)build_sections.get())[x]; - char c; - if (sec->name_ptr < 0) c = 'a'; - else c=build_strlist.get()[sec->name_ptr]; - if (c && c != '-' && !(sec->flags&SF_RO)) iscp++; - } - if (iscp || comppage_used) - { - if (!table->installer.custom) table->installer.custom=add_string_main(str(NLF_COMP_CUSTOM),0); - if (!table->common.subcaptions[1]) - table->common.subcaptions[1]=add_string_main(str(NLF_SUBCAPTION_OPTIONS)); - - if (!table->installer.componentsubtext[2]) - { - if (table->installer.componentsubtext[0]) - table->installer.componentsubtext[2]=table->installer.componentsubtext[0]; - } - if (!table->installer.componentsubtext[3]) - { - if (table->installer.componentsubtext[1]) - table->installer.componentsubtext[3]=table->installer.componentsubtext[1]; - else - table->installer.componentsubtext[3]=add_string_main(str(NLF_COMP_SUBTEXT1_NO_INST_TYPES),0); - } - if (!table->installer.componentsubtext[0]) - table->installer.componentsubtext[0]=add_string_main(str(NLF_COMP_SUBTEXT1),0); - if (!(build_header.common.flags&CH_FLAGS_NO_CUSTOM) && !table->installer.componentsubtext[1]) - table->installer.componentsubtext[1]=add_string_main(str(NLF_COMP_SUBTEXT2),0); - - if (!(build_header.common.flags&CH_FLAGS_NO_CUSTOM)) - build_header.install_types[NSIS_MAX_INST_TYPES] = LANG_COMP_CUSTOM; - } - else table->installer.componenttext=0; - } -#endif - - static bool nameWarned = false; - if (!table->common.name) - { - if (!nameWarned) { - warning("Name command not specified. Assuming default."); - nameWarned = true; - } - table->common.name=add_string_main(str(NLF_DEF_NAME),0); - table->ucommon.name=add_string_uninst(str(NLF_DEF_NAME),0); - } -#ifdef NSIS_CONFIG_VISIBLE_SUPPORT - table->common.byte=add_string_main(str(NLF_BYTE),0); - table->common.kilo=add_string_main(str(NLF_KILO),0); - table->common.mega=add_string_main(str(NLF_MEGA),0); - table->common.giga=add_string_main(str(NLF_GIGA),0); - - /* not yet needed - - table->ucommon.byte=add_string_uninst(str(NLF_BYTE)); - table->ucommon.kilo=add_string_uninst(str(NLF_KILO)); - table->ucommon.mega=add_string_uninst(str(NLF_MEGA)); - table->ucommon.giga=add_string_uninst(str(NLF_GIGA));*/ - -#ifdef NSIS_CONFIG_LOG - table->common.log_install_process=add_string_main(str(NLF_LOG_INSTALL_PROCESS)); - table->ucommon.log_install_process=add_string_uninst(str(NLF_LOG_INSTALL_PROCESS)); -#endif - -#ifdef NSIS_CONFIG_LICENSEPAGE - if (!table->installer.licensedata || !table->installer.licensetext) - { - table->installer.licensedata=0; - table->installer.licensetext=0; - table->installer.licensebuttonagree=0; - table->installer.licensebuttondisagree=0; - } - - if (table->installer.licensedata) - { - if (!table->common.subcaptions[0]) - table->common.subcaptions[0]=add_string_main(str(NLF_SUBCAPTION_LICENSE)); - if (!table->installer.licensebutton) - table->installer.licensebutton=add_string_main(str(NLF_BTN_LICENSE),0); - if (build_header.common.flags&CH_FLAGS_LICENSE_FORCE_SELECTION) { - if (!table->installer.licensebuttonagree) - table->installer.licensebuttonagree=add_string_main(str(NLF_BTN_LICENSE_AGREE),0); - if (!table->installer.licensebuttondisagree && license_force_radio_used) - table->installer.licensebuttondisagree=add_string_main(str(NLF_BTN_LICENSE_DISAGREE),0); - } - } -#endif //NSIS_CONFIG_LICENSEPAGE - - if (table->installer.text) - { - if (!table->installer.dirsubtext) - { - char buf[2048]; - wsprintf(buf,str(NLF_DIR_SUBTEXT),build_strlist.get()+table->common.name); - table->installer.dirsubtext=add_string_main(buf,0); - } - if (!table->common.subcaptions[2]) - table->common.subcaptions[2]=add_string_main(str(NLF_SUBCAPTION_DIR)); - if (!table->installer.browse) table->installer.browse=add_string_main(str(NLF_BTN_BROWSE),0); - if (!table->installer.spaceavailable && !no_space_texts) table->installer.spaceavailable=add_string_main(str(NLF_SPACE_AVAIL),0); - } - - if (table->installer.text -#ifdef NSIS_CONFIG_COMPONENTPAGE - || table->installer.componenttext -#endif - ) - { - if (!table->installer.spacerequired && !no_space_texts) table->installer.spacerequired=add_string_main(str(NLF_SPACE_REQ),0); - } - if (next_used) - { - if (!table->common.nextbutton) table->common.nextbutton=add_string_main(str(NLF_BTN_NEXT),0); - } - if (install_used) - { - if (!table->installer.installbutton) table->installer.installbutton=add_string_main(str(NLF_BTN_INSTALL),0); - } - - if (!table->common.subcaptions[3]) - table->common.subcaptions[3]=add_string_main(str(NLF_SUBCAPTION_INSTFILES)); - if (!table->common.subcaptions[4]) - table->common.subcaptions[4]=add_string_main(str(NLF_SUBCAPTION_COMPLETED)); - - if (!table->common.branding) - { - char buf[256]; - wsprintf(buf,str(NLF_BRANDING),NSIS_VERSION); - table->common.branding=add_string_main(buf,0); - } - if (!table->common.backbutton) table->common.backbutton=add_string_main(str(NLF_BTN_BACK),0); - if (!table->common.cancelbutton) table->common.cancelbutton=add_string_main(str(NLF_BTN_CANCEL),0); - if (!table->common.showdetailsbutton) table->common.showdetailsbutton=add_string_main(str(NLF_BTN_DETAILS),0); - - if (!table->common.closebutton) table->common.closebutton=add_string_main(str(NLF_BTN_CLOSE),0); - if (!table->common.completed) table->common.completed=add_string_main(str(NLF_COMPLETED),0); -#endif - -#ifdef NSIS_SUPPORT_FILE - if (m_inst_fileused) - { - if (!table->common.fileerrtext) - { - table->common.fileerrtext=add_string_main(str(NLF_FILE_ERROR)); - } - if (!table->common.fileerrtext_noignore) - { - table->common.fileerrtext_noignore=add_string_main(str(NLF_FILE_ERROR_NOIGNORE)); - } - } -#endif - +void CEXEBuild::FillLanguageTable(LanguageTable *table) { + for (int i = 0; i < NLF_STRINGS; i++) { #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT - if (ubuild_entries.getlen()) - { - if (uninstaller_writes_used) { - if (!table->uninstall.uninstalltext2) - table->uninstall.uninstalltext2=add_string_uninst(str(NLF_UNINST_SUBTEXT),0); - if (!table->ucommon.caption) - { - char buf[1024]; - wsprintf(buf,str(NLF_UCAPTION),ubuild_strlist.get()+table->ucommon.name); - table->ucommon.caption=add_string_uninst(buf); + if (!NLFRefs[i].iUnRef && !NLFRefs[i].iRef) + continue; +#else + if (!NLFRefs[i].iRef) + continue; +#endif + + int sn, index; + int pos = build_langstrings.get(NLFStrings[i].szLangStringName, &sn, &index); + if (pos >= 0) { + const char *str = table->lang_strings->get(sn); + if (!str || !*str) { + const char *us = UserInnerStrings.get(i); + if (us && *us) { + table->lang_strings->set(sn, (char *) us); + } + else { + char *dstr = table->nlf.m_szStrings[i] ? table->nlf.m_szStrings[i] : NLFStrings[i].szDefault; + if (i == NLF_BRANDING) { + char temp[NSIS_MAX_STRLEN + sizeof(NSIS_VERSION)]; + sprintf(temp, dstr, NSIS_VERSION); + table->lang_strings->set(sn, temp); + continue; + } + table->lang_strings->set(sn, dstr); + } } -#ifdef NSIS_CONFIG_VISIBLE_SUPPORT - if (!table->ucommon.subcaptions[0]) - table->ucommon.subcaptions[0]=add_string_uninst(str(NLF_USUBCAPTION_CONFIRM)); - if (!table->ucommon.subcaptions[1]) - table->ucommon.subcaptions[1]=add_string_uninst(str(NLF_USUBCAPTION_INSTFILES)); - if (!table->ucommon.subcaptions[2]) - table->ucommon.subcaptions[2]=add_string_uninst(str(NLF_USUBCAPTION_COMPLETED)); - table->ucommon.branding=add_string_uninst(build_strlist.get() + table->common.branding,0); - table->ucommon.backbutton=add_string_uninst(build_strlist.get() + table->common.backbutton,0); - table->ucommon.nextbutton=add_string_uninst(build_strlist.get() + table->common.nextbutton,0); - table->ucommon.cancelbutton=add_string_uninst(build_strlist.get() + table->common.cancelbutton,0); - table->ucommon.showdetailsbutton=add_string_uninst(build_strlist.get() + table->common.showdetailsbutton,0); - table->ucommon.closebutton=add_string_uninst(build_strlist.get() + table->common.closebutton,0); - table->ucommon.completed=add_string_uninst(build_strlist.get() + table->common.completed,0); -#endif - - if (!table->uninstall.uninstbutton) table->uninstall.uninstbutton=add_string_uninst(str(NLF_BTN_UNINSTALL),0); } } - -#ifdef NSIS_SUPPORT_FILE - if (m_uninst_fileused) - { - if (!table->ucommon.fileerrtext) - { - table->ucommon.fileerrtext=add_string_uninst(build_strlist.get() + table->common.fileerrtext); - } - if (!table->ucommon.fileerrtext_noignore) - { - table->ucommon.fileerrtext_noignore=add_string_uninst(build_strlist.get() + table->common.fileerrtext_noignore); - } - } -#endif - -#endif - - if (!table->common.caption) - { - char buf[1024]; - wsprintf(buf,str(NLF_CAPTION),build_strlist.get()+table->common.name); - table->common.caption=add_string_main(buf); - } - -#define SET_INSTRUCTION(id,s) table->common.s=add_string_main(str(id),0);table->ucommon.s=add_string_uninst(str(id),0) - -#ifdef NSIS_CONFIG_VISIBLE_SUPPORT - #if defined(NSIS_SUPPORT_DELETE) || defined(NSIS_SUPPORT_RMDIR) || defined(NSIS_SUPPORT_FILE) - SET_INSTRUCTION(NLF_CANT_WRITE, cant_write); - #endif - #ifdef NSIS_SUPPORT_RMDIR - SET_INSTRUCTION(NLF_REMOVE_DIR, remove_dir); - #endif - #ifdef NSIS_SUPPORT_COPYFILES - SET_INSTRUCTION(NLF_COPY_FAILED, copy_failed); - SET_INSTRUCTION(NLF_COPY_TO, copy_to); - #endif - #ifdef NSIS_SUPPORT_ACTIVEXREG - if (register_used) - { - SET_INSTRUCTION(NLF_REGISTERING, registering); - } - if (unregister_used) - { - SET_INSTRUCTION(NLF_UNREGISTERING, unregistering); - } - SET_INSTRUCTION(NLF_SYMBOL_NOT_FOUND, symbol_not_found); - SET_INSTRUCTION(NLF_COULD_NOT_LOAD, could_not_load); - SET_INSTRUCTION(NLF_NO_OLE, no_ole); - // not used anywhere - SET_INSTRUCTION(NLF_ERR_REG_DLL, err_reg_dll); - #endif - #ifdef NSIS_SUPPORT_CREATESHORTCUT - SET_INSTRUCTION(NLF_CREATE_SHORTCUT, create_shortcut); - SET_INSTRUCTION(NLF_ERR_CREATING_SHORTCUT, err_creating_shortcut); - #endif - #ifdef NSIS_SUPPORT_DELETE - SET_INSTRUCTION(NLF_DEL_FILE, del_file); - #ifdef NSIS_SUPPORT_MOVEONREBOOT - SET_INSTRUCTION(NLF_DEL_ON_REBOOT, del_on_reboot); - #endif - #endif - #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT - SET_INSTRUCTION(NLF_CREATED_UNINST, created_uninst); - SET_INSTRUCTION(NLF_ERR_CREATING, err_creating); - #endif - #ifdef NSIS_SUPPORT_SHELLEXECUTE - SET_INSTRUCTION(NLF_EXEC_SHELL, exec_shell); - #endif - #ifdef NSIS_SUPPORT_EXECUTE - SET_INSTRUCTION(NLF_EXEC, exec); - #endif - #ifdef NSIS_SUPPORT_MOVEONREBOOT - SET_INSTRUCTION(NLF_RENAME_ON_REBOOT, rename_on_reboot); - #endif - #ifdef NSIS_SUPPORT_RENAME - SET_INSTRUCTION(NLF_RENAME, rename); - #endif - - #ifdef NSIS_SUPPORT_FILE - SET_INSTRUCTION(NLF_EXTRACT, extract); - SET_INSTRUCTION(NLF_SKIPPED, skipped); - #endif - SET_INSTRUCTION(NLF_OUTPUT_DIR, output_dir); - SET_INSTRUCTION(NLF_CREATE_DIR, create_dir); - SET_INSTRUCTION(NLF_COPY_DETAILS, copy_details); -#endif//NSIS_CONFIG_VISIBLE_SUPPORT - - #ifdef NSIS_SUPPORT_FILE - SET_INSTRUCTION(NLF_ERR_WRITING, err_writing); - SET_INSTRUCTION(NLF_ERR_DECOMPRESSING, err_decompressing); - #endif - SET_INSTRUCTION(NLF_INST_CORRUPTED, inst_corrupted); -} - -bool CEXEBuild::_IsNotSet(int *str) { - if (!str) return true; - for (unsigned int i = 0; i < string_tables.size(); i++) { - if (*(int*)(int(str)-int(string_tables[0])+int(string_tables[i]))) { - return false; - } - } - return true; } char SkipComments(FILE *f) { @@ -709,9 +583,46 @@ char SkipComments(FILE *f) { } // NSIS Language File parser -NLF::NLF(char *filename) { +LanguageTable * CEXEBuild::LoadLangFile(char *filename) { FILE *f = fopen(filename, "r"); - if (!f) throw runtime_error("Can't open language file!"); + if (!f) { + ERROR_MSG("Error: Can't open language file!\n"); + return 0; + } + + // Check header + char buf[NSIS_MAX_STRLEN]; + buf[0] = SkipComments(f); + fgets(buf+1, NSIS_MAX_STRLEN, f); + + if (strncmp(buf, "NLF v", 5)) { + ERROR_MSG("Error: Invalid language file.\n"); + return 0; + } + int nlf_version = atoi(buf+5); + if (nlf_version != NLF_VERSION) { + if (nlf_version != 2 && nlf_version != 3 && nlf_version != 4 && nlf_version != 5) { + ERROR_MSG("Error: Language file version doesn't match NSIS version.\n"); + return 0; + } + } + + // Get language ID + buf[0] = SkipComments(f); + fgets(buf+1, NSIS_MAX_STRLEN, f); + LANGID lang_id = atoi(buf); + + // Get appropriate table + LanguageTable *table = GetLangTable(lang_id); + if (!table) + return 0; + + NLF *nlf = &table->nlf; + + if (nlf->m_bLoaded) { + ERROR_MSG("Error: can't load same language file twice.\n"); + return 0; + } // Generate language name char *p, *p2, t; @@ -726,113 +637,141 @@ NLF::NLF(char *filename) { if (p2) { p2++; - m_szName = new char[strlen(p2)+1]; - strcpy(m_szName, p2); + nlf->m_szName = (char*)malloc(strlen(p2)+1); + strcpy(nlf->m_szName, p2); } else { - m_szName = new char[strlen(filename)+1]; - strcpy(m_szName, filename); + nlf->m_szName = (char*)malloc(strlen(filename)+1); + strcpy(nlf->m_szName, filename); } if (p) *p = t; - // Check header - char buf[1024]; - buf[0] = SkipComments(f); - fgets(buf+1, 1024, f); - - if (strncmp(buf, "NLF v", 5)) throw runtime_error("Invalid language file!"); - int nlf_version = atoi(buf+5); - if (nlf_version != NLF_VERSION) { - if (nlf_version != 2 && nlf_version != 3 && nlf_version != 4) - throw runtime_error("Language file version doesn't match NSIS version!"); + if (nlf_version != NLF_VERSION) + { + warning_fl("%s language file version doesn't match. Using default English texts for missing strings.", nlf->m_szName); } - // Get language ID - buf[0] = SkipComments(f); - fgets(buf+1, 1024, f); - m_wLangId = atoi(buf); - int temp; // Get font - m_szFont = NULL; - m_iFontSize = 0; + nlf->m_szFont = NULL; + nlf->m_iFontSize = 0; buf[0] = SkipComments(f); - fgets(buf+1, 1024, f); + fgets(buf+1, NSIS_MAX_STRLEN, f); temp=strlen(buf); while (buf[temp-1] == '\n' || buf[temp-1] == '\r') { buf[temp-1] = 0; temp--; } if (buf[0] != '-' && buf [1] != 0) { - m_szFont = new char[strlen(buf) + 1]; - strcpy(m_szFont, buf); + nlf->m_szFont = (char*)malloc(strlen(buf)+1);; + strcpy(nlf->m_szFont, buf); } buf[0] = SkipComments(f); - fgets(buf+1, 1024, f); + fgets(buf+1, NSIS_MAX_STRLEN, f); if (buf[0] != '-' && buf [1] != 0) { - m_iFontSize = atoi(buf); + nlf->m_iFontSize = atoi(buf); } // Get code page - m_uCodePage = CP_ACP; + nlf->m_uCodePage = CP_ACP; buf[0] = SkipComments(f); - fgets(buf+1, 1024, f); + fgets(buf+1, NSIS_MAX_STRLEN, f); if (buf[0] != '-' && buf [1] != 0) { - m_uCodePage = atoi(buf); - if (!IsValidCodePage(m_uCodePage)) - m_uCodePage = CP_ACP; + nlf->m_uCodePage = atoi(buf); + if (!IsValidCodePage(nlf->m_uCodePage)) + nlf->m_uCodePage = CP_ACP; + } + + // Get RTL setting + nlf->m_szStrings[NLF_RTL] = (char *)malloc(2); + nlf->m_bRTL = false; + buf[0] = SkipComments(f); + fgets(buf+1, NSIS_MAX_STRLEN, f); + if (buf[0] == 'R' && buf[1] == 'T' && buf[2] == 'L' && (!buf[3] || buf[3] == '\r' || buf[3] == '\n')) { + nlf->m_bRTL = true; + strcpy(nlf->m_szStrings[NLF_RTL], "1"); + } + else { + strcpy(nlf->m_szStrings[NLF_RTL], "0"); } // Read strings - for (int i = 0; i < NLF_STRINGS; i++) { - if (nlf_version < 3 && (i == NLF_BTN_LICENSE_AGREE || i == NLF_BTN_LICENSE_DISAGREE)) { - m_szStrings[i] = new char[strlen(english_strings[i]) + 1]; - strcpy(m_szStrings[i], english_strings[i]); + for (int i = 0; i < NLF_STRINGS - 1; i++) { + + // skip virtual strings + if (!NLFStrings[i].szDefault) continue; - } - - if (nlf_version < 4) { - switch (i) { - case NLF_LOG_INSTALL_PROCESS: - case NLF_BYTE: - case NLF_KILO: - case NLF_MEGA: - case NLF_GIGA: - case NLF_REGISTERING: - case NLF_UNREGISTERING: - m_szStrings[i] = new char[strlen(english_strings[i]) + 1]; - strcpy(m_szStrings[i], english_strings[i]); - continue; - break; - } - } - - if (nlf_version < 5) { - if (i == NLF_FILE_ERROR_NOIGNORE) { - m_szStrings[i] = new char[strlen(english_strings[i]) + 1]; - strcpy(m_szStrings[i], english_strings[i]); + + // Fill in for missing strings + // 0 will mean default will be used from NLFStrings + switch (i) { + case NLF_BTN_LICENSE_AGREE: + case NLF_BTN_LICENSE_DISAGREE: + if (nlf_version >= 3) break; + case NLF_LOG_INSTALL_PROCESS: + case NLF_BYTE: + case NLF_KILO: + case NLF_MEGA: + case NLF_GIGA: + case NLF_REGISTERING: + case NLF_UNREGISTERING: + if (nlf_version >= 4) break; + case NLF_FILE_ERROR_NOIGNORE: + if (nlf_version >= 5) break; + case NLF_USUBCAPTION_OPTIONS: + case NLF_USUBCAPTION_DIR: + case NLF_CLICK_NEXT: + case NLF_CLICK_INSTALL: + case NLF_CLICK_UNINSTALL: + case NLF_LICENSE_TEXT: + case NLF_LICENSE_TEXT_FSCB: + case NLF_LICENSE_TEXT_FSRB: + case NLF_ULICENSE_TEXT: + case NLF_ULICENSE_TEXT_FSCB: + case NLF_ULICENSE_TEXT_FSRB: + case NLF_COMP_TEXT: + case NLF_UCOMP_TEXT: + case NLF_UCOMP_SUBTEXT1: + case NLF_UCOMP_SUBTEXT1_NO_INST_TYPES: + case NLF_UCOMP_SUBTEXT2: + case NLF_DIR_TEXT: + case NLF_DIR_BROWSETEXT: + case NLF_UDIR_TEXT: + case NLF_UDIR_SUBTEXT: + case NLF_UDIR_BROWSETEXT: + case NLF_UNINST_TEXT: + if (nlf_version >= 6) break; + nlf->m_szStrings[i] = 0; continue; - } } buf[0] = SkipComments(f); fgets(buf+1, NSIS_MAX_STRLEN, f); if (strlen(buf) == NSIS_MAX_STRLEN-1) { - wsprintf(buf, "String too long (string #%d)!", i); - throw runtime_error(buf); + ERROR_MSG("Error: String too long (string #%d - \"%s\")", i, NLFStrings[i].szLangStringName); + return 0; } temp=strlen(buf); + while (buf[temp-1] == '\n' || buf[temp-1] == '\r') { - buf[temp-1] = 0; - temp--; + buf[--temp] = 0; } - m_szStrings[i] = new char[strlen(buf)+1]; - for (char *out = m_szStrings[i], *in = buf; *in; in++, out++) { + + char *in = buf; + + // trim quotes + if (buf[0] == '"' && buf[temp-1] == '"') { + in++; + buf[--temp] = 0; + } + + nlf->m_szStrings[i] = (char*)malloc(temp+1); + for (char *out = nlf->m_szStrings[i]; *in; in++, out++) { if (*in == '\\') { in++; switch (*in) { @@ -855,17 +794,17 @@ NLF::NLF(char *filename) { *out = 0; } fclose(f); + + nlf->m_bLoaded = true; + + return table; } -NLF::~NLF() { - delete [] m_szName; - delete [] m_szFont; +void CEXEBuild::DeleteLangTable(LanguageTable *table) { + free(table->nlf.m_szName); + free(table->nlf.m_szFont); + free(table->lang_strings); for (int i = 0; i < NLF_STRINGS; i++) { - delete [] m_szStrings[i]; + free(table->nlf.m_szStrings[i]); } -} - -char* NLF::GetString(int idx) { - if (idx < 0 || idx >= NLF_STRINGS) return 0; - return m_szStrings[idx]; -} +} \ No newline at end of file diff --git a/Source/lang.h b/Source/lang.h index 57bc85ed..475dcddb 100644 --- a/Source/lang.h +++ b/Source/lang.h @@ -1,86 +1,188 @@ -// Lang.h by Amir Szekely 3rd August 2002 - #ifndef ___NLF___H_____ #define ___NLF___H_____ #include "exehead/fileform.h" -#include -using namespace std; + +struct NLFRef { + int iRef; + int iUnRef; +}; struct langstring { int name; + int sn; int index; + int uindex; + int process; }; class LangStringList : public SortedStringListND { public: - LangStringList() - { - index = 0; + LangStringList() { + count = 0; } ~LangStringList() { } - int add(const char *name) + int add(const char *name, int *sn=0) { - int pos=SortedStringListND::add(name); + int pos = SortedStringListND::add(name); if (pos == -1) return -1; - ((struct langstring*)gr.get())[pos].index = index; + ((struct langstring*)gr.get())[pos].sn = count; + if (sn) *sn = count; + count++; + ((struct langstring*)gr.get())[pos].index = -1; + ((struct langstring*)gr.get())[pos].uindex = -1; + ((struct langstring*)gr.get())[pos].process = 1; - int temp = index; - index++; - - return temp; + return pos; } - int get(char *name) + int get(char *name, int *sn=0, int *index=0, int *uindex=0, int *process=0) { + if (index) *index = -1; + if (uindex) *uindex = -1; + if (sn) *sn = -1; int v=SortedStringListND::find(name); if (v==-1) return -1; - return ((struct langstring*)gr.get())[v].index; + if (index) *index = ((struct langstring*)gr.get())[v].index; + if (uindex) *uindex = ((struct langstring*)gr.get())[v].uindex; + if (sn) *sn = ((struct langstring*)gr.get())[v].sn; + if (process) *process = ((struct langstring*)gr.get())[v].process; + return v; + } + + void set(int pos, int index=-1, int uindex=-1, int process=-1) + { + if ((unsigned int)pos > (gr.getlen() / sizeof(struct langstring))) + return; + + struct langstring *data=(struct langstring *)gr.get(); + + if (index >= 0) + data[pos].index = index; + if (uindex >= 0) + data[pos].uindex = uindex; + if (process >= 0) + data[pos].process = process; + } + + void set(char *name, int index, int uindex=-1, int process=-1) + { + set(get(name), index, uindex, process); + } + + const char *pos2name(int pos) + { + struct langstring *data=(struct langstring *)gr.get(); + + if ((unsigned int)pos > (gr.getlen() / sizeof(struct langstring))) + return 0; + + return ((const char*)strings.get() + data[pos].name); + } + + const char *offset2name(int name) + { + if ((unsigned int)name > strings.getlen()) + return 0; + + return (const char*)strings.get() + name; } int getnum() { - return index; + return gr.getlen() / sizeof(struct langstring); } - char *idx2name(int idx) + static int compare_index(const void *item1, const void *item2) { - struct langstring *data=(struct langstring *)gr.get(); - - for (int i = 0; i < index; i++) - { - if (data[i].index == idx) - { - return ((char*)strings.get() + data[i].name); - } - } + struct langstring *ls1 = (struct langstring *)item1; + struct langstring *ls2 = (struct langstring *)item2; - return NULL; + return ls1->index - ls2->index; + } + + struct langstring *sort_index(int *num) + { + if (!num) return 0; + sortbuf.resize(0); + sortbuf.add(gr.get(), gr.getlen()); + *num = sortbuf.getlen() / sizeof(struct langstring); + qsort(sortbuf.get(), *num, sizeof(struct langstring), compare_index); + return (struct langstring*) sortbuf.get(); + } + + static int compare_uindex(const void *item1, const void *item2) + { + struct langstring *ls1 = (struct langstring *)item1; + struct langstring *ls2 = (struct langstring *)item2; + + return ls1->uindex - ls2->uindex; + } + + struct langstring *sort_uindex(int *num) + { + if (!num) return 0; + sortbuf.resize(0); + sortbuf.add(gr.get(), gr.getlen()); + *num = sortbuf.getlen() / sizeof(struct langstring); + qsort(sortbuf.get(), *num, sizeof(struct langstring), compare_uindex); + return (struct langstring*) sortbuf.get(); } private: - int index; + int count; + TinyGrowBuf sortbuf; }; -class NLF; +class StringsArray +{ + private: + TinyGrowBuf offsets; + GrowBuf strings; -struct StringTable { - LANGID lang_id; - int dlg_offset; - common_strings common; - common_strings ucommon; - installer_strings installer; - uninstall_strings uninstall; - TinyGrowBuf user_strings; - TinyGrowBuf user_ustrings; + public: + StringsArray() + { + offsets.set_zeroing(1); - NLF *nlf; + strings.add("", sizeof("")); + } + + ~StringsArray() { } + + void resize(int num) + { + offsets.resize(num * sizeof(int)); + } + + int set(int idx, char *str) + { + if (idx < 0) + return 0; + + if (idx >= (offsets.getlen() / sizeof(int))) + resize(idx+1); + + int old = ((int*)offsets.get())[idx]; + + ((int*)offsets.get())[idx] = strings.add(str, strlen(str) + 1); + + return old; + } + + const char *get(int idx) + { + if ((unsigned int)idx >= (offsets.getlen() / sizeof(int))) + return 0; + + return (const char *)strings.get() + ((int*)offsets.get())[idx]; + } }; -#define NLF_VERSION 5 +#define NLF_VERSION 6 enum { NLF_BRANDING, @@ -91,6 +193,8 @@ enum { NLF_SUBCAPTION_DIR, NLF_SUBCAPTION_INSTFILES, NLF_SUBCAPTION_COMPLETED, + NLF_USUBCAPTION_OPTIONS, + NLF_USUBCAPTION_DIR, NLF_USUBCAPTION_CONFIRM, NLF_USUBCAPTION_INSTFILES, NLF_USUBCAPTION_COMPLETED, @@ -105,15 +209,36 @@ enum { NLF_BTN_CLOSE, NLF_BTN_BROWSE, NLF_BTN_DETAILS, - NLF_DEF_NAME, + NLF_CLICK_NEXT, + NLF_CLICK_INSTALL, + NLF_CLICK_UNINSTALL, + NLF_NAME, NLF_COMPLETED, + NLF_LICENSE_TEXT, + NLF_LICENSE_TEXT_FSCB, + NLF_LICENSE_TEXT_FSRB, + NLF_ULICENSE_TEXT, + NLF_ULICENSE_TEXT_FSCB, + NLF_ULICENSE_TEXT_FSRB, + NLF_LICENSE_DATA, // virtual NLF_COMP_CUSTOM, + NLF_COMP_TEXT, NLF_COMP_SUBTEXT1, NLF_COMP_SUBTEXT1_NO_INST_TYPES, NLF_COMP_SUBTEXT2, + NLF_UCOMP_TEXT, + NLF_UCOMP_SUBTEXT1, + NLF_UCOMP_SUBTEXT1_NO_INST_TYPES, + NLF_UCOMP_SUBTEXT2, + NLF_DIR_TEXT, NLF_DIR_SUBTEXT, + NLF_DIR_BROWSETEXT, + NLF_UDIR_TEXT, + NLF_UDIR_SUBTEXT, + NLF_UDIR_BROWSETEXT, NLF_SPACE_AVAIL, NLF_SPACE_REQ, + NLF_UNINST_TEXT, NLF_UNINST_SUBTEXT, NLF_FILE_ERROR, NLF_FILE_ERROR_NOIGNORE, @@ -150,36 +275,32 @@ enum { NLF_KILO, NLF_MEGA, NLF_GIGA, + NLF_RTL, - NLF_STRINGS, - - SLANG_NAME, - SLANG_COMP_TEXT, - SLANG_LICENSE_TEXT, - SLANG_LICENSE_DATA, - SLANG_DIR_TEXT, - SLANG_UNINST_TEXT + NLF_STRINGS }; -extern char *english_strings[NLF_STRINGS]; - -// NSIS Language File parser -class NLF { - public: - NLF(char *filename); - ~NLF(); - - char *GetString(int idx); - +struct NLF { + bool m_bLoaded; char *m_szName; - - LANGID m_wLangId; char *m_szFont; int m_iFontSize; unsigned int m_uCodePage; - - private: + bool m_bRTL; + char *m_szStrings[NLF_STRINGS]; }; +struct LanguageTable { + LANGID lang_id; + + int dlg_offset; + + GrowBuf *strlist; + + StringsArray *lang_strings; + + NLF nlf; +}; + #endif diff --git a/Source/makenssi.cpp b/Source/makenssi.cpp index e62f1baf..699433cb 100644 --- a/Source/makenssi.cpp +++ b/Source/makenssi.cpp @@ -214,7 +214,7 @@ int main(int argc, char **argv) { fprintf(g_output,"Size of EXE header is %d bytes for zlib, %d bytes for bzip2.\n", zlib_exeheader_size,bzip2_exeheader_size); fprintf(g_output,"Size of info header is %d bytes.\n",sizeof(firstheader)); - fprintf(g_output,"Size of install header is %d bytes, uninstall header is %d bytes.\n",sizeof(header),sizeof(uninstall_header)); + fprintf(g_output,"Size of [un]install header is %d bytes,\n",sizeof(header)); fprintf(g_output,"Size of each section is %d bytes.\n",sizeof(section)); fprintf(g_output,"Size of each page is %d bytes.\n",sizeof(page)); fprintf(g_output,"Size of each instruction is %d bytes.\n",sizeof(entry)); diff --git a/Source/makenssi.dsp b/Source/makenssi.dsp index efebec55..6b708ed3 100644 --- a/Source/makenssi.dsp +++ b/Source/makenssi.dsp @@ -69,8 +69,7 @@ LINK32=link.exe # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /Ob2 /D "_CONSOLE" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "WIN32_LEAN_AND_MEAN" /FD /c # SUBTRACT BASE CPP /Fr /YX /Yc /Yu -# ADD CPP /nologo /MLd /W3 /GX /ZI /Od /D "_CONSOLE" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "WIN32_LEAN_AND_MEAN" /Fr /FD /c -# SUBTRACT CPP /YX /Yc /Yu +# ADD CPP /nologo /MLd /W3 /GX /ZI /Od /D "_CONSOLE" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "WIN32_LEAN_AND_MEAN" /Fr /FD /Zm200 /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe diff --git a/Source/script.cpp b/Source/script.cpp index 8a9062dc..5298e1ba 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -1,6 +1,9 @@ #include #include #include +#define _RICHEDIT_VER 0x0200 +#include +#undef _RICHEDIT_VER #include "tokens.h" #include "build.h" #include "util.h" @@ -8,14 +11,12 @@ #include "ResourceEditor.h" #include "DialogTemplate.h" #include "lang.h" -#include "exehead/lang.h" #include "exehead/resource.h" #ifndef FOF_NOERRORUI #define FOF_NOERRORUI 0x0400 #endif - #define MAX_INCLUDEDEPTH 10 #define MAX_LINELENGTH 4096 @@ -186,38 +187,58 @@ int CEXEBuild::process_script(FILE *filepointer, char *filename) fp = 0; curfilename = 0; - if (ret == PS_ENDIF) ERROR_MSG("!endif: stray !endif\n"); - if (IS_PS_ELSE(ret)) ERROR_MSG("!else: stray !else\n"); if (m_linebuild.getlen()) { ERROR_MSG("Error: invalid script: last line ended with \\\n"); return PS_ERROR; } + + if (num_ifblock()) + { + ERROR_MSG("!if[n]def: open at EOF - need !endif\n"); + return PS_ERROR; + } + return ret; } -#ifdef NSIS_SUPPORT_NAMED_USERVARS - #define PRINTHELP() { if ( !b_abort_compile ) print_help(line.gettoken_str(0)); return PS_ERROR; } -#else - #define PRINTHELP() { print_help(line.gettoken_str(0)); return PS_ERROR; } -#endif +#define PRINTHELP() { print_help(line.gettoken_str(0)); return PS_ERROR; } +void CEXEBuild::start_ifblock() +{ + ifblock ib = {0, }; + if (cur_ifblock) + ib.inherited_ignore = cur_ifblock->ignore || cur_ifblock->inherited_ignore; + int num = build_preprocessor_data.getlen() / sizeof(ifblock); + build_preprocessor_data.add(&ib, sizeof(ifblock)); + cur_ifblock = (ifblock *) build_preprocessor_data.get() + num; +} + +void CEXEBuild::end_ifblock() +{ + if (build_preprocessor_data.getlen()) + { + cur_ifblock--; + build_preprocessor_data.resize(build_preprocessor_data.getlen() - sizeof(ifblock)); + if (!build_preprocessor_data.getlen()) + cur_ifblock = 0; + } +} + +int CEXEBuild::num_ifblock() +{ + return build_preprocessor_data.getlen() / sizeof(ifblock); +} int CEXEBuild::doParse(const char *str) { - static int ignore; - static int last_line_had_slash; - static int ignored_if_count; - static int wait_for_endif; - static bool inside_comment=0; - LineParser line(inside_comment); int res; while (*str == ' ' || *str == '\t') str++; // if ignoring, ignore all lines that don't begin with !. - if (ignore && *str!='!' && !last_line_had_slash) return PS_OK; + if (cur_ifblock && cur_ifblock->ignore && *str!='!' && !last_line_had_slash) return PS_OK; if (m_linebuild.getlen()>1) m_linebuild.resize(m_linebuild.getlen()-2); @@ -291,21 +312,32 @@ parse_again: PRINTHELP() } + int if_from_else = 0; + if (tkid == TOK_P_ELSE) { - if (ignored_if_count) { + if (cur_ifblock && cur_ifblock->inherited_ignore) + return PS_OK; + + if (!num_ifblock() || cur_ifblock->elseused) + { + ERROR_MSG("!else: stray !else\n"); + return PS_ERROR; + } + + if (line.getnumtokens() == 1) + { + cur_ifblock->ignore = !cur_ifblock->ignore; + // if not executed up until now, it will now + cur_ifblock->hasexeced++; + cur_ifblock->elseused++; return PS_OK; } - if (line.getnumtokens() == 1) { - if (!wait_for_endif) { - ignore=!ignore; - return PS_OK; - } - else { - ignore=1; - return PS_OK; - } + if (cur_ifblock->hasexeced) + { + cur_ifblock->ignore++; + return PS_OK; } line.eattoken(); @@ -315,24 +347,18 @@ parse_again: if (line.getnumtokens() == 1) PRINTHELP() if (!v) tkid = TOK_P_IFDEF; else tkid = TOK_P_IFNDEF; - if (ignore && !wait_for_endif) { - ignore=0; // process the ifdef - } - else { - // don't process the if(n)def because the else code shouldn't be executed - // one if was already executed - ignore=1; - wait_for_endif=1; - } + if_from_else++; + + SCRIPT_MSG("!else on line %d - %s\n", linecnt, line.gettoken_str(0)); } if (tkid == TOK_P_IFNDEF || tkid == TOK_P_IFDEF) { - if (wait_for_endif) { - return PS_OK; - } - if (ignore) { - ignored_if_count++; + if (!if_from_else) + start_ifblock(); + + if (cur_ifblock && cur_ifblock->inherited_ignore) + { return PS_OK; } @@ -359,24 +385,31 @@ parse_again: mod &= 1; } } - - if (!istrue && !ignored_if_count) ignore=1; + + if (istrue) + { + cur_ifblock->hasexeced++; + cur_ifblock->ignore = 0; + } + else + cur_ifblock->ignore++; + return PS_OK; } if (tkid == TOK_P_ENDIF) { - if (ignore) { - if (ignored_if_count) ignored_if_count--; - else { - wait_for_endif=0; - ignore=0; - } + if (!num_ifblock()) + { + ERROR_MSG("!endif: no !ifdef open\n"); + return PS_ERROR; } + end_ifblock(); return PS_OK; } - if (!ignore) + if (!cur_ifblock || (!cur_ifblock->ignore && !cur_ifblock->inherited_ignore)) { return doCommand(tkid,line); } + return PS_OK; } @@ -615,7 +648,7 @@ int CEXEBuild::process_jump(LineParser &line, int wt, int *offs) return 0; } -#define FLAG_OFFSET(flag) (FIELD_OFFSET(installer_flags, flag)/sizeof(int)) +#define FLAG_OFFSET(flag) (FIELD_OFFSET(exec_flags, flag)/sizeof(int)) #define SECTION_FIELD_GET(field) (FIELD_OFFSET(section, field)/sizeof(int)) #define SECTION_FIELD_SET(field) (-1 - (int)(FIELD_OFFSET(section, field)/sizeof(int))) @@ -688,7 +721,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) char *p=str; str[0]=0; fgets(str,MAX_LINELENGTH,fp); - SCRIPT_MSG("%s%s", str, str[lstrlen(str)-1]=='\n'?"":"\n"); + //SCRIPT_MSG("%s%s", str, str[lstrlen(str)-1]=='\n'?"":"\n"); if (feof(fp) && !str[0]) { ERROR_MSG("!macro \"%s\": unterminated (no !macroend found in file)!\n",line.gettoken_str(1)); @@ -819,24 +852,30 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return PS_OK; // page ordering shit /////////////////////////////////////////////////////////////////////////////// +#ifdef NSIS_CONFIG_VISIBLE_SUPPORT + case TOK_UNINSTPAGE: + set_uninstall_mode(1); case TOK_PAGE: { - SCRIPT_MSG("Page: %s", line.gettoken_str(1)); + SCRIPT_MSG("%sPage: %s", uninstall_mode?"Uninst":"", line.gettoken_str(1)); - enable_last_page_cancel = 0; - if (!stricmp(line.gettoken_str(line.getnumtokens()-1),"/ENABLECANCEL")) - enable_last_page_cancel = 1; + if (!uninstall_mode) { + enable_last_page_cancel = 0; + if (!stricmp(line.gettoken_str(line.getnumtokens()-1),"/ENABLECANCEL")) + enable_last_page_cancel = 1; + } + else { + uenable_last_page_cancel = 0; + if (!stricmp(line.gettoken_str(line.getnumtokens()-1),"/ENABLECANCEL")) + uenable_last_page_cancel = 1; + } - int k = line.gettoken_enum(1,"custom\0license\0components\0directory\0instfiles"); - page p = { - 0, -#ifdef NSIS_SUPPORT_CODECALLBACKS - -1, - -1, - -1, -#endif - 0 - }; + int k = line.gettoken_enum(1,"custom\0license\0components\0directory\0instfiles\0uninstConfirm"); + + if (k < 0) PRINTHELP(); + + if (add_page(k) != PS_OK) + return PS_ERROR; #ifndef NSIS_SUPPORT_CODECALLBACKS if (!k) { @@ -845,51 +884,38 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) } #endif//!NSIS_SUPPORT_CODECALLBACKS - if (k != 4) { - *build_last_page_define=0; - } - if (k) { // not custom #ifdef NSIS_SUPPORT_CODECALLBACKS switch (line.getnumtokens() - enable_last_page_cancel) { - case 7: - PRINTHELP(); case 6: - if (k != 4) { - lstrcpy(build_last_page_define, line.gettoken_str(5)); - } + PRINTHELP(); case 5: if (*line.gettoken_str(4)) - p.leavefunc = ns_func.add(line.gettoken_str(4),0); + cur_page->leavefunc = ns_func.add(line.gettoken_str(4),0); case 4: if (*line.gettoken_str(3)) - p.showfunc = ns_func.add(line.gettoken_str(3),0); + cur_page->showfunc = ns_func.add(line.gettoken_str(3),0); case 3: if (*line.gettoken_str(2)) - p.prefunc = ns_func.add(line.gettoken_str(2),0); + cur_page->prefunc = ns_func.add(line.gettoken_str(2),0); } -#else - if (line.getnumtokens() - enable_last_page_cancel == 3) - lstrcpy(build_last_page_define, line.gettoken_str(2)); #endif//NSIS_SUPPORT_CODECALLBACKS } #ifdef NSIS_SUPPORT_CODECALLBACKS else { // a custom page switch (line.getnumtokens() - enable_last_page_cancel) { - case 7: - PRINTHELP(); case 6: - lstrcpy(build_last_page_define, line.gettoken_str(5)); + PRINTHELP(); case 5: - p.caption = add_string_main(line.gettoken_str(4)); + cur_page->caption = add_string(line.gettoken_str(4)); case 4: if (*line.gettoken_str(3)) - p.leavefunc = ns_func.add(line.gettoken_str(3),0); + cur_page->leavefunc = ns_func.add(line.gettoken_str(3),0); case 3: if (*line.gettoken_str(2)) - p.prefunc = ns_func.add(line.gettoken_str(2),0); + cur_page->prefunc = ns_func.add(line.gettoken_str(2),0); break; case 2: ERROR_MSG("\nError: custom page must have a creator function!\n"); @@ -898,259 +924,336 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) } #endif//NSIS_SUPPORT_CODECALLBACKS - switch (k) { - case 0: - p.id = NSIS_PAGE_CUSTOM; - build_custom_used++; - break; - case 1: -#ifdef NSIS_CONFIG_LICENSEPAGE - p.id = NSIS_PAGE_LICENSE; - p.caption = LANG_SUBCAPTION(0); - break; -#else - ERROR_MSG("Error: %s specified, NSIS_CONFIG_LICENSEPAGE not defined.\n", line.gettoken_str(1)); - return PS_ERROR; -#endif - case 2: -#ifdef NSIS_CONFIG_COMPONENTPAGE - p.id = NSIS_PAGE_SELCOM; - p.caption = LANG_SUBCAPTION(1); - comppage_used++; - break; -#else - ERROR_MSG("Error: %s specified, NSIS_CONFIG_COMPONENTPAGE not defined.\n", line.gettoken_str(1)); - return PS_ERROR; -#endif - case 3: - p.id = NSIS_PAGE_DIR; - p.caption = LANG_SUBCAPTION(2); - break; - case 4: - if (*build_last_page_define) definedlist.add(build_last_page_define,""); - p.id = NSIS_PAGE_INSTFILES; - p.caption = LANG_SUBCAPTION(3); - break; - default: - PRINTHELP(); - } - #ifdef NSIS_SUPPORT_CODECALLBACKS - if (p.prefunc>=0) + if (cur_page->prefunc>=0) SCRIPT_MSG(" (%s:%s)", k?"pre":"creator", line.gettoken_str(2)); - if (p.showfunc>=0 && k) + if (cur_page->showfunc>=0 && k) SCRIPT_MSG(" (show:%s)", line.gettoken_str(3)); - if (p.leavefunc>=0) + if (cur_page->leavefunc>=0) SCRIPT_MSG(" (leave:%s)", line.gettoken_str(4-!k)); - else if (p.caption && !k) + else if (cur_page->caption && !k) SCRIPT_MSG(" (caption:%s)", line.gettoken_str(3)); #endif SCRIPT_MSG("\n"); - build_pages.add(&p,sizeof(page)); - build_header.common.num_pages++; - if (p.id == NSIS_PAGE_INSTFILES) { - p.id=NSIS_PAGE_COMPLETED; -#ifdef NSIS_SUPPORT_CODECALLBACKS - p.prefunc = -1; - p.showfunc = -1; - p.leavefunc = -1; -#endif - p.caption = LANG_SUBCAPTION(4); - build_pages.add(&p,sizeof(page)); - build_header.common.num_pages++; + page_end(); + + if (k == PAGE_INSTFILES) { + add_page(PAGE_COMPLETED); + page_end(); } + + set_uninstall_mode(0); } return make_sure_not_in_secorfunc(line.gettoken_str(0)); - case TOK_UNINSTPAGE: -#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT + + // extended page setting + case TOK_PAGEEX: + { + int k = line.gettoken_enum(1,"custom\0license\0components\0directory\0instfiles\0uninstConfirm\0"); + if (k < 0) { + k = line.gettoken_enum(1,"un.custom\0un.license\0un.components\0un.directory\0un.instfiles\0un.uninstConfirm\0"); + if (k < 0) PRINTHELP(); + set_uninstall_mode(1); + } + + SCRIPT_MSG("PageEx: %s\n", line.gettoken_str(1)); + + if (add_page(k) != PS_OK) + return PS_ERROR; + + cur_page->flags |= PF_PAGE_EX; + } + return make_sure_not_in_secorfunc(line.gettoken_str(0), 1); + + case TOK_PAGEEXEND: + { + SCRIPT_MSG("PageExEnd\n"); + + if (!cur_page) { + ERROR_MSG("Error: no PageEx open!\n"); + return PS_ERROR; + } + +#ifdef NSIS_SUPPORT_CODECALLBACKS + if (cur_page_type == PAGE_CUSTOM && !cur_page->prefunc) { + ERROR_MSG("Error: custom pages must have a creator function.\n"); + return PS_ERROR; + } +#endif + + page_end(); + + if (cur_page_type == PAGE_INSTFILES) { + add_page(PAGE_COMPLETED); + page_end(); + } + + set_uninstall_mode(0); + } + return make_sure_not_in_secorfunc(line.gettoken_str(0)); + case TOK_PAGECALLBACKS: +#ifdef NSIS_SUPPORT_CODECALLBACKS + { + SCRIPT_MSG("PageCallbacks:"); + if (!cur_page) { + ERROR_MSG("\nPageCallbacks must be used inside PageEx!\n"); + return PS_ERROR; + } + if (cur_page_type == PAGE_CUSTOM) { - SCRIPT_MSG("UninstPage: %s", line.gettoken_str(1)); - - uenable_last_page_cancel = 0; - if (!stricmp(line.gettoken_str(line.getnumtokens()-1),"/ENABLECANCEL")) - uenable_last_page_cancel = 1; - - int k = line.gettoken_enum(1,"custom\0uninstConfirm\0instfiles"); - page p = { - 0, -#ifdef NSIS_SUPPORT_CODECALLBACKS - -1, - -1, - -1, -#endif - 0 - }; - -#ifndef NSIS_SUPPORT_CODECALLBACKS - if (!k) { - ERROR_MSG("Error: custom page specified, NSIS_SUPPORT_CODECALLBACKS not defined.\n"); - return PS_ERROR; - } -#endif//!NSIS_SUPPORT_CODECALLBACKS - - if (k != 2) { - *ubuild_last_page_define=0; - } - - if (k) { - // not custom -#ifdef NSIS_SUPPORT_CODECALLBACKS - switch (line.getnumtokens() - uenable_last_page_cancel) { - case 7: - PRINTHELP(); - case 6: - if (k != 2) { - lstrcpy(ubuild_last_page_define, line.gettoken_str(5)); - } - case 5: - if (*line.gettoken_str(4)) { - if (strnicmp(line.gettoken_str(4),"un.",3)) { - ERROR_MSG("\nError: uninstall function must have a un. prefix!\n"); - return PS_ERROR; - } - p.leavefunc = ns_func.add(line.gettoken_str(4),0); - } - case 4: - if (*line.gettoken_str(3)) { - if (strnicmp(line.gettoken_str(3),"un.",3)) { - ERROR_MSG("\nError: uninstall function must have a un. prefix!\n"); - return PS_ERROR; - } - p.showfunc = ns_func.add(line.gettoken_str(3),0); - } - case 3: - if (*line.gettoken_str(2)) { - if (strnicmp(line.gettoken_str(2),"un.",3)) { - ERROR_MSG("\nError: uninstall function must have a un. prefix!\n"); - return PS_ERROR; - } - p.prefunc = ns_func.add(line.gettoken_str(2),0); - } - } -#else - if (line.getnumtokens() - uenable_last_page_cancel == 3) - lstrcpy(ubuild_last_page_define, line.gettoken_str(2)); -#endif//NSIS_SUPPORT_CODECALLBACKS - } -#ifdef NSIS_SUPPORT_CODECALLBACKS - else { - // a custom page - switch (line.getnumtokens() - uenable_last_page_cancel) { - case 7: - PRINTHELP(); - case 6: - lstrcpy(ubuild_last_page_define, line.gettoken_str(5)); - case 5: - p.caption = add_string_uninst(line.gettoken_str(4)); - case 4: - if (*line.gettoken_str(3)) { - if (strnicmp(line.gettoken_str(3),"un.",3)) { - ERROR_MSG("\nError: uninstall function must have a un. prefix!\n"); - return PS_ERROR; - } - p.leavefunc = ns_func.add(line.gettoken_str(3),0); - } - case 3: - if (*line.gettoken_str(2)) { - if (strnicmp(line.gettoken_str(2),"un.",3)) { - ERROR_MSG("\nError: uninstall function must have a un. prefix!\n"); - return PS_ERROR; - } - p.prefunc = ns_func.add(line.gettoken_str(2),0); - } - break; - case 2: - ERROR_MSG("\nError: custom page must have a creator function!\n"); - PRINTHELP(); - } - } -#endif//NSIS_SUPPORT_CODECALLBACKS - - switch (k) { - case 0: - p.id = NSIS_PAGE_CUSTOM; - ubuild_custom_used++; - break; - case 1: - p.id = NSIS_PAGE_UNINST; - p.caption=LANG_SUBCAPTION(0); - break; - case 2: - if (*ubuild_last_page_define) definedlist.add(ubuild_last_page_define,""); - p.id = NSIS_PAGE_INSTFILES; - p.caption=LANG_SUBCAPTION(1); - break; - default: + switch (line.getnumtokens()) + { + case 4: + { PRINTHELP(); - } - -#ifdef NSIS_SUPPORT_CODECALLBACKS - if (p.prefunc>=0) - SCRIPT_MSG(" (%s:%s)", k?"pre":"creator", line.gettoken_str(2)); - if (p.showfunc>=0 && k) - SCRIPT_MSG(" (show:%s)", line.gettoken_str(3)); - if (p.leavefunc>=0) - SCRIPT_MSG(" (leave:%s)", line.gettoken_str(4-!k)); - else if (p.caption && !k) - SCRIPT_MSG(" (caption:%s)", line.gettoken_str(3)); -#endif - SCRIPT_MSG("\n"); - - ubuild_pages.add(&p,sizeof(page)); - build_uninst.common.num_pages++; - if (p.id==NSIS_PAGE_INSTFILES) { - p.id=NSIS_PAGE_COMPLETED; -#ifdef NSIS_SUPPORT_CODECALLBACKS - p.prefunc=-1; - p.showfunc=-1; - p.leavefunc=-1; -#endif - p.caption=LANG_SUBCAPTION(2); - ubuild_pages.add(&p,sizeof(page)); - build_uninst.common.num_pages++; + } + case 3: + { + if (*line.gettoken_str(2)) + { + if (strnicmp(line.gettoken_str(2), "un.", 3)) + { + if (uninstall_mode) + { + ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n"); + return PS_ERROR; + } + } + else + { + if (!uninstall_mode) + { + ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n"); + return PS_ERROR; + } + } + cur_page->leavefunc = ns_func.add(line.gettoken_str(2),0); + } + } + case 2: + { + if (*line.gettoken_str(1)) + { + if (strnicmp(line.gettoken_str(1), "un.", 3)) + { + if (uninstall_mode) + { + ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n"); + return PS_ERROR; + } + } + else + { + if (!uninstall_mode) + { + ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n"); + return PS_ERROR; + } + } + cur_page->prefunc = ns_func.add(line.gettoken_str(1),0); + } + } } } - return make_sure_not_in_secorfunc(line.gettoken_str(0)); + else + { + switch (line.getnumtokens()) + { + case 4: + { + if (*line.gettoken_str(3)) + { + if (strnicmp(line.gettoken_str(3), "un.", 3)) + { + if (uninstall_mode) + { + ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n"); + return PS_ERROR; + } + } + else + { + if (!uninstall_mode) + { + ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n"); + return PS_ERROR; + } + } + cur_page->leavefunc = ns_func.add(line.gettoken_str(3),0); + } + } + case 3: + { + if (*line.gettoken_str(2)) + { + if (strnicmp(line.gettoken_str(2), "un.", 3)) + { + if (uninstall_mode) + { + ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n"); + return PS_ERROR; + } + } + else + { + if (!uninstall_mode) + { + ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n"); + return PS_ERROR; + } + } + cur_page->showfunc = ns_func.add(line.gettoken_str(2),0); + } + } + case 2: + { + if (*line.gettoken_str(1)) + { + if (strnicmp(line.gettoken_str(1), "un.", 3)) + { + if (uninstall_mode) + { + ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n"); + return PS_ERROR; + } + } + else + { + if (!uninstall_mode) + { + ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n"); + return PS_ERROR; + } + } + cur_page->prefunc = ns_func.add(line.gettoken_str(1),0); + } + } + } + } + + int custom = cur_page_type == PAGE_CUSTOM ? 1 : 0; + + if (cur_page->prefunc>=0) + SCRIPT_MSG(" %s:%s", !custom?"pre":"creator", line.gettoken_str(1)); + if (cur_page->showfunc>=0 && !custom) + SCRIPT_MSG(" show:%s", line.gettoken_str(2)); + if (cur_page->leavefunc>=0) + SCRIPT_MSG(" leave:%s", line.gettoken_str(3-custom)); + + SCRIPT_MSG("\n"); + } + return make_sure_not_in_secorfunc(line.gettoken_str(0), 1); #else - ERROR_MSG("Error: %s specified, NSIS_CONFIG_UNINSTALL_SUPPORT not defined.\n", line.gettoken_str(0)); + ERROR_MSG("Error: %s specified, NSIS_SUPPORT_CODECALLBACKS not defined.\n", line.gettoken_str(0)); return PS_ERROR; -#endif +#endif//NSIS_SUPPORT_CODECALLBACKS +#else + case TOK_PAGE: + case TOK_UNINSTPAGE: + case TOK_PAGEEX: + case TOK_PAGEEXEND: + case TOK_PAGECALLBACKS: + ERROR_MSG("Error: %s specified, NSIS_CONFIG_VISIBLE_SUPPORT not defined.\n", line.gettoken_str(0)); + return PS_ERROR; +#endif//NSIS_CONFIG_VISIBLE_SUPPORT // header flags /////////////////////////////////////////////////////////////////////////////// case TOK_LANGSTRING: - case TOK_LANGSTRINGUP: - SCRIPT_MSG("LangString: \"%s\" %s \"%s\"%s\n", line.gettoken_str(1), line.gettoken_str(2), line.gettoken_str(3), which_token==TOK_LANGSTRINGUP?" (unprocessed)":""); - if (SetUserString(line.gettoken_str(1), line.gettoken_int(2), line.gettoken_str(3), which_token==TOK_LANGSTRING) != PS_OK) - { - ERROR_MSG("Error: LangString: can't add user string!\n"); + { + char *name = line.gettoken_str(1); + LANGID lang = line.gettoken_int(2); + char *str = line.gettoken_str(3); + int ret = SetLangString(name, lang, str); + if (ret == PS_WARNING) + warning_fl("LangString \"%s\" set multiple times for %d, wasting space", name, lang); + else if (ret == PS_ERROR) { + ERROR_MSG("Error: can't set LangString \"%s\"!\n", name); return PS_ERROR; } + SCRIPT_MSG("LangString: \"%s\" %d \"%s\"\n", name, lang, str); + } + return make_sure_not_in_secorfunc(line.gettoken_str(0)); + case TOK_LANGSTRINGUP: + SCRIPT_MSG("Error: LangStringUP is obsolete, there are no more unprocessed strings. Use LangString.\n"); + return PS_ERROR; + case TOK_LICENSELANGSTRING: + { +#ifdef NSIS_CONFIG_SILENT_SUPPORT + if (build_header.flags&(CH_FLAGS_SILENT|CH_FLAGS_SILENT_LOG)) + { + warning_fl("LicenseLangString: SilentInstall enabled, wasting space"); + } +#endif + char *name = line.gettoken_str(1); + LANGID lang = line.gettoken_int(2); + char *file = line.gettoken_str(3); + + FILE *fp; + int datalen; + fp=fopen(file,"rb"); + if (!fp) + { + ERROR_MSG("LicenseLangString: open failed \"%s\"\n",file); + PRINTHELP() + } + fseek(fp,0,SEEK_END); + datalen=ftell(fp); + if (!datalen) + { + ERROR_MSG("LicenseLangString: empty license file \"%s\"\n",file); + fclose(fp); + return PS_ERROR; + } + rewind(fp); + char *data=(char*)malloc(datalen+2); + char *ldata=data+1; + if (fread(ldata,1,datalen,fp) != datalen) + { + ERROR_MSG("LicenseLangString: can't read file.\n"); + fclose(fp); + return PS_ERROR; + } + fclose(fp); + ldata[datalen]=0; + if (!strncmp(ldata,"{\\rtf",sizeof("{\\rtf")-1)) + *data = SF_RTF; + else + *data = SF_TEXT; + + int ret = SetLangString(name, lang, data); + if (ret == PS_WARNING) + warning_fl("LicenseLangString \"%s\" set multiple times for %d, wasting space", name, lang); + else if (ret == PS_ERROR) + { + ERROR_MSG("Error: can't set LicenseLangString \"%s\"!\n", name); + return PS_ERROR; + } + + SCRIPT_MSG("LicenseLangString: \"%s\" %d \"%s\"\n", name, lang, file); + } return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_NAME: { - int a = 1; - WORD lang = 0; - if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); - if (line.getnumtokens()!=a+1) PRINTHELP(); - if (IsSet(common.name,lang)) - warning("%s: specified multiple times, wasting space (%s:%d)",line.gettoken_str(0),curfilename,linecnt); - SetString(line.gettoken_str(a),SLANG_NAME,0,lang); - SCRIPT_MSG("Name: \"%s\"\n",line.gettoken_str(a)); + if (SetInnerString(NLF_NAME,line.gettoken_str(1)) == PS_WARNING) + warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0)); + SCRIPT_MSG("Name: \"%s\"\n",line.gettoken_str(1)); } return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_CAPTION: { - int a = 1; - WORD lang = 0; - if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); - if (line.getnumtokens()!=a+1) PRINTHELP(); - if (IsSet(common.caption,lang)) - warning("%s: specified multiple times, wasting space (%s:%d)",line.gettoken_str(0),curfilename,linecnt); - SetString(line.gettoken_str(a),NLF_CAPTION,1,lang); - SCRIPT_MSG("Caption: \"%s\"\n",line.gettoken_str(a)); + if (!cur_page) + { + if (SetInnerString(NLF_CAPTION,line.gettoken_str(1)) == PS_WARNING) + warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0)); + } + else + { + cur_page->caption = add_string(line.gettoken_str(1)); + } + SCRIPT_MSG("Caption: \"%s\"\n",line.gettoken_str(1)); } - return make_sure_not_in_secorfunc(line.gettoken_str(0)); + return make_sure_not_in_secorfunc(line.gettoken_str(0), 1); case TOK_ICON: SCRIPT_MSG("Icon: \"%s\"\n",line.gettoken_str(1)); try { @@ -1166,7 +1269,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) } return make_sure_not_in_secorfunc(line.gettoken_str(0)); #ifdef NSIS_CONFIG_COMPONENTPAGE - // Changed by Amir Szekely 24th July 2002 case TOK_CHECKBITMAP: SCRIPT_MSG("CheckBitmap: \"%s\"\n",line.gettoken_str(1)); try { @@ -1203,78 +1305,118 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) case TOK_DIRTEXT: #ifdef NSIS_CONFIG_VISIBLE_SUPPORT { - int a = 1; - WORD lang = 0; - if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); - if (line.getnumtokens()==a) PRINTHELP(); - if (IsSet(installer.text,lang) && line.gettoken_str(a)[0]) - warning("%s: specified multiple times, wasting space (%s:%d)",line.gettoken_str(0),curfilename,linecnt); - SetString(line.gettoken_str(a),SLANG_DIR_TEXT,0,lang); - if (line.getnumtokens()>a+1) SetString(line.gettoken_str(a+1),NLF_DIR_SUBTEXT,0,lang); - if (line.getnumtokens()>a+2) SetString(line.gettoken_str(a+2),NLF_BTN_BROWSE,0,lang); - SCRIPT_MSG("DirText: \"%s\" \"%s\" \"%s\"\n",line.gettoken_str(a),line.gettoken_str(a+1),line.gettoken_str(a+2)); + if (!cur_page) { + if (SetInnerString(NLF_DIR_TEXT, line.gettoken_str(1)) == PS_WARNING) + warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0)); + if (line.getnumtokens() > 2) + SetInnerString(NLF_DIR_SUBTEXT, line.gettoken_str(2)); + if (line.getnumtokens() > 3) + SetInnerString(NLF_BTN_BROWSE, line.gettoken_str(3)); + if (line.getnumtokens() > 4) + SetInnerString(NLF_DIR_BROWSETEXT, line.gettoken_str(4)); + } + else { + if (cur_page_type != PAGE_DIRECTORY) { + ERROR_MSG("Error: DirText can only be used inside PageEx directory.\n"); + return PS_ERROR; + } + cur_page->parms[0] = add_string(line.gettoken_str(1)); + if (line.getnumtokens() > 2) + cur_page->parms[1] = add_string(line.gettoken_str(2)); + if (line.getnumtokens() > 3) + cur_page->parms[2] = add_string(line.gettoken_str(3)); + if (line.getnumtokens() > 4) + cur_page->parms[3] = add_string(line.gettoken_str(4)); + } + SCRIPT_MSG("DirText: \"%s\" \"%s\" \"%s\" \"%s\"\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4)); } - return make_sure_not_in_secorfunc(line.gettoken_str(0)); + return make_sure_not_in_secorfunc(line.gettoken_str(0), 1); #else//NSIS_CONFIG_VISIBLE_SUPPORT ERROR_MSG("Error: %s specified, NSIS_CONFIG_VISIBLE_SUPPORT not defined.\n", line.gettoken_str(0)); return PS_ERROR; #endif//!NSIS_CONFIG_VISIBLE_SUPPORT + case TOK_DIRVAR: + { + if (!cur_page || (cur_page_type != PAGE_DIRECTORY && cur_page_type != PAGE_UNINSTCONFIRM)) { + ERROR_MSG("Error: can't use DirVar outside of PageEx directory|uninstConfirm.\n"); + return PS_ERROR; + } + cur_page->parms[4] = GetUserVarIndex(line, 1) + 1; + if (cur_page->parms[4] <= 0) PRINTHELP(); + SCRIPT_MSG("DirVar: %s\n", line.gettoken_str(1)); + } + return make_sure_not_in_secorfunc(line.gettoken_str(0), 1); #ifdef NSIS_CONFIG_COMPONENTPAGE case TOK_COMPTEXT: { - int a = 1; - WORD lang = 0; - if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); - if (line.getnumtokens()==a) PRINTHELP(); - if (IsSet(installer.componenttext,lang) && line.gettoken_str(a)[0]) - warning("%s: specified multiple times, wasting space (%s:%d)",line.gettoken_str(0),curfilename,linecnt); - SetString(line.gettoken_str(a),SLANG_COMP_TEXT,0,lang); - if (line.getnumtokens()>a+1) SetString(line.gettoken_str(a+1),NLF_COMP_SUBTEXT1,0,lang); - if (line.getnumtokens()>a+2) SetString(line.gettoken_str(a+2),NLF_COMP_SUBTEXT2,0,lang); - SCRIPT_MSG("ComponentText: \"%s\" \"%s\" \"%s\"\n",line.gettoken_str(a),line.gettoken_str(a+1),line.gettoken_str(a+2)); + if (!cur_page) { + if (SetInnerString(NLF_COMP_TEXT, line.gettoken_str(1)) == PS_WARNING) + warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0)); + if (line.getnumtokens() > 2) + SetInnerString(NLF_COMP_SUBTEXT1, line.gettoken_str(2)); + if (line.getnumtokens() > 3) + SetInnerString(NLF_COMP_SUBTEXT2, line.gettoken_str(3)); + } + else { + if (cur_page_type != PAGE_COMPONENTS) { + ERROR_MSG("Error: ComponentText can only be used inside PageEx components.\n"); + return PS_ERROR; + } + cur_page->parms[0] = add_string(line.gettoken_str(1)); + cur_page->parms[1] = add_string(line.gettoken_str(2)); + cur_page->parms[2] = add_string(line.gettoken_str(3)); + cur_page->parms[3] = cur_page->parms[1]; + cur_page->parms[4] = cur_page->parms[2]; + } + SCRIPT_MSG("ComponentText: \"%s\" \"%s\" \"%s\"\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3)); } - return make_sure_not_in_secorfunc(line.gettoken_str(0)); + return make_sure_not_in_secorfunc(line.gettoken_str(0), 1); case TOK_INSTTYPE: { int x; - if (strnicmp(line.gettoken_str(1),"/LANG=",6) && line.getnumtokens() > 2) PRINTHELP(); if (!stricmp(line.gettoken_str(1),"/NOCUSTOM")) { - build_header.common.flags|=CH_FLAGS_NO_CUSTOM; + build_header.flags|=CH_FLAGS_NO_CUSTOM; SCRIPT_MSG("InstType: disabling custom install type\n"); } else if (!stricmp(line.gettoken_str(1),"/COMPONENTSONLYONCUSTOM")) { - build_header.common.flags|=CH_FLAGS_COMP_ONLY_ON_CUSTOM; + build_header.flags|=CH_FLAGS_COMP_ONLY_ON_CUSTOM; SCRIPT_MSG("InstType: making components viewable only on custom install type\n"); } - else if (!strnicmp(line.gettoken_str(1),"/LANG=",6)) { - if (!strnicmp(line.gettoken_str(2),"/CUSTOMSTRING=",14)) { - SCRIPT_MSG("InstType: setting custom text to: /LANG=%d \"%s\"\n",line.gettoken_str(1)+6,line.gettoken_str(2)+14); - SetString(line.gettoken_str(2)+14,NLF_COMP_CUSTOM,0,atoi(line.gettoken_str(1)+6)); - } - else PRINTHELP() - } else if (!strnicmp(line.gettoken_str(1),"/CUSTOMSTRING=",14)) { SCRIPT_MSG("InstType: setting custom text to: \"%s\"\n",line.gettoken_str(1)+14); - SetString(line.gettoken_str(1)+14,NLF_COMP_CUSTOM,0); + if (SetInnerString(NLF_COMP_CUSTOM,line.gettoken_str(1)+14) == PS_WARNING) + warning_fl("%s: specified multiple times, wasting space","InstType /CUSTOMSTRING"); + } + else if (line.gettoken_str(1)[0]=='/') + { + PRINTHELP() } - else if (line.gettoken_str(1)[0]=='/') PRINTHELP() else { - for (x = 0; x < NSIS_MAX_INST_TYPES && build_header.install_types[x]; x ++); - if (x==NSIS_MAX_INST_TYPES) + char *itname = line.gettoken_str(1); + + if (!strnicmp(itname, "un.", 3)) { + set_uninstall_mode(1); + itname += 3; + } + + for (x = 0; x < NSIS_MAX_INST_TYPES && cur_header->install_types[x]; x ++); + if (x == NSIS_MAX_INST_TYPES) { - ERROR_MSG("InstType: no more than %d install types allowed. %d specified\n",NSIS_MAX_INST_TYPES,NSIS_MAX_INST_TYPES+1); + ERROR_MSG("InstType: no more than %d install types allowed. %d specified\n", NSIS_MAX_INST_TYPES, NSIS_MAX_INST_TYPES + 1); return PS_ERROR; } else { - build_header.install_types[x] = add_string_main(line.gettoken_str(1)); - SCRIPT_MSG("InstType: %d=\"%s\"\n",x+1,line.gettoken_str(1)); + cur_header->install_types[x] = add_string(itname); + SCRIPT_MSG("InstType: %s%d=\"%s\"\n", uninstall_mode ? "(uninstall) " : "", x+1, itname); } + + set_uninstall_mode(0); } } return make_sure_not_in_secorfunc(line.gettoken_str(0)); @@ -1287,174 +1429,170 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) #ifdef NSIS_CONFIG_LICENSEPAGE case TOK_LICENSETEXT: { - int a = 1; - WORD lang = 0; - if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); - if (line.getnumtokens()==a) PRINTHELP(); - if (IsSet(installer.licensetext,lang)) - warning("%s: specified multiple times, wasting space (%s:%d)",line.gettoken_str(0),curfilename,linecnt); - SetString(line.gettoken_str(a),SLANG_LICENSE_TEXT,0,lang); - if (line.getnumtokens()>a+1) SetString(line.gettoken_str(a+1),NLF_BTN_LICENSE,0,lang); - SCRIPT_MSG("LicenseText: \"%s\" \"%s\"\n",line.gettoken_str(a),line.gettoken_str(a+1)); + if (!cur_page) { + if (SetInnerString(NLF_LICENSE_TEXT, line.gettoken_str(1)) == PS_WARNING) + warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0)); + SetInnerString(NLF_LICENSE_TEXT_FSRB, line.gettoken_str(1)); + SetInnerString(NLF_LICENSE_TEXT_FSCB, line.gettoken_str(1)); + if (line.getnumtokens() > 2) + SetInnerString(NLF_BTN_LICENSE, line.gettoken_str(2)); + } + else { + if (cur_page_type != PAGE_LICENSE) { + ERROR_MSG("Error: LicenseText can only be used inside PageEx license.\n"); + return PS_ERROR; + } + cur_page->parms[0] = add_string(line.gettoken_str(1)); + cur_page->next = add_string(line.gettoken_str(2)); + } + SCRIPT_MSG("LicenseText: \"%s\" \"%s\"\n",line.gettoken_str(1),line.gettoken_str(2)); } - return make_sure_not_in_secorfunc(line.gettoken_str(0)); + return make_sure_not_in_secorfunc(line.gettoken_str(0), 1); case TOK_LICENSEDATA: #ifdef NSIS_CONFIG_SILENT_SUPPORT - if (build_header.common.flags&(CH_FLAGS_SILENT|CH_FLAGS_SILENT_LOG)) + if (build_header.flags&(CH_FLAGS_SILENT|CH_FLAGS_SILENT_LOG)) { - warning("LicenseData: SilentInstall enabled, wasting space (%s:%d)",curfilename,linecnt); + warning_fl("LicenseData: SilentInstall enabled, wasting space"); } #endif { - int a = 1; - WORD lang = 0; - if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); - if (line.getnumtokens()==a) PRINTHELP(); - if (IsSet(installer.licensedata,lang)) - warning("%s: specified multiple times, wasting space (%s:%d)",line.gettoken_str(0),curfilename,linecnt); - FILE *fp; - int datalen; - fp=fopen(line.gettoken_str(a),"rb"); - if (!fp) + int idx = 0; + char *file = line.gettoken_str(1); + char *data; + + if (file[0] == '$' && file[1] == '(') { - ERROR_MSG("LicenseData: open failed \"%s\"\n",line.gettoken_str(a)); - PRINTHELP() + char *cp = strdup(file+2); + char *p = strchr(cp, ')'); + if (p && p[1] == 0) { // if string is only a language str identifier + *p = 0; + if (!uninstall_mode && !strnicmp(cp,"un.",3)) + { + ERROR_MSG("Installer language strings can't start with un. (%s)! (%s:%d)", cp, curfilename, linecnt); + free(cp); + return PS_ERROR; + } + else if (uninstall_mode && strnicmp(cp,"un.",3)) + { + ERROR_MSG("Uninstaller language strings must start with un. (%s)! (%s:%d)", cp, curfilename, linecnt); + free(cp); + return PS_ERROR; + } + idx = DefineLangString(cp, 0); + } + free(cp); + data = file; } - fseek(fp,0,SEEK_END); - datalen=ftell(fp); - if (!datalen) + + if (!idx) { - ERROR_MSG("LicenseData: empty license file \"%s\"\n",line.gettoken_str(a)); + int datalen; + FILE *fp=fopen(file,"rb"); + if (!fp) + { + ERROR_MSG("LicenseData: open failed \"%s\"\n",file); + PRINTHELP() + } + fseek(fp,0,SEEK_END); + datalen=ftell(fp); + if (!datalen) + { + ERROR_MSG("LicenseData: empty license file \"%s\"\n",file); + fclose(fp); + return PS_ERROR; + } + rewind(fp); + data=(char*)malloc(datalen+2); + char *ldata=data+1; + if (fread(ldata,1,datalen,fp) != datalen) { + ERROR_MSG("LicenseData: can't read file.\n"); + fclose(fp); + return PS_ERROR; + } fclose(fp); - return PS_ERROR; + ldata[datalen]=0; + if (!strncmp(ldata,"{\\rtf",sizeof("{\\rtf")-1)) + *data = SF_RTF; + else + *data = SF_TEXT; } - rewind(fp); - char *data=(char*)malloc(datalen+1); - if (fread(data,1,datalen,fp) != datalen) { - ERROR_MSG("LicenseData: can't read file.\n"); - fclose(fp); - return PS_ERROR; + + if (!cur_page) { + if (SetInnerString(NLF_LICENSE_DATA,data) == PS_WARNING) + warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0)); } - fclose(fp); - data[datalen]=0; - SetString(data,SLANG_LICENSE_DATA,0,lang); - SCRIPT_MSG("LicenseData: \"%s\"\n",line.gettoken_str(a)); + else { + if (cur_page_type != PAGE_LICENSE) { + ERROR_MSG("Error: LicenseData can only be used inside PageEx license.\n"); + return PS_ERROR; + } + + cur_page->parms[1] = add_string(data, 0); + } + SCRIPT_MSG("LicenseData: \"%s\"\n",file); } - return make_sure_not_in_secorfunc(line.gettoken_str(0)); + return make_sure_not_in_secorfunc(line.gettoken_str(0), 1); case TOK_LICENSEFORCESELECTION: { - LANGID lang = 0; - int a = 0; - - if (!strnicmp(line.gettoken_str(1),"/LANG=",6)) { - lang=atoi(line.gettoken_str(1)+6); - a++; - } - - int k=line.gettoken_enum(1+a,"off\0checkbox\0radiobuttons\0"); + int k=line.gettoken_enum(1,"off\0checkbox\0radiobuttons\0"); if (k == -1) PRINTHELP() - if (k < line.getnumtokens() - 2 - a) PRINTHELP() + if (k < line.getnumtokens() - 2) PRINTHELP() - switch (line.getnumtokens()-a) { - case 4: - SetString(line.gettoken_str(3+a), NLF_BTN_LICENSE_DISAGREE, 0, lang); - case 3: - SetString(line.gettoken_str(2+a), NLF_BTN_LICENSE_AGREE, 0, lang); - break; - } - - try { - init_res_editor(); - - BYTE* dlg = res_editor->GetResource(RT_DIALOG, MAKEINTRESOURCE(IDD_LICENSE), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)); - if (!dlg) throw runtime_error("IDD_LICENSE doesn't exist!"); - CDialogTemplate dt(dlg,uDefCodePage); - free(dlg); + if (!cur_page) { + switch (line.getnumtokens()) { + case 4: + SetInnerString(NLF_BTN_LICENSE_DISAGREE, line.gettoken_str(3)); + case 3: + SetInnerString(NLF_BTN_LICENSE_AGREE, line.gettoken_str(2)); + break; + } switch (k) { case 0: - build_header.common.flags&=~CH_FLAGS_LICENSE_FORCE_SELECTION; - dt.RemoveItem(IDC_LICENSEAGREE); - dt.RemoveItem(IDC_LICENSEDISAGREE); + license_res_id = IDD_LICENSE; break; case 1: - { - build_header.common.flags|=CH_FLAGS_LICENSE_FORCE_SELECTION; - - DialogItemTemplate *licenseData = dt.GetItem(IDC_EDIT1); - - DialogItemTemplate *item; - for (int i = 0; item = dt.GetItemByIdx(i); i++) { - if (item->sY >= licenseData->sY + licenseData->sHeight) { - item->sY -= 10; - } - } - - licenseData->sHeight -= 10; - - DialogItemTemplate checkBox = { - 0, - 0, - dt.GetHeight() - 9, - dt.GetWidth(), - 9, - 0, - BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, - IDC_LICENSEAGREE, - MAKEINTRESOURCE(0x0080), - }; - dt.AddItem(checkBox); - + license_res_id = IDD_LICENSE_FSCB; break; - } case 2: - { - build_header.common.flags|=CH_FLAGS_LICENSE_FORCE_SELECTION; - - license_force_radio_used=true; - - DialogItemTemplate *licenseData = dt.GetItem(IDC_EDIT1); - - DialogItemTemplate *item; - for (int i = 0; item = dt.GetItemByIdx(i); i++) { - if (item->sY >= licenseData->sY + licenseData->sHeight) { - item->sY -= 20; - } - } - - licenseData->sHeight -= 20; - - DialogItemTemplate radionButton = { - 0, - 0, - dt.GetHeight() - 9, - dt.GetWidth(), - 9, - 0, - BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, - IDC_LICENSEDISAGREE, - MAKEINTRESOURCE(0x0080), - }; - dt.AddItem(radionButton); - - radionButton.sY -= 10; - radionButton.wId = IDC_LICENSEAGREE; - dt.AddItem(radionButton); - } + license_res_id = IDD_LICENSE_FSRB; + break; + } + } + else { + if (cur_page_type != PAGE_LICENSE) { + ERROR_MSG("Error: LicenseForceSelection can only be used inside PageEx license.\n"); + return PS_ERROR; + } + switch (line.getnumtokens()) { + case 4: + cur_page->parms[3] = add_string(line.gettoken_str(3)); + case 3: + cur_page->parms[2] = add_string(line.gettoken_str(2)); + break; } - DWORD dwSize; - dlg = dt.Save(dwSize); - res_editor->UpdateResource(RT_DIALOG, MAKEINTRESOURCE(IDD_LICENSE), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), dlg, dwSize); - free(dlg); + cur_page->flags &= ~(PF_LICENSE_FORCE_SELECTION | PF_LICENSE_NO_FORCE_SELECTION); + + switch (k) { + case 0: + cur_page->dlg_id = IDD_LICENSE; + cur_page->flags |= PF_LICENSE_NO_FORCE_SELECTION; + break; + case 1: + cur_page->dlg_id = IDD_LICENSE_FSCB; + cur_page->flags |= PF_LICENSE_FORCE_SELECTION; + break; + case 2: + cur_page->dlg_id = IDD_LICENSE_FSRB; + cur_page->flags |= PF_LICENSE_FORCE_SELECTION; + break; + } } - catch (exception& err) { - ERROR_MSG("Error in LicenseForceSelection: %s\n", err.what()); - return PS_ERROR; - } - SCRIPT_MSG("LicenseForceSelection: %s \"%s\" \"%s\"\n", line.gettoken_str(1+a), line.gettoken_str(2+a), line.gettoken_str(3+a)); + + SCRIPT_MSG("LicenseForceSelection: %s \"%s\" \"%s\"\n", line.gettoken_str(1), line.gettoken_str(2), line.gettoken_str(3)); } - return make_sure_not_in_secorfunc(line.gettoken_str(0)); + return make_sure_not_in_secorfunc(line.gettoken_str(0), 1); case TOK_LICENSEBKCOLOR: { char *p = line.gettoken_str(1); @@ -1472,6 +1610,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) { int v=strtoul(p,&p,16); build_header.license_bg=((v&0xff)<<16)|(v&0xff00)|((v&0xff0000)>>16); + build_uninst.license_bg=build_header.license_bg; SCRIPT_MSG("LicenseBkColor: %06X\n",v); } } @@ -1497,31 +1636,31 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) #endif//NSIS_CONFIG_LOG SCRIPT_MSG("SilentInstall: %s\n",line.gettoken_str(1)); #ifdef NSIS_CONFIG_LICENSEPAGE - if (k && !IsNotSet(installer.licensedata)) + if (k && HasUserDefined(NLF_LICENSE_DATA)) { - warning("SilentInstall: LicenseData already specified. wasting space (%s:%d)",curfilename,linecnt); + warning_fl("SilentInstall: LicenseData already specified. wasting space"); } if (k) { - build_header.common.flags|=CH_FLAGS_SILENT; + build_header.flags|=CH_FLAGS_SILENT; if (k == 2) - build_header.common.flags|=CH_FLAGS_SILENT_LOG; + build_header.flags|=CH_FLAGS_SILENT_LOG; } else { - build_header.common.flags&=~CH_FLAGS_SILENT; - build_header.common.flags&=~CH_FLAGS_SILENT_LOG; + build_header.flags&=~CH_FLAGS_SILENT; + build_header.flags&=~CH_FLAGS_SILENT_LOG; } #endif//NSIS_CONFIG_LICENSEPAGE } return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_SILENTUNINST: - { #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT + { int k=line.gettoken_enum(1,"normal\0silent\0"); if (k<0) PRINTHELP() if (k) - build_uninst.common.flags|=CH_FLAGS_SILENT; + build_uninst.flags|=CH_FLAGS_SILENT; else - build_uninst.common.flags&=~CH_FLAGS_SILENT; + build_uninst.flags&=~CH_FLAGS_SILENT; SCRIPT_MSG("SilentUnInstall: %s\n",line.gettoken_str(1)); } return make_sure_not_in_secorfunc(line.gettoken_str(0)); @@ -1529,9 +1668,29 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ERROR_MSG("Error: %s specified, NSIS_CONFIG_UNINSTALL_SUPPORT not defined.\n", line.gettoken_str(0)); return PS_ERROR; #endif + case TOK_IFSILENT: + ent.which=EW_IFFLAG; + if (process_jump(line,1,&ent.offsets[0]) || + process_jump(line,2,&ent.offsets[1])) PRINTHELP() + ent.offsets[2]=FLAG_OFFSET(silent); + ent.offsets[3]=~0;//new value mask - keep flag + SCRIPT_MSG("IfSilent ?%s:%s\n",line.gettoken_str(1),line.gettoken_str(2)); + return add_entry(&ent); + case TOK_SETSILENT: + { + ent.which=EW_SETFLAG; + ent.offsets[0]=FLAG_OFFSET(silent); + int k=line.gettoken_enum(1,"normal\0silent\0"); + if (k<0) PRINTHELP() + ent.offsets[1]=add_intstring(k); + SCRIPT_MSG("SetSilent: %s\n",line.gettoken_str(1)); + } + return add_entry(&ent); #else//!NSIS_CONFIG_SILENT_SUPPORT case TOK_SILENTINST: case TOK_SILENTUNINST: + case TOK_IFSILENT: + case TOK_SETSILENT: ERROR_MSG("Error: %s specified, NSIS_CONFIG_SILENT_SUPPORT not defined.\n", line.gettoken_str(0)); return PS_ERROR; #endif//NSIS_CONFIG_SILENT_SUPPORT @@ -1544,9 +1703,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) char *p = line.gettoken_str(1); if (build_header.install_directory_ptr) { - warning("%s: specified multiple times. wasting space (%s:%d)",line.gettoken_str(0),curfilename,linecnt); + warning_fl("%s: specified multiple times. wasting space",line.gettoken_str(0)); } - build_header.install_directory_ptr = add_string_main(p); + build_header.install_directory_ptr = add_string(p); build_header.install_directory_auto_append = 0; if (*p && *CharPrev(p, p + strlen(p)) != '\\') { @@ -1565,15 +1724,16 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) { if (build_header.install_reg_key_ptr) { - warning("%s: specified multiple times, wasting space (%s:%d)",line.gettoken_str(0),curfilename,linecnt); + warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0)); } int k=line.gettoken_enum(1,rootkeys[0]); if (k == -1) k=line.gettoken_enum(1,rootkeys[1]); if (k == -1) PRINTHELP() build_header.install_reg_rootkey=(int)rootkey_tab[k]; - build_header.install_reg_key_ptr = add_string_main(line.gettoken_str(2),0); - if (line.gettoken_str(2)[0] == '\\') warning("%s: registry path name begins with \'\\\', may cause problems (%s:%d)",line.gettoken_str(0),curfilename,linecnt); - build_header.install_reg_value_ptr = add_string_main(line.gettoken_str(3),0); + build_header.install_reg_key_ptr = add_string(line.gettoken_str(2),0); + if (line.gettoken_str(2)[0] == '\\') + warning_fl("%s: registry path name begins with \'\\\', may cause problems",line.gettoken_str(0)); + build_header.install_reg_value_ptr = add_string(line.gettoken_str(3),0); SCRIPT_MSG("InstallRegKey: \"%s\\%s\\%s\"\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3)); } return make_sure_not_in_secorfunc(line.gettoken_str(0)); @@ -1586,11 +1746,11 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) { int x; int smooth=0; - build_header.common.flags&=~CH_FLAGS_PROGRESS_COLORED; + build_header.flags&=~CH_FLAGS_PROGRESS_COLORED; for (x = 1; x < line.getnumtokens(); x ++) { if (!stricmp(line.gettoken_str(x),"smooth")) smooth=1; - else if (!stricmp(line.gettoken_str(x),"colored")) build_header.common.flags|=CH_FLAGS_PROGRESS_COLORED; + else if (!stricmp(line.gettoken_str(x),"colored")) build_header.flags|=CH_FLAGS_PROGRESS_COLORED; else PRINTHELP() } try { @@ -1620,7 +1780,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return PS_ERROR; } SCRIPT_MSG("InstProgressFlags: smooth=%d, colored=%d\n",smooth, - !!(build_header.common.flags&CH_FLAGS_PROGRESS_COLORED)); + !!(build_header.flags&CH_FLAGS_PROGRESS_COLORED)); } return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_AUTOCLOSE: @@ -1628,9 +1788,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) int k=line.gettoken_enum(1,"false\0true\0"); if (k == -1) PRINTHELP(); if (k) - build_header.common.flags|=CH_FLAGS_AUTO_CLOSE; + build_header.flags|=CH_FLAGS_AUTO_CLOSE; else - build_header.common.flags&=~CH_FLAGS_AUTO_CLOSE; + build_header.flags&=~CH_FLAGS_AUTO_CLOSE; SCRIPT_MSG("AutoCloseWindow: %s\n",k?"true":"false"); } return make_sure_not_in_secorfunc(line.gettoken_str(0)); @@ -1705,20 +1865,20 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT if (which_token == TOK_SHOWDETAILSUNINST) { - build_uninst.common.flags&=~(CH_FLAGS_DETAILS_NEVERSHOW|CH_FLAGS_DETAILS_SHOWDETAILS); + build_uninst.flags&=~(CH_FLAGS_DETAILS_NEVERSHOW|CH_FLAGS_DETAILS_SHOWDETAILS); if (k==1) - build_uninst.common.flags|=CH_FLAGS_DETAILS_SHOWDETAILS; + build_uninst.flags|=CH_FLAGS_DETAILS_SHOWDETAILS; else if (k==2) - build_uninst.common.flags|=CH_FLAGS_DETAILS_NEVERSHOW; + build_uninst.flags|=CH_FLAGS_DETAILS_NEVERSHOW; } else #endif { - build_header.common.flags&=~(CH_FLAGS_DETAILS_NEVERSHOW|CH_FLAGS_DETAILS_SHOWDETAILS); + build_header.flags&=~(CH_FLAGS_DETAILS_NEVERSHOW|CH_FLAGS_DETAILS_SHOWDETAILS); if (k==1) - build_header.common.flags|=CH_FLAGS_DETAILS_SHOWDETAILS; + build_header.flags|=CH_FLAGS_DETAILS_SHOWDETAILS; else if (k==2) - build_header.common.flags|=CH_FLAGS_DETAILS_NEVERSHOW; + build_header.flags|=CH_FLAGS_DETAILS_NEVERSHOW; } SCRIPT_MSG("%s: %s\n",line.gettoken_str(0),line.gettoken_str(1)); } @@ -1728,9 +1888,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) int k=line.gettoken_enum(1,"show\0hide\0"); if (k == -1) PRINTHELP(); if (k) - build_header.common.flags|=CH_FLAGS_DIR_NO_SHOW; + build_header.flags|=CH_FLAGS_DIR_NO_SHOW; else - build_header.common.flags&=~CH_FLAGS_DIR_NO_SHOW; + build_header.flags&=~CH_FLAGS_DIR_NO_SHOW; SCRIPT_MSG("DirShow: %s\n",k?"hide":"show"); } return make_sure_not_in_secorfunc(line.gettoken_str(0)); @@ -1739,9 +1899,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) int k=line.gettoken_enum(1,"true\0false\0"); if (k == -1) PRINTHELP(); if (k) - build_header.common.flags|=CH_FLAGS_NO_ROOT_DIR; + build_header.flags|=CH_FLAGS_NO_ROOT_DIR; else - build_header.common.flags&=~CH_FLAGS_NO_ROOT_DIR; + build_header.flags&=~CH_FLAGS_NO_ROOT_DIR; SCRIPT_MSG("AllowRootDirInstall: %s\n",k?"false":"true"); } return make_sure_not_in_secorfunc(line.gettoken_str(0)); @@ -1753,12 +1913,12 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) if (line.getnumtokens()==1) { SCRIPT_MSG("BGGradient: default colors\n"); - build_header.common.bg_color1=0; - build_header.common.bg_color2=RGB(0,0,255); + build_header.bg_color1=0; + build_header.bg_color2=RGB(0,0,255); } else if (!stricmp(line.gettoken_str(1),"off")) { - build_header.common.bg_color1=build_header.common.bg_color2=-1; + build_header.bg_color1=build_header.bg_color2=-1; SCRIPT_MSG("BGGradient: off\n"); if (line.getnumtokens()>2) PRINTHELP() } @@ -1767,19 +1927,19 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) char *p = line.gettoken_str(1); int v1,v2,v3=-1; v1=strtoul(p,&p,16); - build_header.common.bg_color1=((v1&0xff)<<16)|(v1&0xff00)|((v1&0xff0000)>>16); + build_header.bg_color1=((v1&0xff)<<16)|(v1&0xff00)|((v1&0xff0000)>>16); p=line.gettoken_str(2); v2=strtoul(p,&p,16); - build_header.common.bg_color2=((v2&0xff)<<16)|(v2&0xff00)|((v2&0xff0000)>>16); + build_header.bg_color2=((v2&0xff)<<16)|(v2&0xff00)|((v2&0xff0000)>>16); p=line.gettoken_str(3); if (*p) { - if (!stricmp(p,"notext")) build_header.common.bg_textcolor=-1; + if (!stricmp(p,"notext")) build_header.bg_textcolor=-1; else { v3=strtoul(p,&p,16); - build_header.common.bg_textcolor=((v3&0xff)<<16)|(v3&0xff00)|((v3&0xff0000)>>16); + build_header.bg_textcolor=((v3&0xff)<<16)|(v3&0xff00)|((v3&0xff0000)>>16); } } @@ -1787,40 +1947,40 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) } #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT - build_uninst.common.bg_color1=build_header.common.bg_color1; - build_uninst.common.bg_color2=build_header.common.bg_color2; - build_uninst.common.bg_textcolor=build_header.common.bg_textcolor; + build_uninst.bg_color1=build_header.bg_color1; + build_uninst.bg_color2=build_header.bg_color2; + build_uninst.bg_textcolor=build_header.bg_textcolor; #endif//NSIS_CONFIG_UNINSTALL_SUPPORT #endif//NSIS_SUPPORT_BGBG return make_sure_not_in_secorfunc(line.gettoken_str(0)); +#ifdef NSIS_CONFIG_VISIBLE_SUPPORT case TOK_INSTCOLORS: + { + char *p = line.gettoken_str(1); + if (p[0]=='/') { - char *p = line.gettoken_str(1); - if (p[0]=='/') - { - if (stricmp(p,"/windows") || line.getnumtokens()!=2) PRINTHELP() - build_header.common.lb_fg=build_header.common.lb_bg=-1; - SCRIPT_MSG("InstallColors: windows default colors\n"); - } - else - { - int v1,v2; - if (line.getnumtokens()!=3) PRINTHELP() - v1=strtoul(p,&p,16); - build_header.common.lb_fg=((v1&0xff)<<16)|(v1&0xff00)|((v1&0xff0000)>>16); - p=line.gettoken_str(2); - v2=strtoul(p,&p,16); - build_header.common.lb_bg=((v2&0xff)<<16)|(v2&0xff00)|((v2&0xff0000)>>16); - SCRIPT_MSG("InstallColors: fg=%06X bg=%06X\n",v1,v2); - } + if (stricmp(p,"/windows") || line.getnumtokens()!=2) PRINTHELP() + build_header.lb_fg=build_header.lb_bg=-1; + SCRIPT_MSG("InstallColors: windows default colors\n"); + } + else + { + int v1,v2; + if (line.getnumtokens()!=3) PRINTHELP() + v1=strtoul(p,&p,16); + build_header.lb_fg=((v1&0xff)<<16)|(v1&0xff00)|((v1&0xff0000)>>16); + p=line.gettoken_str(2); + v2=strtoul(p,&p,16); + build_header.lb_bg=((v2&0xff)<<16)|(v2&0xff00)|((v2&0xff0000)>>16); + SCRIPT_MSG("InstallColors: fg=%06X bg=%06X\n",v1,v2); + } #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT - build_uninst.common.lb_fg=build_header.common.lb_fg; - build_uninst.common.lb_bg=build_header.common.lb_bg; + build_uninst.lb_fg=build_header.lb_fg; + build_uninst.lb_bg=build_header.lb_bg; #endif - } + } return make_sure_not_in_secorfunc(line.gettoken_str(0)); - // Added by Amir Szekely 7th July 2002 case TOK_XPSTYLE: try { int k=line.gettoken_enum(1,"on\0off\0"); @@ -1835,21 +1995,13 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return PS_ERROR; } return make_sure_not_in_secorfunc(line.gettoken_str(0)); - // Added by Amir Szekely 28th July 2002 -#ifdef NSIS_CONFIG_VISIBLE_SUPPORT case TOK_CHANGEUI: try { DWORD dwSize; - int a = 1; - bool rtl = false; - if (!stricmp(line.gettoken_str(a), "/RTL")) { - rtl = true; - a++; - } - int k=line.gettoken_enum(a++, "all\0IDD_LICENSE\0IDD_DIR\0IDD_SELCOM\0IDD_INST\0IDD_INSTFILES\0IDD_UNINST\0IDD_VERIFY\0"); + int k=line.gettoken_enum(1, "all\0IDD_LICENSE\0IDD_DIR\0IDD_SELCOM\0IDD_INST\0IDD_INSTFILES\0IDD_UNINST\0IDD_VERIFY\0IDD_LICENSE_FSRB\0IDD_LICENSE_FSCB\0"); if (k<0) PRINTHELP(); - HINSTANCE hUIFile = LoadLibraryEx(line.gettoken_str(a), 0, LOAD_LIBRARY_AS_DATAFILE); + HINSTANCE hUIFile = LoadLibraryEx(line.gettoken_str(2), 0, LOAD_LIBRARY_AS_DATAFILE); if (!hUIFile) { ERROR_MSG("Error: Can't find \"%s\" in \"%s\"!\n", line.gettoken_str(1), line.gettoken_str(2)); return PS_ERROR; @@ -1859,7 +2011,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) // Search for required items #define SEARCH(x) if (!UIDlg.GetItem(x)) {ERROR_MSG("Error: Can't find %s (%u) in the custom UI!\n", #x, x);return PS_ERROR;} - #define SAVE(x) if (rtl) {UIDlg.ConvertToRTL(); dlg = UIDlg.Save(dwSize);} else dwSize = UIDlg.GetSize(); res_editor->UpdateResource(RT_DIALOG, x, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), dlg, dwSize); + #define SAVE(x) dwSize = UIDlg.GetSize(); res_editor->UpdateResource(RT_DIALOG, x, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), dlg, dwSize); BYTE* dlg = 0; @@ -1948,65 +2100,38 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) res_editor->UpdateResource(RT_DIALOG, IDD_VERIFY, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), dlg, UIDlg.GetSize()); } + if (k == 0 || k == 8) { + dlg = get_dlg(hUIFile, IDD_LICENSE_FSRB, line.gettoken_str(2)); + if (!dlg) return PS_ERROR; + CDialogTemplate UIDlg(dlg,uDefCodePage); + SEARCH(IDC_EDIT1); + SEARCH(IDC_LICENSEAGREE); + SEARCH(IDC_LICENSEDISAGREE); + SAVE(IDD_LICENSE_FSRB); + } + + if (k == 0 || k == 9) { + dlg = get_dlg(hUIFile, IDD_LICENSE_FSCB, line.gettoken_str(2)); + if (!dlg) return PS_ERROR; + CDialogTemplate UIDlg(dlg,uDefCodePage); + SEARCH(IDC_EDIT1); + SEARCH(IDC_LICENSEAGREE); + SAVE(IDD_LICENSE_FSCB); + } + if (!FreeLibrary(hUIFile)) { ERROR_MSG("can't free library!\n"); } - SCRIPT_MSG("ChangeUI: %s%s %s%s\n", rtl?"(RTL) ":"", line.gettoken_str(a-1), line.gettoken_str(a), branding_image_found?" (branding image holder found)":""); + SCRIPT_MSG("ChangeUI: %s %s%s\n", line.gettoken_str(1), line.gettoken_str(2), branding_image_found?" (branding image holder found)":""); } catch (exception& err) { ERROR_MSG("Error while changing UI: %s\n", err.what()); return PS_ERROR; } return make_sure_not_in_secorfunc(line.gettoken_str(0)); - /* - Useless - - case TOK_USEOUTERUIITEM: - { - int k = line.gettoken_enum(1,"introtext\0spaceavail\0spacereq\0dirsubtext\0comsubtext1\0comsubtext2\0uninstsubtext\0"); - if (k < 0) PRINTHELP(); - int id = line.gettoken_int(2); - if (!id) { - ERROR_MSG("Error: Item id can't be zero!\n"); - return PS_ERROR; - } - switch (k) { - case 0: - build_header.common.intro_text_id=build_uninst.common.intro_text_id=id; - break; - case 1: - build_header.space_avail_id=id; - break; - case 2: - build_header.space_req_id=id; - break; - case 3: - build_header.dir_subtext_id=id; - break; - case 4: - build_header.com_subtext1_id=id; - break; - case 5: - build_header.com_subtext2_id=id; - break; - case 6: - build_uninst.uninst_subtext_id=id; - break; - } - SCRIPT_MSG("%s: %s now uses outer UI item %d\n",line.gettoken_str(0),line.gettoken_str(1),id); - } - return make_sure_not_in_secorfunc(line.gettoken_str(0));*/ -#else - case TOK_CHANGEUI: - //case TOK_USEOUTERUIITEM: - ERROR_MSG("Error: %s specified, NSIS_CONFIG_VISIBLE_SUPPORT not defined.\n",line.gettoken_str(0)); - return PS_ERROR; -#endif// NSIS_CONFIG_VISIBLE_SUPPORT - // Added by Amir Szekely 21st July 2002 -#ifdef NSIS_CONFIG_VISIBLE_SUPPORT case TOK_ADDBRANDINGIMAGE: - try { + try { int k=line.gettoken_enum(1,"top\0left\0bottom\0right\0"); int wh=line.gettoken_int(2); if (k == -1) PRINTHELP(); @@ -2078,11 +2203,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return PS_ERROR; } return make_sure_not_in_secorfunc(line.gettoken_str(0)); -#else - ERROR_MSG("Error: %s specified, NSIS_CONFIG_VISIBLE_SUPPORT not defined.\n",line.gettoken_str(0)); - return PS_ERROR; -#endif// NSIS_CONFIG_VISIBLE_SUPPORT -#ifdef NSIS_CONFIG_VISIBLE_SUPPORT case TOK_SETFONT: SCRIPT_MSG("SetFont: \"%s\" %s\n", line.gettoken_str(1), line.gettoken_str(2)); try { @@ -2123,10 +2243,14 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) } return make_sure_not_in_secorfunc(line.gettoken_str(0)); #else + case TOK_INSTCOLORS: + case TOK_XPSTYLE: + case TOK_CHANGEUI: + case TOK_ADDBRANDINGIMAGE: + case TOK_SETFONT: ERROR_MSG("Error: %s specified, NSIS_CONFIG_VISIBLE_SUPPORT not defined.\n",line.gettoken_str(0)); - return PS_ERROR; + return PS_ERROR; #endif// NSIS_CONFIG_VISIBLE_SUPPORT - // Added by Amir Szekely 31st July 2002 // Ability to change compression methods from within the script case TOK_SETCOMPRESSOR: #ifdef NSIS_CONFIG_COMPRESSION_SUPPORT @@ -2190,44 +2314,26 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) case TOK_LOADNLF: { SCRIPT_MSG("LoadLanguageFile: %s\n", line.gettoken_str(1)); - try { - NLF *newNLF = new NLF(line.gettoken_str(1)); - unsigned int i; - for (i = 0; i < build_nlfs.size(); i++) - { - if (build_nlfs[i]->m_wLangId == newNLF->m_wLangId) - { - ERROR_MSG("Error: Can't add same language twice!\n"); - return PS_ERROR; - } - } - if (!build_nlfs.size()) - { - uDefCodePage = newNLF->m_uCodePage; - } - build_nlfs.push_back(newNLF); - StringTable * Table = GetTable(newNLF->m_wLangId); - for (i = 0; i < build_nlfs.size(); i++) { - if (build_nlfs[i]->m_wLangId == Table->lang_id) { - Table->nlf = build_nlfs[i]; - break; - } - } + LanguageTable *table = LoadLangFile(line.gettoken_str(1)); - last_used_lang = newNLF->m_wLangId; - // define LANG_LangName as "####" (lang id) - // for example ${LANG_ENGLISH} = 1033 - char lang_id[16]; - char lang_name[128]; - wsprintf(lang_name, "LANG_%s", newNLF->m_szName); - wsprintf(lang_id, "%u", newNLF->m_wLangId); - definedlist.add(lang_name,lang_id); - } - catch (exception &err) { - ERROR_MSG("Error while loading language file: %s\n", err.what()); + if (!table) return PS_ERROR; + + if (!defcodepage_set) + { + uDefCodePage = table->nlf.m_uCodePage; + defcodepage_set = true; } + + last_used_lang = table->lang_id; + // define LANG_LangName as "####" (lang id) + // for example ${LANG_ENGLISH} = 1033 + char lang_id[16]; + char lang_name[128]; + wsprintf(lang_name, "LANG_%s", table->nlf.m_szName); + wsprintf(lang_id, "%u", table->lang_id); + definedlist.add(lang_name, lang_id); } return make_sure_not_in_secorfunc(line.gettoken_str(0)); @@ -2366,8 +2472,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) fclose(incfp); if (r != PS_EOF && r != PS_OK) { - if (r == PS_ENDIF) ERROR_MSG("!endif: stray !endif\n"); - if (IS_PS_ELSE(r)) ERROR_MSG("!else: stray !else\n"); ERROR_MSG("!include: error in script: \"%s\" on line %d\n",f,errlinecnt); if (malloced) free(f); return PS_ERROR; @@ -2387,18 +2491,58 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ERROR_MSG("!error: %s\n",line.gettoken_str(1)); return PS_ERROR; case TOK_P_WARNING: - warning("!warning: %s (%s:%d)\n",line.gettoken_str(1),curfilename,linecnt); + warning_fl("!warning: %s\n",line.gettoken_str(1)); return PS_OK; - // Added by Amir Szekely 23rd July 2002 case TOK_P_ECHO: SCRIPT_MSG("%s (%s:%d)\n", line.gettoken_str(1),curfilename,linecnt); return PS_OK; - // Added by Amir Szekely 23rd July 2002 case TOK_P_VERBOSE: { extern int g_display_errors; - int v=line.gettoken_int(1); + int k=line.gettoken_enum(1,"push\0pop\0"); + int v; + if (k < 0) + // just set + v=line.gettoken_int(1); + else + { + if (k) + { + // pop + int l=verbose_stack.getlen(); + if (l) + { + v=((int*)verbose_stack.get())[(l/sizeof(int))-1]; + verbose_stack.resize(l-sizeof(int)); + } + else + return PS_OK; + } + else + { + // push + v=0; + if (display_errors) + { + v++; + if (display_warnings) + { + v++; + if (display_info) + { + v++; + if (display_script) + { + v++; + } + } + } + } + verbose_stack.add(&v,sizeof(int)); + return PS_OK; + } + } display_script=v>3; display_info=v>2; display_warnings=v>1; @@ -2413,14 +2557,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT case TOK_UNINSTCAPTION: { - int a = 1; - WORD lang = 0; - if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); - if (line.getnumtokens()==a) PRINTHELP(); - if (IsSet(ucommon.caption,lang)) - warning("%s: specified multiple times, wasting space (%s:%d)",line.gettoken_str(0),curfilename,linecnt); - SetString(line.gettoken_str(a),NLF_UCAPTION,1,lang); - SCRIPT_MSG("UninstCaption: \"%s\"\n",line.gettoken_str(a)); + if (SetInnerString(NLF_UCAPTION,line.gettoken_str(1)) == PS_WARNING) + warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0)); + SCRIPT_MSG("UninstCaption: \"%s\"\n",line.gettoken_str(1)); } return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_UNINSTICON: @@ -2440,28 +2579,29 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_UNINSTTEXT: { - int a = 1; - WORD lang = 0; - if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); - if (line.getnumtokens()==a) PRINTHELP(); - if (IsSet(uninstall.uninstalltext,lang)) - warning("%s: specified multiple times, wasting space (%s:%d)",line.gettoken_str(0),curfilename,linecnt); - SetString(line.gettoken_str(a),SLANG_UNINST_TEXT,0,lang); - if (line.getnumtokens()>a+1) SetString(line.gettoken_str(a+1),NLF_UNINST_SUBTEXT,0,lang); - SCRIPT_MSG("UninstallText: \"%s\" \"%s\"\n",line.gettoken_str(a),line.gettoken_str(a+1)); + if (!cur_page) { + if (SetInnerString(NLF_UNINST_TEXT, line.gettoken_str(1)) == PS_WARNING) + warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0)); + SetInnerString(NLF_UNINST_SUBTEXT, line.gettoken_str(2)); + } + else { + if (cur_page_type != PAGE_UNINSTCONFIRM) { + ERROR_MSG("Error: UninstallText can only be used inside PageEx uninstConfirm.\n"); + return PS_ERROR; + } + cur_page->parms[0] = add_string(line.gettoken_str(1)); + cur_page->parms[1] = add_string(line.gettoken_str(2)); + } + SCRIPT_MSG("UninstallText: \"%s\" \"%s\"\n",line.gettoken_str(1),line.gettoken_str(2)); } - return make_sure_not_in_secorfunc(line.gettoken_str(0)); + return make_sure_not_in_secorfunc(line.gettoken_str(0), 1); case TOK_UNINSTSUBCAPTION: { - int a = 1; - WORD lang = 0; - if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); - if (line.getnumtokens()!=a+2) PRINTHELP(); int s; - int w=line.gettoken_int(a,&s); + int w=line.gettoken_int(1,&s); if (!s || w < 0 || w > 2) PRINTHELP() - SetString(line.gettoken_str(a+1),NLF_USUBCAPTION_CONFIRM+w,1,lang); - SCRIPT_MSG("UninstSubCaption: page:%d, text=%s\n",w,line.gettoken_str(a+1)); + SetInnerString(NLF_USUBCAPTION_CONFIRM+w,line.gettoken_str(2)); + SCRIPT_MSG("UninstSubCaption: page:%d, text=%s\n",w,line.gettoken_str(2)); } return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_WRITEUNINSTALLER: @@ -2472,11 +2612,14 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) } uninstaller_writes_used++; ent.which=EW_WRITEUNINSTALLER; - ent.offsets[0]=add_string_main(line.gettoken_str(1)); + ent.offsets[0]=add_string(line.gettoken_str(1)); ent.offsets[1]=0; // uninstall section 0 ent.offsets[2]=0; if (!ent.offsets[0]) PRINTHELP() SCRIPT_MSG("WriteUninstaller: \"%s\"\n",line.gettoken_str(1)); + + DefineInnerLangString(NLF_ERR_CREATING); + DefineInnerLangString(NLF_CREATED_UNINST); return add_entry(&ent); #else//!NSIS_CONFIG_UNINSTALL_SUPPORT case TOK_WRITEUNINSTALLER: @@ -2514,15 +2657,18 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) int ret; - if (line.gettoken_str(a)[0]=='-') ret=add_section("",line.gettoken_str(a+1)); + if (line.gettoken_str(a)[0]=='-') + { + if (!strnicmp(line.gettoken_str(a)+1,"un.",3)) + ret=add_section("un.",line.gettoken_str(a+1)); + else + ret=add_section("",line.gettoken_str(a+1)); + } else ret=add_section(line.gettoken_str(a),line.gettoken_str(a+1)); if (ret != PS_OK) return ret; if (unselected) - { - use_first_insttype = false; build_cursection->flags &= ~SF_SELECTED; - } return PS_OK; } @@ -2577,18 +2723,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) wsprintf(buf,"-%s",line.gettoken_str(a)); if (which_token == TOK_SUBSECTION && !line.gettoken_str(a)[0]) PRINTHELP() - if (which_token == TOK_SUBSECTIONEND) - { - subsection_open_cnt--; - if (subsection_open_cnt<0) - { - ERROR_MSG("SubSectionEnd: no SubSections are open\n"); - return PS_ERROR; - } - } - else - subsection_open_cnt++; - SCRIPT_MSG("%s %s",line.gettoken_str(0),line.gettoken_str(a)); if (line.gettoken_str(a+1)[0]) SCRIPT_MSG(" ->(%s)",line.gettoken_str(a+1)); SCRIPT_MSG("\n"); @@ -2646,7 +2780,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) if (build_compress==-1) PRINTHELP() if (build_compress==0 && build_compress_whole) { - warning("'SetCompress off' encountered, and in whole compression mode. Effectively ignored. (%s:%d)",curfilename,linecnt); + warning_fl("'SetCompress off' encountered, and in whole compression mode. Effectively ignored."); } SCRIPT_MSG("SetCompress: %s\n",line.gettoken_str(1)); return PS_OK; @@ -2666,26 +2800,19 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return PS_OK; case TOK_SUBCAPTION: { - int a = 1; - WORD lang = 0; - if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); - if (line.getnumtokens()!=a+2) PRINTHELP(); int s; - int w=line.gettoken_int(a,&s); + int w=line.gettoken_int(1,&s); if (!s || w < 0 || w > 4) PRINTHELP() - SetString(line.gettoken_str(a+1),NLF_SUBCAPTION_LICENSE+w,1,lang); - SCRIPT_MSG("SubCaption: page:%d, text=%s\n",w,line.gettoken_str(a+1)); + SetInnerString(NLF_SUBCAPTION_LICENSE+w,line.gettoken_str(2)); + SCRIPT_MSG("SubCaption: page:%d, text=%s\n",w,line.gettoken_str(2)); } return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_FILEERRORTEXT: #ifdef NSIS_SUPPORT_FILE { - int a = 1; - WORD lang = 0; - if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); - SetString(line.gettoken_str(a),NLF_FILE_ERROR,1,lang); - SetString(line.gettoken_str(a+1),NLF_FILE_ERROR_NOIGNORE,1,lang); - SCRIPT_MSG("FileErrorText: \"%s\" \"%s\"\n",line.gettoken_str(a),line.gettoken_str(a+1)); + SetInnerString(NLF_FILE_ERROR,line.gettoken_str(1)); + SetInnerString(NLF_FILE_ERROR_NOIGNORE,line.gettoken_str(2)); + SCRIPT_MSG("FileErrorText: \"%s\" \"%s\"\n",line.gettoken_str(1),line.gettoken_str(2)); } return make_sure_not_in_secorfunc(line.gettoken_str(0)); #else @@ -2695,11 +2822,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) case TOK_BRANDINGTEXT: { int a = 1; - WORD lang = 0; int trim = 0; while (line.gettoken_str(a)[0] == '/') { - if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); - else if (!strnicmp(line.gettoken_str(a),"/TRIM",5)) { + if (!strnicmp(line.gettoken_str(a),"/TRIM",5)) { if (!stricmp(line.gettoken_str(a)+5,"LEFT")) trim = 1; else if (!stricmp(line.gettoken_str(a)+5,"RIGHT")) trim = 2; else if (!stricmp(line.gettoken_str(a)+5,"CENTER")) trim = 3; @@ -2709,7 +2834,8 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) else break; } if (line.getnumtokens()!=a+1 && !trim) PRINTHELP(); - if (line.getnumtokens()==a+1) SetString(line.gettoken_str(a),NLF_BRANDING,0,lang); + if (line.getnumtokens()==a+1) + SetInnerString(NLF_BRANDING,line.gettoken_str(a)); if (trim) try { init_res_editor(); @@ -2746,74 +2872,69 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_MISCBUTTONTEXT: { - int a = 1; - WORD lang = 0; - if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); - if (line.getnumtokens()==a) PRINTHELP(); - SetString(line.gettoken_str(a),NLF_BTN_BACK,0,lang); - SetString(line.gettoken_str(a+1),NLF_BTN_NEXT,0,lang); - SetString(line.gettoken_str(a+2),NLF_BTN_CANCEL,0,lang); - SetString(line.gettoken_str(a+3),NLF_BTN_CLOSE,0,lang); - SCRIPT_MSG("MiscButtonText: back=\"%s\" next=\"%s\" cancel=\"%s\" close=\"%s\"\n",line.gettoken_str(a),line.gettoken_str(a+1),line.gettoken_str(a+2),line.gettoken_str(a+3)); + SetInnerString(NLF_BTN_BACK,line.gettoken_str(1)); + SetInnerString(NLF_BTN_NEXT,line.gettoken_str(2)); + SetInnerString(NLF_BTN_CANCEL,line.gettoken_str(3)); + SetInnerString(NLF_BTN_CLOSE,line.gettoken_str(4)); + SCRIPT_MSG("MiscButtonText: back=\"%s\" next=\"%s\" cancel=\"%s\" close=\"%s\"\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4)); } return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_SPACETEXTS: { - int a = 1; - WORD lang = 0; - if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); - if (line.getnumtokens()==a) PRINTHELP(); - - if (!lstrcmpi(line.gettoken_str(a), "none")) { + if (!lstrcmpi(line.gettoken_str(1), "none")) { no_space_texts=true; SCRIPT_MSG("SpaceTexts: none\n"); } else { - SetString(line.gettoken_str(a),NLF_SPACE_REQ,0); - SetString(line.gettoken_str(a+1),NLF_SPACE_AVAIL,0); - SCRIPT_MSG("SpaceTexts: required=\"%s\" available=\"%s\"\n",line.gettoken_str(a),line.gettoken_str(a+1)); + SetInnerString(NLF_SPACE_REQ,line.gettoken_str(1)); + SetInnerString(NLF_SPACE_AVAIL,line.gettoken_str(2)); + SCRIPT_MSG("SpaceTexts: required=\"%s\" available=\"%s\"\n",line.gettoken_str(1),line.gettoken_str(2)); } } return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_INSTBUTTONTEXT: { - int a = 1; - WORD lang = 0; - if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); - if (line.getnumtokens()==a) PRINTHELP(); - SetString(line.gettoken_str(a),NLF_BTN_INSTALL,0,lang); - SCRIPT_MSG("InstallButtonText: \"%s\"\n",line.gettoken_str(a)); + SetInnerString(NLF_BTN_INSTALL,line.gettoken_str(1)); + SCRIPT_MSG("InstallButtonText: \"%s\"\n",line.gettoken_str(1)); } return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_DETAILSBUTTONTEXT: { - int a = 1; - WORD lang = 0; - if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); - if (line.getnumtokens()==a) PRINTHELP(); - SetString(line.gettoken_str(a),NLF_BTN_DETAILS,0,lang); - SCRIPT_MSG("DetailsButtonText: \"%s\"\n",line.gettoken_str(a)); + if (!cur_page) { + if (SetInnerString(NLF_BTN_DETAILS,line.gettoken_str(1)) == PS_WARNING) + warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0)); + } + else { + if (cur_page_type != PAGE_INSTFILES) { + ERROR_MSG("Error: DetailsButtonText can only be used inside PageEx instfiles.\n"); + return PS_ERROR; + } + cur_page->parms[1] = add_string(line.gettoken_str(1)); + } + SCRIPT_MSG("DetailsButtonText: \"%s\"\n",line.gettoken_str(1)); } - return make_sure_not_in_secorfunc(line.gettoken_str(0)); + return make_sure_not_in_secorfunc(line.gettoken_str(0),1); case TOK_COMPLETEDTEXT: { - int a = 1; - WORD lang = 0; - if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); - if (line.getnumtokens()==a) PRINTHELP(); - SetString(line.gettoken_str(a),NLF_COMPLETED,0,lang); - SCRIPT_MSG("CompletedText: \"%s\"\n",line.gettoken_str(a)); + if (!cur_page) { + if (SetInnerString(NLF_COMPLETED,line.gettoken_str(1)) == PS_WARNING) + warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0)); + } + else { + if (cur_page_type != PAGE_INSTFILES) { + ERROR_MSG("Error: CompletedText can only be used inside PageEx instfiles.\n"); + return PS_ERROR; + } + cur_page->parms[2] = add_string(line.gettoken_str(1)); + } + SCRIPT_MSG("CompletedText: \"%s\"\n",line.gettoken_str(1)); } return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_UNINSTBUTTONTEXT: #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT { - int a = 1; - WORD lang = 0; - if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); - if (line.getnumtokens()==a) PRINTHELP(); - SetString(line.gettoken_str(a),NLF_BTN_UNINSTALL,0,lang); - SCRIPT_MSG("UninstButtonText: \"%s\"\n",line.gettoken_str(a)); + SetInnerString(NLF_BTN_UNINSTALL,line.gettoken_str(1)); + SCRIPT_MSG("UninstButtonText: \"%s\"\n",line.gettoken_str(1)); } return make_sure_not_in_secorfunc(line.gettoken_str(0)); #else @@ -2882,21 +3003,12 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return add_entry(&ent); case TOK_SETOUTPATH: { - char *p=line.gettoken_str(1); - if (*p == '-') cur_out_path[0]=0; - else - { - if (p[0] == '\\' && p[1] != '\\') p++; - strncpy(cur_out_path,p,1024-1); - cur_out_path[1024-1]=0; - if (*CharPrev(cur_out_path,cur_out_path+strlen(cur_out_path))=='\\') - *CharPrev(cur_out_path,cur_out_path+strlen(cur_out_path))=0; // remove trailing slash - } - if (!cur_out_path[0]) strcpy(cur_out_path,"$INSTDIR"); - SCRIPT_MSG("SetOutPath: \"%s\"\n",cur_out_path); + SCRIPT_MSG("SetOutPath: \"%s\"\n",line.gettoken_str(1)); ent.which=EW_CREATEDIR; - ent.offsets[0]=add_string(cur_out_path); + ent.offsets[0]=add_string(line.gettoken_str(1)); ent.offsets[1]=1; + + DefineInnerLangString(NLF_OUTPUT_DIR); } return add_entry(&ent); case TOK_CREATEDIR: @@ -2915,6 +3027,8 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) SCRIPT_MSG("CreateDirectory: \"%s\"\n",out_path); ent.which=EW_CREATEDIR; ent.offsets[0]=add_string(out_path); + + DefineInnerLangString(NLF_CREATE_DIR); } return add_entry(&ent); case TOK_EXEC: @@ -2930,6 +3044,8 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) if (line.gettoken_str(2)[0] && ent.offsets[2]<0) PRINTHELP() } SCRIPT_MSG("%s: \"%s\" (->%s)\n",ent.offsets[1]?"ExecWait":"Exec",line.gettoken_str(1),line.gettoken_str(2)); + + DefineInnerLangString(NLF_EXEC); return add_entry(&ent); #else//!NSIS_SUPPORT_EXECUTE ERROR_MSG("Error: %s specified, NSIS_SUPPORT_EXECUTE not defined.\n", line.gettoken_str(0)); @@ -2951,6 +3067,8 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) } SCRIPT_MSG("ExecShell: %s: \"%s\" \"%s\" %s\n",line.gettoken_str(1),line.gettoken_str(2), line.gettoken_str(3),line.gettoken_str(4)); + + DefineInnerLangString(NLF_EXEC_SHELL); return add_entry(&ent); #else//!NSIS_SUPPORT_SHELLEXECUTE ERROR_MSG("Error: %s specified, NSIS_SUPPORT_SHELLEXECUTE not defined.\n", line.gettoken_str(0)); @@ -2968,8 +3086,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) if (which_token == TOK_UNREGDLL) { ent.offsets[1]=add_string("DllUnregisterServer"); - ent.offsets[2]=LANG_UNREGISTERING; - unregister_used=true; + ent.offsets[2]=DefineInnerLangString(NLF_UNREGISTERING); } else if (which_token == TOK_CALLINSTDLL) { @@ -2987,11 +3104,15 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) { ent.offsets[1] = add_string(line.gettoken_str(2)); if (!ent.offsets[1]) ent.offsets[1]=add_string("DllRegisterServer"); - ent.offsets[2]=LANG_REGISTERING; - register_used=true; + ent.offsets[2]=DefineInnerLangString(NLF_REGISTERING); } SCRIPT_MSG("%s: \"%s\" %s\n",line.gettoken_str(0),line.gettoken_str(1), line.gettoken_str(ent.offsets[3]?3:2)); + + DefineInnerLangString(NLF_SYMBOL_NOT_FOUND); + DefineInnerLangString(NLF_COULD_NOT_LOAD); + DefineInnerLangString(NLF_NO_OLE); + DefineInnerLangString(NLF_ERR_REG_DLL); return add_entry(&ent); #endif//NSIS_SUPPORT_ACTIVEXREG case TOK_RENAME: @@ -3016,6 +3137,11 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ent.offsets[0]=add_string(line.gettoken_str(a)); ent.offsets[1]=add_string(line.gettoken_str(a+1)); SCRIPT_MSG("Rename: %s%s->%s\n",ent.offsets[2]?"/REBOOTOK ":"",line.gettoken_str(a),line.gettoken_str(a+1)); + + DefineInnerLangString(NLF_RENAME); +#ifdef NSIS_SUPPORT_MOVEONREBOOT + DefineInnerLangString(NLF_RENAME_ON_REBOOT); +#endif } return add_entry(&ent); #else//!NSIS_SUPPORT_RENAME @@ -3148,7 +3274,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) c=VK_F1-1+atoi(s+1); if (atoi(s+1) < 1 || atoi(s+1) > 24) { - warning("CreateShortCut: F-key \"%s\" out of range (%s:%d)",s,curfilename,linecnt); + warning_fl("CreateShortCut: F-key \"%s\" out of range",s); } } else if (s[0] >= 'a' && s[0] <= 'z' && !s[1]) @@ -3158,7 +3284,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) else { c=s[0]; - warning("CreateShortCut: unrecognized hotkey \"%s\" (%s:%d)",s,curfilename,linecnt); + warning_fl("CreateShortCut: unrecognized hotkey \"%s\"",s); } ent.offsets[4] |= (c) << 16; } @@ -3166,6 +3292,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) SCRIPT_MSG("CreateShortCut: \"%s\"->\"%s\" %s icon:%s,%d, showmode=0x%X, hotkey=0x%X, comment=%s\n", line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3), line.gettoken_str(4),ent.offsets[4]&0xff,(ent.offsets[4]>>8)&0xff,ent.offsets[4]>>16,line.gettoken_str(8)); + + DefineInnerLangString(NLF_CREATE_SHORTCUT); + DefineInnerLangString(NLF_ERR_CREATING_SHORTCUT); return add_entry(&ent); #else//!NSIS_SUPPORT_CREATESHORTCUT ERROR_MSG("Error: %s specified, NSIS_SUPPORT_CREATESHORTCUT not defined.\n", line.gettoken_str(0)); @@ -3249,24 +3378,73 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ent.offsets[2]=add_string(line.gettoken_str(3)); SCRIPT_MSG("GetDlgItem: output=%s dialog=%s item=%s\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3)); return add_entry(&ent); - case TOK_GETWINTEXT: - ent.which=EW_GETWINTEXT; - ent.offsets[0]=GetUserVarIndex(line,1); - if (ent.offsets[0]<0) PRINTHELP(); - ent.offsets[1]=add_string(line.gettoken_str(2)); - SCRIPT_MSG("GetWindowText: output=%s hwnd=%s\n",line.gettoken_str(1),line.gettoken_str(2)); - return add_entry(&ent); - case TOK_SETBKCOLOR: - ent.which=EW_SETBKCOLOR; - if (!stricmp(line.gettoken_str(2),"transparent")) - ent.offsets[0]=BS_NULL; - else { - ent.offsets[0]=BS_SOLID; - ent.offsets[1]=line.gettoken_int(2); + case TOK_SETCTLCOLORS: + { + ctlcolors c={0, }; + + ent.which=EW_SETCTLCOLORS; + ent.offsets[0]=add_string(line.gettoken_str(1)); + + if (!strcmpi(line.gettoken_str(2),"branding")) { + if (line.getnumtokens() == 4) { + ERROR_MSG("Error: SetCtlColors expected 2 parameters, got 3\n"); + return PS_ERROR; + } + + c.flags|=CC_BK|CC_BK_SYS|CC_BKB; + c.bk.lbStyle=BS_NULL; + c.bk.lbColor=COLOR_BTNFACE; + c.flags|=CC_TEXT|CC_TEXT_SYS; + c.text=COLOR_BTNFACE; + c.bkmode=OPAQUE; } - ent.offsets[2]=0; - ent.offsets[3]=add_string(line.gettoken_str(1)); - SCRIPT_MSG("SetBkColor: hwnd=%s color=%s\n",line.gettoken_str(1),line.gettoken_str(2)); + else { + char *p; + + if (line.getnumtokens() == 3) { + ERROR_MSG("Error: SetCtlColors expected 3 parameters, got 2\n"); + return PS_ERROR; + } + + if (!strcmpi(line.gettoken_str(3),"transparent")) { + c.flags|=CC_BKB; + c.bk.lbStyle=BS_NULL; + c.bkmode=TRANSPARENT; + } + else { + p=line.gettoken_str(3); + if (*p) { + int v=strtoul(p,&p,16); + c.bk.lbColor=((v&0xff)<<16)|(v&0xff00)|((v&0xff0000)>>16); + c.flags|=CC_BK|CC_BKB; + } + + c.bk.lbStyle=BS_SOLID; + c.bkmode=OPAQUE; + } + + p=line.gettoken_str(2); + if (*p) { + int v=strtoul(p,&p,16); + c.text=((v&0xff)<<16)|(v&0xff00)|((v&0xff0000)>>16); + c.flags|=CC_TEXT; + } + } + + int i; + int l=cur_ctlcolors->getlen()/sizeof(ctlcolors); + for (i=0; iget()+i,&c,sizeof(ctlcolors))) { + ent.offsets[1]=i*sizeof(ctlcolors); + break; + } + } + if (i>=l) { + ent.offsets[1]=cur_ctlcolors->add(&c,sizeof(ctlcolors)); + } + + SCRIPT_MSG("SetCtlColors: hwnd=%s text=%s background=%s\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3)); + } return add_entry(&ent); case TOK_CREATEFONT: ent.which=EW_CREATEFONT; @@ -3354,7 +3532,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return add_entry(&ent); #else//NSIS_CONFIG_ENHANCEDUI_SUPPORT case TOK_GETDLGITEM: - case TOK_SETBKCOLOR: + case TOK_SETCTLCOLORS: case TOK_SHOWWINDOW: case TOK_BRINGTOFRONT: case TOK_CREATEFONT: @@ -3398,6 +3576,11 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) if (line.getnumtokens() != a+1) PRINTHELP() ent.offsets[0]=add_string(line.gettoken_str(a)); SCRIPT_MSG("Delete: %s\"%s\"\n",ent.offsets[1]?"/REBOOTOK ":"",line.gettoken_str(a)); + + DefineInnerLangString(NLF_DEL_FILE); +#ifdef NSIS_SUPPORT_MOVEONREBOOT + DefineInnerLangString(NLF_DEL_ON_REBOOT); +#endif } return add_entry(&ent); #else//!NSIS_SUPPORT_DELETE @@ -3424,6 +3607,8 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) else if (line.gettoken_str(1)[0]=='/') PRINTHELP() ent.offsets[0]=add_string(line.gettoken_str(a)); SCRIPT_MSG("RMDir: %s%s\"%s\"\n",a==1?"":line.gettoken_str(1),ent.offsets[1]?" ":"",line.gettoken_str(a)); + + DefineInnerLangString(NLF_REMOVE_DIR); } return add_entry(&ent); #else//!NSIS_SUPPORT_RMDIR @@ -3526,6 +3711,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) if (!s && line.gettoken_str(a+2)[0]) PRINTHELP() section_add_size_kb(size_kb); SCRIPT_MSG("CopyFiles: %s\"%s\" -> \"%s\", size=%iKB\n",ent.offsets[2]&FOF_SILENT?"(silent) ":"", line.gettoken_str(a),line.gettoken_str(a+1),size_kb); + + DefineInnerLangString(NLF_COPY_FAILED); + DefineInnerLangString(NLF_COPY_TO); } return add_entry(&ent); #else//!NSIS_SUPPORT_COPYFILES @@ -3620,8 +3808,20 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ent.which=EW_UPDATETEXT; ent.offsets[0] = 0; ent.offsets[1] = line.gettoken_enum(1,"lastused\0listonly\0textonly\0both\0none\0"); - if (ent.offsets[1] < 0) PRINTHELP() - if (!ent.offsets[1]) ent.offsets[1]=8; + if (ent.offsets[1] < 0) PRINTHELP(); + switch (ent.offsets[1]) { + case 0: + ent.offsets[1]=8; + break; + case 1: + case 2: + case 3: + ent.offsets[1]<<=2; + break; + case 4: + ent.offsets[1]=16; + break; + } SCRIPT_MSG("SetDetailsPrint: %s\n",line.gettoken_str(1)); return add_entry(&ent); case TOK_SETAUTOCLOSE: @@ -3702,7 +3902,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ent.offsets[0]=GetUserVarIndex(line, 1); { char buf[32]; - wsprintf(buf,"%d",1+(uninstall_mode?build_uninst.code_size:build_header.common.num_entries)); + wsprintf(buf,"%d",1+(cur_header->blocks[NB_ENTRIES].num)); ent.offsets[1]=add_string(buf); } if (ent.offsets[0] < 0) PRINTHELP() @@ -4033,7 +4233,8 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ent.offsets[3]=add_string(line.gettoken_str(4)); if (which_token == TOK_READREGDWORD) ent.offsets[4]=1; else ent.offsets[4]=0; - if (line.gettoken_str(3)[0] == '\\') warning("%s: registry path name begins with \'\\\', may cause problems (%s:%d)",line.gettoken_str(0),curfilename,linecnt); + if (line.gettoken_str(3)[0] == '\\') + warning_fl("%s: registry path name begins with \'\\\', may cause problems",line.gettoken_str(0)); SCRIPT_MSG("%s %s %s\\%s\\%s\n",line.gettoken_str(0), line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4)); @@ -4062,7 +4263,8 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ent.offsets[0]=(int)rootkey_tab[k]; ent.offsets[1]=add_string(line.gettoken_str(a+1)); ent.offsets[2]=(which_token==TOK_DELETEREGKEY)?0:add_string(line.gettoken_str(a+2)); - if (line.gettoken_str(a+1)[0] == '\\') warning("%s: registry path name begins with \'\\\', may cause problems (%s:%d)",line.gettoken_str(0),curfilename,linecnt); + if (line.gettoken_str(a+1)[0] == '\\') + warning_fl("%s: registry path name begins with \'\\\', may cause problems",line.gettoken_str(0)); if (which_token==TOK_DELETEREGKEY) SCRIPT_MSG("DeleteRegKey: %s\\%s\n",line.gettoken_str(a),line.gettoken_str(a+1)); else @@ -4080,7 +4282,8 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ent.which=EW_WRITEREG; ent.offsets[0]=(int)rootkey_tab[k]; ent.offsets[1]=add_string(line.gettoken_str(2)); - if (line.gettoken_str(2)[0] == '\\') warning("%s: registry path name begins with \'\\\', may cause problems (%s:%d)",line.gettoken_str(0),curfilename,linecnt); + if (line.gettoken_str(2)[0] == '\\') + warning_fl("%s: registry path name begins with \'\\\', may cause problems",line.gettoken_str(0)); ent.offsets[2]=add_string(line.gettoken_str(3)); if (which_token == TOK_WRITEREGSTR || which_token == TOK_WRITEREGEXPANDSTR) { @@ -4150,7 +4353,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ent.offsets[2]=add_string(line.gettoken_str(3)); ent.offsets[3]=add_string(line.gettoken_str(4)); ent.offsets[4]=which_token == TOK_ENUMREGKEY; - if (line.gettoken_str(3)[0] == '\\') warning("%s: registry path name begins with \'\\\', may cause problems (%s:%d)",line.gettoken_str(0),curfilename,linecnt); + if (line.gettoken_str(3)[0] == '\\') warning_fl("%s: registry path name begins with \'\\\', may cause problems",line.gettoken_str(0)); SCRIPT_MSG("%s %s %s\\%s\\%s\n",which_token == TOK_ENUMREGKEY ? "EnumRegKey" : "EnumRegValue", line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4)); } @@ -4202,6 +4405,8 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ent.offsets[1]=1; ent.offsets[2]=0; } + + DefineInnerLangString(NLF_INST_CORRUPTED); } return add_entry(&ent); case TOK_PUSH: @@ -4390,6 +4595,8 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ent.which=EW_REBOOT; ent.offsets[0]=0xbadf00d; SCRIPT_MSG("Reboot! (WOW)\n"); + + DefineInnerLangString(NLF_INST_CORRUPTED); return add_entry(&ent); case TOK_IFREBOOTFLAG: ent.which=EW_IFFLAG; @@ -4439,11 +4646,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) #endif//!NSIS_CONFIG_LOG #ifdef NSIS_CONFIG_COMPONENTPAGE case TOK_SECTIONSETTEXT: - if (uninstall_mode) - { - ERROR_MSG("Error: %s called in uninstall section.\n", line.gettoken_str(0)); - return PS_ERROR; - } ent.which=EW_SECTIONSET; ent.offsets[0]=add_string(line.gettoken_str(1)); ent.offsets[1]=SECTION_FIELD_SET(name_ptr); @@ -4451,11 +4653,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) SCRIPT_MSG("SectionSetText: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2)); return add_entry(&ent); case TOK_SECTIONGETTEXT: - if (uninstall_mode) - { - ERROR_MSG("Error: %s called in uninstall section.\n", line.gettoken_str(0)); - return PS_ERROR; - } ent.which=EW_SECTIONSET; ent.offsets[0]=add_string(line.gettoken_str(1)); ent.offsets[1]=SECTION_FIELD_GET(name_ptr); @@ -4464,11 +4661,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) SCRIPT_MSG("SectionGetText: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2)); return add_entry(&ent); case TOK_SECTIONSETFLAGS: - if (uninstall_mode) - { - ERROR_MSG("Error: %s called in uninstall section.\n", line.gettoken_str(0)); - return PS_ERROR; - } ent.which=EW_SECTIONSET; ent.offsets[0]=add_string(line.gettoken_str(1)); ent.offsets[1]=SECTION_FIELD_SET(flags); @@ -4476,11 +4668,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) SCRIPT_MSG("SectionSetFlags: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2)); return add_entry(&ent); case TOK_SECTIONGETFLAGS: - if (uninstall_mode) - { - ERROR_MSG("Error: %s called in uninstall section.\n", line.gettoken_str(0)); - return PS_ERROR; - } ent.which=EW_SECTIONSET; ent.offsets[0]=add_string(line.gettoken_str(1)); ent.offsets[1]=SECTION_FIELD_GET(flags); @@ -4489,11 +4676,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) SCRIPT_MSG("SectionGetFlags: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2)); return add_entry(&ent); case TOK_INSTTYPESETTEXT: - if (uninstall_mode) - { - ERROR_MSG("Error: %s called in uninstall section.\n", line.gettoken_str(0)); - return PS_ERROR; - } ent.which=EW_INSTTYPESET; ent.offsets[0]=add_string(line.gettoken_str(1)); ent.offsets[1]=add_string(line.gettoken_str(2)); @@ -4501,11 +4683,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) SCRIPT_MSG("InstTypeSetText: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2)); return add_entry(&ent); case TOK_INSTTYPEGETTEXT: - if (uninstall_mode) - { - ERROR_MSG("Error: %s called in uninstall section.\n", line.gettoken_str(0)); - return PS_ERROR; - } ent.which=EW_INSTTYPESET; ent.offsets[0]=add_string(line.gettoken_str(1)); ent.offsets[1]=GetUserVarIndex(line, 2); @@ -4514,11 +4691,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) SCRIPT_MSG("InstTypeGetText: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2)); return add_entry(&ent); case TOK_SECTIONSETINSTTYPES: - if (uninstall_mode) - { - ERROR_MSG("Error: %s called in uninstall section.\n", line.gettoken_str(0)); - return PS_ERROR; - } ent.which=EW_SECTIONSET; ent.offsets[0]=add_string(line.gettoken_str(1)); ent.offsets[1]=SECTION_FIELD_SET(install_types); @@ -4526,11 +4698,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) SCRIPT_MSG("SectionSetInstTypes: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2)); return add_entry(&ent); case TOK_SECTIONGETINSTTYPES: - if (uninstall_mode) - { - ERROR_MSG("Error: %s called in uninstall section.\n", line.gettoken_str(0)); - return PS_ERROR; - } ent.which=EW_SECTIONSET; ent.offsets[0]=add_string(line.gettoken_str(1)); ent.offsets[1]=SECTION_FIELD_GET(install_types); @@ -4539,11 +4706,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) SCRIPT_MSG("SectionGetInstTypes: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2)); return add_entry(&ent); case TOK_SECTIONSETSIZE: - if (uninstall_mode) - { - ERROR_MSG("Error: %s called in uninstall section.\n", line.gettoken_str(0)); - return PS_ERROR; - } ent.which=EW_SECTIONSET; ent.offsets[0]=add_string(line.gettoken_str(1)); ent.offsets[1]=SECTION_FIELD_SET(size_kb); @@ -4551,11 +4713,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) SCRIPT_MSG("SectionSetSize: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2)); return add_entry(&ent); case TOK_SECTIONGETSIZE: - if (uninstall_mode) - { - ERROR_MSG("Error: %s called in uninstall section.\n", line.gettoken_str(0)); - return PS_ERROR; - } ent.which=EW_SECTIONSET; ent.offsets[0]=add_string(line.gettoken_str(1)); ent.offsets[1]=SECTION_FIELD_GET(size_kb); @@ -4566,24 +4723,14 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) case TOK_SETCURINSTTYPE: { int ret; - if (uninstall_mode) - { - ERROR_MSG("Error: %s called in uninstall section.\n", line.gettoken_str(0)); - return PS_ERROR; - } SCRIPT_MSG("SetCurInstType: %s\n",line.gettoken_str(1)); - ret = add_entry_direct(EW_SETFLAG, FLAG_OFFSET(cur_insttype), add_string(line.gettoken_str(1))); + ret = add_entry_indirect(EW_SETFLAG, FLAG_OFFSET(cur_insttype), add_string(line.gettoken_str(1))); if (ret != PS_OK) return ret; - ret = add_entry_direct(EW_INSTTYPESET, 0, 0, 0, 1); + ret = add_entry_indirect(EW_INSTTYPESET, 0, 0, 0, 1); if (ret != PS_OK) return ret; } return PS_OK; case TOK_GETCURINSTTYPE: - if (uninstall_mode) - { - ERROR_MSG("Error: %s called in uninstall section.\n", line.gettoken_str(0)); - return PS_ERROR; - } ent.which=EW_GETFLAG; ent.offsets[0]=GetUserVarIndex(line, 1); ent.offsets[1]=FLAG_OFFSET(cur_insttype); @@ -4664,9 +4811,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) #ifdef NSIS_SUPPORT_VERSION_INFO case TOK_VI_ADDKEY: { - LANGID LangID=0; + LANGID LangID=0; int a = 1; - if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) + if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) LangID=atoi(line.gettoken_str(a++)+6); if (line.getnumtokens()!=a+2) PRINTHELP(); char *pKey = line.gettoken_str(a); @@ -4680,12 +4827,12 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) { SCRIPT_MSG("%s: \"%s\" \"%s\"\n", line.gettoken_str(0), line.gettoken_str(a), line.gettoken_str(a+1)); LANGID lReaded = LangID; - StringTable *strTable = GetTable(LangID); + LanguageTable *table = GetLangTable(LangID); if ( a > 1 && lReaded == 0 ) - warning("%s: %s language not loaded, using default \"1033-English\". (%s:%d)", line.gettoken_str(0), line.gettoken_str(1), curfilename,linecnt); - if ( rVersionInfo.SetKeyValue(LangID, strTable->nlf ? strTable->nlf->m_uCodePage : 1252 /*English US*/, pKey, pValue) ) + warning_fl("%s: %s language not loaded, using default \"1033-English\"", line.gettoken_str(0), line.gettoken_str(1)); + if ( rVersionInfo.SetKeyValue(LangID, table->nlf.m_bLoaded ? table->nlf.m_uCodePage : 1252 /*English US*/, pKey, pValue) ) { - ERROR_MSG("%s: \"%s\" \"%04d-%s\" already defined!\n",line.gettoken_str(0), line.gettoken_str(2), LangID, strTable->nlf ? strTable->nlf->m_szName : LangID == 1033 ? "English" : "???"); + ERROR_MSG("%s: \"%s\" \"%04d-%s\" already defined!\n",line.gettoken_str(0), line.gettoken_str(2), LangID, table->nlf.m_bLoaded ? table->nlf.m_szName : LangID == 1033 ? "English" : "???"); return PS_ERROR; } @@ -4773,12 +4920,21 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) else { ent.which=EW_EXTRACTFILE; + + DefineInnerLangString(NLF_SKIPPED); + DefineInnerLangString(NLF_ERR_DECOMPRESSING); + DefineInnerLangString(NLF_ERR_WRITING); + DefineInnerLangString(NLF_EXTRACT); + DefineInnerLangString(NLF_CANT_WRITE); + ent.offsets[0]=1; // overwrite off + ent.offsets[0]|=(MB_ABORTRETRYIGNORE|MB_ICONSTOP)<<2; ent.offsets[1]=add_string(tempDLL); ent.offsets[2]=data_handle; ent.offsets[3]=0xffffffff; ent.offsets[4]=0xffffffff; ent.offsets[5]=MB_ABORTRETRYIGNORE | MB_ICONSTOP; + ent.offsets[5]=DefineInnerLangString(NLF_FILE_ERROR); ret=add_entry(&ent); if (ret != PS_OK) { free(command); @@ -4829,7 +4985,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) } SCRIPT_MSG("\n"); if (nounloadmisused) - warning("/NOUNLOAD must come first before any plugin parameter. Unless the plugin you are trying to use has a parameter /NOUNLOAD, you are doing something wrong. (%s:%d)",curfilename,linecnt); + warning_fl("/NOUNLOAD must come first before any plugin parameter. Unless the plugin you are trying to use has a parameter /NOUNLOAD, you are doing something wrong"); // next, call it ent.which=EW_REGISTERDLL; @@ -4894,7 +5050,7 @@ int CEXEBuild::do_add_file(const char *lgss, int attrib, int recurse, int linecn char dir[1024]; char newfn[1024]; HANDLE h; - WIN32_FIND_DATA d, temp; + WIN32_FIND_DATA d; strcpy(dir,lgss); { char *s=dir+strlen(dir); @@ -4913,7 +5069,15 @@ int CEXEBuild::do_add_file(const char *lgss, int attrib, int recurse, int linecn DWORD len; (*total_files)++; sprintf(newfn,"%s%s%s",dir,dir[0]?"\\":"",d.cFileName); - hFile=CreateFile(newfn,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); + hFile=CreateFile( + newfn, + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, + NULL + ); if (hFile == INVALID_HANDLE_VALUE) { ERROR_MSG("%sFile: failed opening file \"%s\"\n",generatecode?"":"Reserve",newfn); @@ -4953,6 +5117,13 @@ int CEXEBuild::do_add_file(const char *lgss, int attrib, int recurse, int linecn if (generatecode) { ent.which=EW_EXTRACTFILE; + + DefineInnerLangString(NLF_SKIPPED); + DefineInnerLangString(NLF_ERR_DECOMPRESSING); + DefineInnerLangString(NLF_ERR_WRITING); + DefineInnerLangString(NLF_EXTRACT); + DefineInnerLangString(NLF_CANT_WRITE); + ent.offsets[0]=build_overwrite; if (name_override) { @@ -5016,8 +5187,10 @@ int CEXEBuild::do_add_file(const char *lgss, int attrib, int recurse, int linecn ent.offsets[3]=0xffffffff; ent.offsets[4]=0xffffffff; } - // Added by ramon 23 May 2003 - ent.offsets[5]=(build_allowskipfiles?MB_ABORTRETRYIGNORE:MB_RETRYCANCEL) | MB_ICONSTOP; + + // overwrite flag can be 0, 1, 2 or 3. in all cases, 2 bits + ent.offsets[0] |= ((build_allowskipfiles ? MB_ABORTRETRYIGNORE : MB_RETRYCANCEL) | MB_ICONSTOP) << 2; + ent.offsets[5] = DefineInnerLangString(build_allowskipfiles ? NLF_FILE_ERROR : NLF_FILE_ERROR_NOIGNORE); if (uninstall_mode) m_uninst_fileused++; else m_inst_fileused++; @@ -5035,17 +5208,9 @@ int CEXEBuild::do_add_file(const char *lgss, int attrib, int recurse, int linecn } if (attrib) { - char tmp_path[1024]; ent.which=EW_SETFILEATTRIBUTES; - if (name_override) - { - sprintf(tmp_path,"%s\\%s",cur_out_path,name_override); - } - else - { - sprintf(tmp_path,"%s\\%s",cur_out_path,buf); - } - ent.offsets[0]=add_string(tmp_path); + // $OUTDIR is the working directory + ent.offsets[0]=add_string(name_override?name_override:buf); ent.offsets[1]=d.dwFileAttributes; a=add_entry(&ent); @@ -5063,6 +5228,9 @@ int CEXEBuild::do_add_file(const char *lgss, int attrib, int recurse, int linecn if (recurse) { +#ifdef NSIS_SUPPORT_STACK + WIN32_FIND_DATA temp; + int a=GetFileAttributes(lgss); const char *fspec=lgss+strlen(dir)+!!dir[0]; strcpy(newfn,lgss); @@ -5090,12 +5258,10 @@ int CEXEBuild::do_add_file(const char *lgss, int attrib, int recurse, int linecn { entry ent={0,}; int a; - int wd_save=strlen(cur_out_path); + char out_path[1024] = "$OUTDIR\\"; { - char *i=d.cFileName,*o=cur_out_path; - while (*o) o++; - if (o > cur_out_path && CharPrev(cur_out_path,o)[0] != '\\') *o++='\\'; + char *i = d.cFileName, *o=out_path+strlen(out_path); while (*i) { @@ -5120,38 +5286,36 @@ int CEXEBuild::do_add_file(const char *lgss, int attrib, int recurse, int linecn char spec[1024]; sprintf(spec,"%s%s%s",dir,dir[0]?"\\":"",d.cFileName); - SCRIPT_MSG("%sFile: Descending to: \"%s\" -> \"%s\"\n",generatecode?"":"Reserve",spec,cur_out_path); + SCRIPT_MSG("%sFile: Descending to: \"%s\"\n",generatecode?"":"Reserve",spec); strcat(spec,"\\"); strcat(spec,fspec); if (generatecode) { + a=add_entry_indirect(EW_PUSHPOP, add_string("$OUTDIR")); + if (a != PS_OK) + { + FindClose(h); + return a; + } + + a=add_entry_indirect(EW_ASSIGNVAR, m_UserVarNames.get("OUTDIR"), add_string(out_path)); + if (a != PS_OK) + { + FindClose(h); + return a; + } + HANDLE htemp = FindFirstFile(spec,&temp); if (htemp != INVALID_HANDLE_VALUE) { FindClose(htemp); - ent.which=EW_CREATEDIR; - ent.offsets[0]=add_string(cur_out_path); - ent.offsets[1]=1; - a=add_entry(&ent); + a=add_entry_indirect(EW_CREATEDIR, add_string("$OUTDIR"), 1); if (a != PS_OK) { FindClose(h); return a; } - if (attrib) - { - ent.which=EW_SETFILEATTRIBUTES; - ent.offsets[0]=add_string(cur_out_path); - ent.offsets[1]=d.dwFileAttributes; - - a=add_entry(&ent); - if (a != PS_OK) - { - FindClose(h); - return a; - } - } } } a=do_add_file(spec,attrib,recurse,linecnt,total_files,NULL,generatecode,data_handle,rec_depth+1); @@ -5161,8 +5325,26 @@ int CEXEBuild::do_add_file(const char *lgss, int attrib, int recurse, int linecn return a; } - cur_out_path[wd_save]=0; - SCRIPT_MSG("%sFile: Returning to: \"%s\" -> \"%s\"\n",generatecode?"":"Reserve",dir,cur_out_path); + if (generatecode) + { + a=add_entry_indirect(EW_PUSHPOP, m_UserVarNames.get("OUTDIR"), 1); + if (a != PS_OK) + { + FindClose(h); + return a; + } + + if (attrib) + { + a=add_entry_indirect(EW_SETFILEATTRIBUTES, add_string(out_path), d.dwFileAttributes); + if (a != PS_OK) + { + FindClose(h); + return a; + } + } + } + SCRIPT_MSG("%sFile: Returning to: \"%s\"\n",generatecode?"":"Reserve",dir); } } } while (FindNextFile(h,&d)); @@ -5170,11 +5352,8 @@ int CEXEBuild::do_add_file(const char *lgss, int attrib, int recurse, int linecn if (!rec_depth) { - entry ent={0,}; - ent.which=EW_CREATEDIR; - ent.offsets[1]=1; - ent.offsets[0]=add_string(cur_out_path); - a=add_entry(&ent); + // return to the original $OUTDIR + a=add_entry_indirect(EW_CREATEDIR, add_string("$OUTDIR"), 1); if (a != PS_OK) { FindClose(h); @@ -5183,6 +5362,10 @@ int CEXEBuild::do_add_file(const char *lgss, int attrib, int recurse, int linecn } } } +#else + ERROR_MSG("Error: recursive [Reserve]File requires NSIS_SUPPORT_STACK\n"); + return PS_ERROR; +#endif } return PS_OK; diff --git a/Source/strlist.h b/Source/strlist.h index 294895e1..cc2d2492 100644 --- a/Source/strlist.h +++ b/Source/strlist.h @@ -481,7 +481,7 @@ class MMapBuf : public IGrowBuf int add(const void *data, int len) { if (len<=0) return 0; - resize(getlen()+len); + resize(getlen()+len); memcpy((char*)get()+getlen()-len,data,len); return getlen()-len; } @@ -507,7 +507,7 @@ class MMapBuf : public IGrowBuf char buf[MAX_PATH],buf2[MAX_PATH]; GetTempPath(MAX_PATH,buf); GetTempFileName(buf,"nsd",0,buf2); - m_hFile=CreateFile(buf2,GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE,NULL); + m_hFile=CreateFile(buf2,GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE|FILE_FLAG_SEQUENTIAL_SCAN,NULL); } if (m_hFile != INVALID_HANDLE_VALUE) m_hFileMap=CreateFileMapping(m_hFile,NULL,PAGE_READWRITE,0,m_alloc,NULL); diff --git a/Source/tokens.cpp b/Source/tokens.cpp index 8e645b1d..0d10052e 100644 --- a/Source/tokens.cpp +++ b/Source/tokens.cpp @@ -22,14 +22,14 @@ static tokenType tokenlist[TOK__LAST] = {TOK_ADDSIZE,"AddSize",1,0,"size_to_add_to_section_in_kb"}, {TOK_AUTOCLOSE,"AutoCloseWindow",1,0,"(false|true)"}, {TOK_BGGRADIENT,"BGGradient",0,3,"(off | [top_color [bottom_color [text_color]]])"}, -{TOK_BRANDINGTEXT,"BrandingText",1,2,"[/LANG=lang_id] [/TRIM(LEFT|RIGHT|CENTER)] installer_text"}, +{TOK_BRANDINGTEXT,"BrandingText",1,1,"[/TRIM(LEFT|RIGHT|CENTER)] installer_text"}, {TOK_BRINGTOFRONT,"BringToFront",0,0,""}, {TOK_CALL,"Call",1,0,"function_name | [:label_name]"}, {TOK_CALLINSTDLL,"CallInstDLL",2,1,"dll_path_on_target.dll [/NOUNLOAD] function"}, -{TOK_CAPTION,"Caption",1,1,"[/LANG=lang_id] installer_caption"}, -{TOK_CHANGEUI,"ChangeUI",2,1,"/RTL (all|dlg_id) ui_file.exe"}, +{TOK_CAPTION,"Caption",1,0,"installer_caption"}, +{TOK_CHANGEUI,"ChangeUI",1,1,"[/RTL] (all|dlg_id) ui_file.exe"}, {TOK_CLEARERRORS,"ClearErrors",0,0,""}, -{TOK_COMPTEXT,"ComponentText",0,4,"[/LANG=lang_id] [component_page_description] [component_subtext1] [component_subtext2]"}, +{TOK_COMPTEXT,"ComponentText",0,3,"[component_page_description] [component_subtext1] [component_subtext2]"}, {TOK_GETDLLVERSION,"GetDLLVersion",3,0,"filename $(user_var: high output) $(user_var: low output)"}, {TOK_GETDLLVERSIONLOCAL,"GetDLLVersionLocal",3,0,"localfilename $(user_var: high output) $(user_var: low output)"}, {TOK_GETFILETIME,"GetFileTime",3,0,"file $(user_var: high output) $(user_var: low output)"}, @@ -46,8 +46,9 @@ static tokenType tokenlist[TOK__LAST] = {TOK_DELETEREGVALUE,"DeleteRegValue",3,0,"root_key subkey entry_name\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD)"}, {TOK_DELETE,"Delete",1,1,"[/REBOOTOK] filespec"}, {TOK_DETAILPRINT,"DetailPrint",1,0,"message"}, -{TOK_DIRTEXT,"DirText",0,4,"[/LANG=lang_id] [directory_page_description] [directory_page_subtext] [browse button text]"}, +{TOK_DIRTEXT,"DirText",0,3,"[directory_page_description] [directory_page_subtext] [browse_button_text] [browse_dlg_text]"}, {TOK_DIRSHOW,"DirShow",1,0,"(show|hide)"}, +{TOK_DIRVAR,"DirVar",1,0,"$(user_var: dir in/out))"}, {TOK_ROOTDIRINST,"AllowRootDirInstall",1,0,"(true|false)"}, {TOK_CHECKBITMAP,"CheckBitmap",1,0,"local_bitmap.bmp"}, {TOK_ENABLEWINDOW,"EnableWindow",2,0,"hwnd (1|0)"}, @@ -66,7 +67,7 @@ static tokenType tokenlist[TOK__LAST] = {TOK_FLUSHINI,"FlushINI",1,0,"ini_file"}, {TOK_RESERVEFILE,"ReserveFile",1,-1,"[/nonfatal] [/r] file [file...]"}, {TOK_FILECLOSE,"FileClose",1,0,"$(user_var: handle input)"}, -{TOK_FILEERRORTEXT,"FileErrorText",0,3,"[/LANG=lang_id] [text (can contain $0)] [text without ignore (can contain $0)]"}, +{TOK_FILEERRORTEXT,"FileErrorText",0,2,"[text (can contain $0)] [text without ignore (can contain $0)]"}, {TOK_FILEOPEN,"FileOpen",3,0,"$(user_var: handle output) filename openmode\n openmode=r|w|a"}, {TOK_FILEREAD,"FileRead",2,1,"$(user_var: handle input) $(user_var: text output) [maxlen]"}, {TOK_FILEWRITE,"FileWrite",2,0,"$(user_var: handle input) text"}, @@ -78,18 +79,18 @@ static tokenType tokenlist[TOK__LAST] = {TOK_GETDLGITEM,"GetDlgItem",3,0,"$(user_var: handle output) dialog item_id"}, {TOK_GETFULLPATHNAME,"GetFullPathName",2,1,"[/SHORT] $(user_var: result) path_or_file"}, {TOK_GETTEMPFILENAME,"GetTempFileName",1,1,"$(user_var: name output) [base_dir]"}, -{TOK_GETWINTEXT,"GetWindowText",2,0,"$(user_var: handle output) hwnd"}, {TOK_HIDEWINDOW,"HideWindow",0,0,""}, {TOK_ICON,"Icon",1,0,"local_icon.ico"}, {TOK_IFABORT,"IfAbort",1,1,"label_to_goto_if_abort [label_to_goto_if_no_abort]"}, {TOK_IFERRORS,"IfErrors",1,1,"label_to_goto_if_errors [label_to_goto_if_no_errors]"}, {TOK_IFFILEEXISTS,"IfFileExists",2,1,"filename label_to_goto_if_file_exists [label_to_goto_otherwise]"}, {TOK_IFREBOOTFLAG,"IfRebootFlag",1,1,"jump_if_set [jump_if_not_set]"}, +{TOK_IFSILENT,"IfSilent",1,1,"jump_if_silent [jump_if_not_silent]"}, {TOK_INSTALLDIRREGKEY,"InstallDirRegKey",3,0,"root_key subkey entry_name\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD)"}, {TOK_INSTCOLORS,"InstallColors",1,1,"(/windows | (foreground_color background_color))"}, {TOK_INSTDIR,"InstallDir",1,0,"default_install_directory"}, {TOK_INSTPROGRESSFLAGS,"InstProgressFlags",0,-1,"[flag [...]]\n flag={smooth|colored}"}, -{TOK_INSTTYPE,"InstType",1,1,"install_type_name | /NOCUSTOM | ([/LANG=lang_id] /CUSTOMSTRING=str) | /COMPONENTSONLYONCUSTOM"}, +{TOK_INSTTYPE,"InstType",1,0,"install_type_name | /NOCUSTOM | /CUSTOMSTRING=str | /COMPONENTSONLYONCUSTOM"}, {TOK_INTOP,"IntOp",3,1,"$(user_var: result) val1 OP [val2]\n OP=(+ - * / % | & ^ ~ ! || &&)"}, {TOK_INTCMP,"IntCmp",3,2,"val1 val2 jump_if_equal [jump_if_val1_less] [jump_if_val1_more]"}, {TOK_INTCMPU,"IntCmpU",3,2,"val1 val2 jump_if_equal [jump_if_val1_less] [jump_if_val1_more]"}, @@ -97,10 +98,11 @@ static tokenType tokenlist[TOK__LAST] = {TOK_ISWINDOW,"IsWindow",2,1,"hwnd jump_if_window [jump_if_not_window]"}, {TOK_GOTO,"Goto",1,0,"label"}, {TOK_LANGSTRING,"LangString",3,0,"[un.]name lang_id string"}, -{TOK_LANGSTRINGUP,"LangStringUP",3,0,"[un.]name lang_id string"}, -{TOK_LICENSEDATA,"LicenseData",1,1,"[/LANG=lang_id] local_file_that_has_license_text.txt"}, -{TOK_LICENSEFORCESELECTION,"LicenseForceSelection",1,3,"[/LANG=lang_id] (checkbox [accept_text] | radiobuttons [accept_text] [decline_text] | off)"}, -{TOK_LICENSETEXT,"LicenseText",1,2,"[/LANG=lang_id] license_page_description [license_button_text]"}, +{TOK_LANGSTRINGUP,"LangStringUP",0,0,"obsolete, use LangString."}, +{TOK_LICENSEDATA,"LicenseData",1,0,"local_file_that_has_license_text | license_lang_string"}, +{TOK_LICENSEFORCESELECTION,"LicenseForceSelection",1,2,"(checkbox [accept_text] | radiobuttons [accept_text] [decline_text] | off)"}, +{TOK_LICENSELANGSTRING,"LicenseLangString",3,0,"name lang_id license_path"}, +{TOK_LICENSETEXT,"LicenseText",1,1,"license_page_description [license_button_text]"}, {TOK_LICENSEBKCOLOR,"LicenseBkColor",1,0,"background_color"}, {TOK_LOADNLF,"LoadLanguageFile",1,0,"language.nlf"}, {TOK_LOGSET,"LogSet",1,0,"on|off"}, @@ -108,13 +110,16 @@ static tokenType tokenlist[TOK__LAST] = {TOK_MESSAGEBOX,"MessageBox",2,4,"mode messagebox_text [return_check label_to_goto_if_equal [return_check2 label2]]\n mode=modeflag[|modeflag[|modeflag[...]]]\n " "modeflag=(MB_ABORTRETRYIGNORE|MB_OK|MB_OKCANCEL|MB_RETRYCANCEL|MB_YESNO|MB_YESNOCANCEL|MB_ICONEXCLAMATION|MB_ICONINFORMATION|MB_ICONQUESTION|MB_ICONSTOP|MB_TOPMOST|MB_SETFOREGROUND|MB_RIGHT"}, {TOK_NOP,"Nop",0,0,""}, -{TOK_NAME,"Name",1,1,"[/LANG=lang_id] installer_name"}, +{TOK_NAME,"Name",1,0,"installer_name"}, {TOK_OUTFILE,"OutFile",1,0,"install_output.exe"}, #ifdef NSIS_SUPPORT_CODECALLBACKS -{TOK_PAGE,"Page",1,5,"((custom [creator_function] [leave_function] [caption]) | ((license|components|directory|instfiles) [pre_function] [show_function] [leave_function])) [define_if_last]"}, +{TOK_PAGE,"Page",1,4,"((custom [creator_function] [leave_function] [caption]) | ((license|components|directory|instfiles|uninstConfirm) [pre_function] [show_function] [leave_function]))"}, #else -{TOK_PAGE,"Page",1,1,"license|components|directory|instfiles"}, +{TOK_PAGE,"Page",1,1,"license|components|directory|instfiles|uninstConfirm"}, #endif +{TOK_PAGECALLBACKS,"PageCallbacks",0,3,"([creator_function] [leave_function]) | ([pre_function] [show_function] [leave_function])"}, +{TOK_PAGEEX,"PageEx",1,0,"[un.](custom|uninstConfirm|license|components|directory|instfiles)"}, +{TOK_PAGEEXEND,"PageExEnd",0,0,""}, {TOK_POP,"Pop",1,0,"$(user_var: output)"}, {TOK_PUSH,"Push",1,0,"string"}, {TOK_QUIT,"Quit",0,0,""}, @@ -147,7 +152,7 @@ static tokenType tokenlist[TOK__LAST] = {TOK_INSTTYPEGETTEXT,"InstTypeGetText",2,0,"insttype_index $(user_var: output flags)"}, {TOK_SENDMESSAGE,"SendMessage",4,2,"hwnd message [wparam|STR:wParam] [lparam|STR:lParam] [$(user_var: return value)] [/TIMEOUT=X]"}, {TOK_SETAUTOCLOSE,"SetAutoClose",1,0,"(false|true)"}, -{TOK_SETBKCOLOR,"SetBkColor",2,0,"hwnd color"}, +{TOK_SETCTLCOLORS,"SetCtlColors",2,1,"hwnd (branding | (text_color (transparent|bg_color)))"}, {TOK_SETBRANDINGIMAGE,"SetBrandingImage",1,2,"[/IMGID=image_item_id_in_dialog] [/RESIZETOFIT] bitmap.bmp"}, {TOK_SETCOMPRESS,"SetCompress",1,0,"(off|auto|force)"}, {TOK_SETCOMPRESSOR,"SetCompressor",1,0,"(zlib|bzip2)"}, @@ -162,6 +167,7 @@ static tokenType tokenlist[TOK__LAST] = {TOK_SETPLUGINUNLOAD,"SetPluginUnload",1,0,"(manual|alwaysoff)"}, {TOK_SETREBOOTFLAG,"SetRebootFlag",1,0,"true|false"}, {TOK_SETSHELLVARCONTEXT,"SetShellVarContext",1,0,"all|current"}, +{TOK_SETSILENT,"SetSilent",1,0,"silent|normal"}, {TOK_SHOWDETAILS,"ShowInstDetails",1,0,"(hide|show|nevershow)"}, {TOK_SHOWDETAILSUNINST,"ShowUninstDetails",1,0,"(hide|show|nevershow)"}, {TOK_SHOWWINDOW,"ShowWindow",2,0,"hwnd show_state"}, @@ -171,17 +177,17 @@ static tokenType tokenlist[TOK__LAST] = {TOK_STRCMP,"StrCmp",3,1,"str1 str2 label_to_goto_if_equal [label_to_goto_if_not]"}, {TOK_STRCPY,"StrCpy",2,2,"$(user_var: output) str [maxlen] [startoffset]"}, {TOK_STRLEN,"StrLen",2,0,"$(user_var: length output) str"}, -{TOK_SUBCAPTION,"SubCaption",2,1,"[/LANG=lang_id] page_number(0-4) new_subcaption"}, +{TOK_SUBCAPTION,"SubCaption",2,0,"page_number(0-4) new_subcaption"}, {TOK_UNINSTALLEXENAME,"UninstallExeName",0,0,"no longer supported, use WriteUninstaller from section."}, -{TOK_UNINSTCAPTION,"UninstallCaption",1,1,"[/LANG=lang_id] uninstaller_caption"}, +{TOK_UNINSTCAPTION,"UninstallCaption",1,0,"uninstaller_caption"}, {TOK_UNINSTICON,"UninstallIcon",1,0,"icon_on_local_system.ico"}, #ifdef NSIS_SUPPORT_CODECALLBACKS -{TOK_UNINSTPAGE,"UninstPage",1,5,"((custom [creator_function] [leave_function] [caption]) | ((uninstConfirm|instfiles) [pre_function] [show_function] [leave_function])) [define_if_last]"}, +{TOK_UNINSTPAGE,"UninstPage",1,4,"((custom [creator_function] [leave_function] [caption]) | ((license|components|directory|instfiles|uninstConfirm) [pre_function] [show_function] [leave_function]))"}, #else -{TOK_UNINSTPAGE,"UninstPage",1,1,"uninstConfirm|instfiles"}, +{TOK_UNINSTPAGE,"UninstPage",1,1,"license|components|directory|instfiles|uninstConfirm"}, #endif -{TOK_UNINSTTEXT,"UninstallText",1,2,"[/LANG=lang_id] Text_to_go_on_uninstall page [subtext]"}, -{TOK_UNINSTSUBCAPTION,"UninstallSubCaption",2,1,"[/LANG=lang_id] page_number(0-2) new_subcaption"}, +{TOK_UNINSTTEXT,"UninstallText",1,1,"Text_to_go_on_uninstall_page [subtext]"}, +{TOK_UNINSTSUBCAPTION,"UninstallSubCaption",2,0,"page_number(0-2) new_subcaption"}, {TOK_UNREGDLL,"UnRegDLL",1,0,"dll_path_on_target.dll"}, // useless - {TOK_USEOUTERUIITEM,"UseOuterUIItem",2,0,"item id"}, {TOK_WINDOWICON,"WindowIcon",1,0,"on|off"}, @@ -207,18 +213,18 @@ static tokenType tokenlist[TOK__LAST] = {TOK_P_WARNING,"!warning",0,1,"[warning_message]"}, {TOK_P_ERROR,"!error",0,1,"[error_message]"}, -{TOK_P_VERBOSE,"!verbose",1,0,"verbose_level"}, +{TOK_P_VERBOSE,"!verbose",1,0,"verbose_level | push | pop"}, {TOK_P_MACRO,"!macro",1,-1,"macroname [parms ...]"}, {TOK_P_MACROEND,"!macroend",0,0,""}, {TOK_P_INSERTMACRO,"!insertmacro",1,-1,"macroname [parms ...]"}, -{TOK_MISCBUTTONTEXT,"MiscButtonText",0,5,"[/LANG=lang_id] [back button text] [next button text] [cancel button text] [close button text]"}, -{TOK_DETAILSBUTTONTEXT,"DetailsButtonText",0,2,"[/LANG=lang_id] [details button text]"}, -{TOK_UNINSTBUTTONTEXT,"UninstallButtonText",0,2,"[/LANG=lang_id] [uninstall button text]"}, -{TOK_INSTBUTTONTEXT,"InstallButtonText",0,2,"[/LANG=lang_id] [install button text]"}, -{TOK_SPACETEXTS,"SpaceTexts",0,3,"[/LANG=lang_id] [space required text] [space available text]"}, -{TOK_COMPLETEDTEXT,"CompletedText",0,2,"[/LANG=lang_id] [completed text]"}, +{TOK_MISCBUTTONTEXT,"MiscButtonText",0,4,"[back button text] [next button text] [cancel button text] [close button text]"}, +{TOK_DETAILSBUTTONTEXT,"DetailsButtonText",0,1,"[details button text]"}, +{TOK_UNINSTBUTTONTEXT,"UninstallButtonText",0,1,"[uninstall button text]"}, +{TOK_INSTBUTTONTEXT,"InstallButtonText",0,1,"[install button text]"}, +{TOK_SPACETEXTS,"SpaceTexts",0,2,"none | ([space required text] [space available text])"}, +{TOK_COMPLETEDTEXT,"CompletedText",0,2,"[completed text]"}, {TOK_GETFUNCTIONADDR,"GetFunctionAddress",2,0,"output function"}, {TOK_GETLABELADDR,"GetLabelAddress",2,0,"output label"}, @@ -231,8 +237,8 @@ static tokenType tokenlist[TOK__LAST] = // Added by ramon 3 jun 2003 {TOK_DEFVAR,"Var",1,0,"VarName"}, // Added by ramon 6 jun 2003 -{TOK_VI_ADDKEY,"VIAddVersionKey", 2, 1, "[/LANG=lang_id] keyname value"}, -{TOK_VI_SETPRODUCTVERSION,"VIProductVersion", 1, 0, "[version_string_X.X.X.X]"}, +{TOK_VI_ADDKEY,"VIAddVersionKey",2,1,"/LANG=lang_id keyname value"}, +{TOK_VI_SETPRODUCTVERSION,"VIProductVersion",1,0,"[version_string_X.X.X.X]"}, }; void CEXEBuild::print_help(char *commandname) diff --git a/Source/tokens.h b/Source/tokens.h index cccdb326..e3e80f1e 100644 --- a/Source/tokens.h +++ b/Source/tokens.h @@ -14,10 +14,11 @@ enum TOK_WINDOWICON, TOK_DIRTEXT, TOK_COMPTEXT, - TOK_LICENSETEXT, + TOK_LICENSEBKCOLOR, TOK_LICENSEDATA, TOK_LICENSEFORCESELECTION, - TOK_LICENSEBKCOLOR, + TOK_LICENSELANGSTRING, + TOK_LICENSETEXT, TOK_UNINSTTEXT, TOK_SILENTINST, TOK_SILENTUNINST, @@ -46,6 +47,10 @@ enum TOK_SETCOMPRESSOR, TOK_LOADNLF, TOK_RESERVEFILE, + TOK_ALLOWSKIPFILES, + TOK_DEFVAR, + TOK_VI_ADDKEY, + TOK_VI_SETPRODUCTVERSION, TOK_MISCBUTTONTEXT, TOK_DETAILSBUTTONTEXT, @@ -89,9 +94,15 @@ enum TOK_FUNCTIONEND, TOK_ADDSIZE, - // Page oredering shit + // page oredering shit TOK_PAGE, TOK_UNINSTPAGE, + TOK_PAGEEX, + TOK_PAGECALLBACKS, + TOK_PAGEEXEND, + + // PageEx stuff + TOK_DIRVAR, // flag setters TOK_SETDATESAVE, @@ -175,8 +186,7 @@ enum TOK_SENDMESSAGE, TOK_ISWINDOW, TOK_GETDLGITEM, - TOK_GETWINTEXT, - TOK_SETBKCOLOR, + TOK_SETCTLCOLORS, TOK_FINDFIRST, TOK_FINDNEXT, TOK_FINDCLOSE, @@ -213,12 +223,8 @@ enum TOK_CREATEFONT, TOK_SHOWWINDOW, TOK_ENABLEWINDOW, - // Added by ramon 23 May 2003 - TOK_ALLOWSKIPFILES, - // Added by ramon 3 jun 2003 - TOK_DEFVAR, - TOK_VI_ADDKEY, - TOK_VI_SETPRODUCTVERSION, + TOK_SETSILENT, + TOK_IFSILENT, TOK__LAST, TOK__PLUGINCOMMAND diff --git a/TODO.txt b/TODO.txt index 8ebe16ed..6b4905a7 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,42 +1,30 @@ TODO --- NSIS 2 Beta 4 -- - NSIS * SetCurInstType should work without the components page -* component page for uninstaller, multiple sections - -* more default texts in NLF language files - -* all installer strings should be language strings - -* move no custom to compiler (custom as just another inst type) - * empty subsections should not show --- Before NSIS 2 Final -- +* start optimizing datablock after file mapping was released + +* map files part by part to save memory + +* compressor from command line + +* skip plugin calls, file instructions that add more than one file with +1 with goto + +* more powerful plug-ins (access to ExecFunc and flags and even more) + +* LZMA compression + +* stop using static variables so CEXEBuild can be used as a real class EXAMPLES * write an advanced paging example showing multiple components page with multiple instfiles pages -NSIS - -* skip plugin calls, file instructions that add more than one file with +1 with goto - -* different color for the drive space when there is not enough space - -* more powerful plug-ins (access to ExecFunc and flags and even more) - -* ChangeUI RTL full support - -* LZMA compression - -* stop using static variables so CEXEBuild can be used as a real class - PLUGINS * InstallOptions - custom class names so you can include whatever control you want