Version Information now rely on languages, some more updates on named uservars, maybe last one before official release :) (preview UserVars.nsi - doesn't compile yet)
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@2633 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
7adbddc567
commit
1ea2160310
14 changed files with 539 additions and 283 deletions
46
Examples/UserVars.nsi
Normal file
46
Examples/UserVars.nsi
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
; VersionInfo.nsi
|
||||||
|
;
|
||||||
|
; This script shows you how to declare and user VARIABLES.
|
||||||
|
|
||||||
|
;--------------------------------
|
||||||
|
!include "MUI.nsh"
|
||||||
|
|
||||||
|
!define MUI_PRODUCT "User Variables"
|
||||||
|
!define MUI_VERSION "1.0"
|
||||||
|
|
||||||
|
;--------------------------------
|
||||||
|
;Configuration
|
||||||
|
|
||||||
|
;General
|
||||||
|
OutFile "UserVars.exe"
|
||||||
|
ShowInstDetails nevershow
|
||||||
|
|
||||||
|
;--------------------------------
|
||||||
|
;Pages
|
||||||
|
|
||||||
|
!insertmacro MUI_PAGE_INSTFILES
|
||||||
|
|
||||||
|
;--------------------------------
|
||||||
|
;Languages
|
||||||
|
|
||||||
|
!insertmacro MUI_LANGUAGE "English"
|
||||||
|
|
||||||
|
;--------------------------------
|
||||||
|
; Declaration of User Variables with command DIM, allowed charaters for variables names : [a-z][A-Z][0-9] and '_'
|
||||||
|
|
||||||
|
DIM "Name"
|
||||||
|
DIM "Serial"
|
||||||
|
|
||||||
|
;--------------------------------
|
||||||
|
;Installer Sections
|
||||||
|
|
||||||
|
Section "Dummy Section" SecCopyUI
|
||||||
|
|
||||||
|
StrCpy $0 "Admin"
|
||||||
|
StrCpy "$Name" $0
|
||||||
|
StrCpy "$Serial" "12345"
|
||||||
|
|
||||||
|
MessageBox MB_OK "User Name: $Name$\n$\nSerial Number: $Serial"
|
||||||
|
|
||||||
|
SectionEnd
|
||||||
|
|
|
@ -12,16 +12,14 @@ OutFile "VersionInfo.exe"
|
||||||
;--------------------------------
|
;--------------------------------
|
||||||
;Version Information
|
;Version Information
|
||||||
|
|
||||||
VISetVersionLanguage 2057 1200 ; English UK
|
|
||||||
VIAddTranslation 2057 1200 ; English UK
|
|
||||||
VIProductVersion "1.2.3.4"
|
VIProductVersion "1.2.3.4"
|
||||||
VIAddVersionKey "ProductName" "Test Application"
|
VIAddVersionKey ${LANG_ENGLISH} "ProductName" "Test Application"
|
||||||
VIAddVersionKey "Comments" "A test comment"
|
VIAddVersionKey ${LANG_ENGLISH} "Comments" "A test comment"
|
||||||
VIAddVersionKey "CompanyName" "Fake company"
|
VIAddVersionKey ${LANG_ENGLISH} "CompanyName" "Fake company"
|
||||||
VIAddVersionKey "LegalTrademarks" "Test Application is a trademark of Fake company"
|
VIAddVersionKey ${LANG_ENGLISH} "LegalTrademarks" "Test Application is a trademark of Fake company"
|
||||||
VIAddVersionKey "LegalCopyright" "© Fake company"
|
VIAddVersionKey ${LANG_ENGLISH} "LegalCopyright" "© Fake company"
|
||||||
VIAddVersionKey "FileDescription" "Test Application"
|
VIAddVersionKey ${LANG_ENGLISH} "FileDescription" "Test Application"
|
||||||
VIAddVersionKey "FileVersion" "1.2.3"
|
VIAddVersionKey ${LANG_ENGLISH} "FileVersion" "1.2.3"
|
||||||
|
|
||||||
;--------------------------------
|
;--------------------------------
|
||||||
|
|
||||||
|
|
|
@ -28,12 +28,24 @@ CResourceVersionInfo::CResourceVersionInfo()
|
||||||
// Detect local codepage and language
|
// Detect local codepage and language
|
||||||
WORD Lang = GetSystemDefaultLangID();
|
WORD Lang = GetSystemDefaultLangID();
|
||||||
WORD CodePage = GetACP();
|
WORD CodePage = GetACP();
|
||||||
char Buff[10];
|
/*
|
||||||
sprintf(Buff, "%04x%04x", Lang, CodePage);
|
SetKeyValue(Lang, CodePage, "Comments", "Portuguese");
|
||||||
SetVersionInfoLang(Buff);
|
SetKeyValue(Lang, CodePage, "FileVersion", "1.2");
|
||||||
|
SetKeyValue(Lang, CodePage, "FileDescription", "Soft");
|
||||||
|
SetKeyValue(Lang, CodePage, "LegalCopyright", "My");
|
||||||
|
SetKeyValue(Lang, CodePage, "InternalName", "My");
|
||||||
|
SetKeyValue(Lang, CodePage, "CompanyName", "rats");
|
||||||
|
SetKeyValue(Lang, CodePage, "ProductVersion", "ProductVersion");
|
||||||
|
|
||||||
AddTranslation(CodePage, Lang);
|
Lang = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
|
||||||
b_CustomTranslations = false;
|
SetKeyValue(Lang, CodePage, "Comments", "English");
|
||||||
|
SetKeyValue(Lang, CodePage, "FileVersion", "1.2");
|
||||||
|
SetKeyValue(Lang, CodePage, "FileDescription", "Soft");
|
||||||
|
SetKeyValue(Lang, CodePage, "LegalCopyright", "My");
|
||||||
|
SetKeyValue(Lang, CodePage, "InternalName", "My");
|
||||||
|
SetKeyValue(Lang, CodePage, "CompanyName", "rats");
|
||||||
|
SetKeyValue(Lang, CodePage, "ProductVersion", "ProductVersion");
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
CResourceVersionInfo::~CResourceVersionInfo()
|
CResourceVersionInfo::~CResourceVersionInfo()
|
||||||
|
@ -58,14 +70,13 @@ void CResourceVersionInfo::SetProductVersion(int HighPart, int LowPart)
|
||||||
m_FixedInfo.dwProductVersionMS = HighPart;
|
m_FixedInfo.dwProductVersionMS = HighPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Util function
|
// Util function - must be freeded
|
||||||
wstring StrToWstr(const string& istr)
|
WCHAR* StrToWstrAlloc(const char* istr, int codepage)
|
||||||
{
|
{
|
||||||
wstring wstr;
|
int strSize = strlen(istr);
|
||||||
for(string::const_iterator it = istr.begin(); it != istr.end(); ++it)
|
WCHAR* wstr = new WCHAR[(strSize*2)];
|
||||||
{
|
MultiByteToWideChar(codepage, 0, istr, -1, wstr, strSize*2);
|
||||||
wstr += (unsigned char)*it;
|
return wstr;
|
||||||
} return wstr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetVersionHeader (LPSTR &p, WORD &wLength, WORD &wValueLength, WORD &wType)
|
int GetVersionHeader (LPSTR &p, WORD &wLength, WORD &wValueLength, WORD &wType)
|
||||||
|
@ -95,7 +106,7 @@ void PadStream (GrowBuf &strm)
|
||||||
strm.add (&ZEROS, 4 - (strm.getlen() % 4));
|
strm.add (&ZEROS, 4 - (strm.getlen() % 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveVersionHeader (GrowBuf &strm, WORD wLength, WORD wValueLength, WORD wType, const wstring &key, void *value)
|
void SaveVersionHeader (GrowBuf &strm, WORD wLength, WORD wValueLength, WORD wType, const WCHAR *key, void *value)
|
||||||
{
|
{
|
||||||
WORD valueLen;
|
WORD valueLen;
|
||||||
WORD keyLen;
|
WORD keyLen;
|
||||||
|
@ -104,8 +115,8 @@ void SaveVersionHeader (GrowBuf &strm, WORD wLength, WORD wValueLength, WORD wTy
|
||||||
|
|
||||||
strm.add (&wValueLength, sizeof (wValueLength));
|
strm.add (&wValueLength, sizeof (wValueLength));
|
||||||
strm.add (&wType, sizeof (wType));
|
strm.add (&wType, sizeof (wType));
|
||||||
keyLen = (key.length() + 1) * sizeof (WCHAR);
|
keyLen = (wcslen(key) + 1) * sizeof (WCHAR);
|
||||||
strm.add ((void*)key.c_str(), keyLen);
|
strm.add ((void*)key, keyLen);
|
||||||
|
|
||||||
PadStream(strm);
|
PadStream(strm);
|
||||||
|
|
||||||
|
@ -118,112 +129,129 @@ void SaveVersionHeader (GrowBuf &strm, WORD wLength, WORD wValueLength, WORD wTy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CResourceVersionInfo::ExportToStream(GrowBuf &strm)
|
void CResourceVersionInfo::ExportToStream(GrowBuf &strm, int Index)
|
||||||
{
|
{
|
||||||
DWORD v;
|
DWORD v;
|
||||||
WORD wSize;
|
WORD wSize;
|
||||||
int p, p1;
|
int p, p1;
|
||||||
wstring KeyName, KeyValue;
|
WCHAR *KeyName, *KeyValue;
|
||||||
|
|
||||||
|
strm.resize(0);
|
||||||
SaveVersionHeader (strm, 0, sizeof (VS_FIXEDFILEINFO), 0, L"VS_VERSION_INFO", &m_FixedInfo);
|
SaveVersionHeader (strm, 0, sizeof (VS_FIXEDFILEINFO), 0, L"VS_VERSION_INFO", &m_FixedInfo);
|
||||||
|
|
||||||
if ( m_ChildStrings.getnum() > 0 )
|
DefineList *pChildStrings = m_ChildStringLists.get_strings(Index);
|
||||||
|
if ( pChildStrings->getnum() > 0 )
|
||||||
{
|
{
|
||||||
GrowBuf stringInfoStream;
|
GrowBuf stringInfoStream;
|
||||||
KeyName = StrToWstr(m_VersionInfoLang);
|
int codepage = m_ChildStringLists.get_codepage(Index);
|
||||||
|
LANGID langid = m_ChildStringLists.get_lang(Index);
|
||||||
|
char Buff[16];
|
||||||
|
sprintf(Buff, "%04x%04x", langid, codepage);
|
||||||
|
KeyName = StrToWstrAlloc(Buff, CP_ACP);
|
||||||
|
SaveVersionHeader (stringInfoStream, 0, 0, 0, KeyName, &ZEROS);
|
||||||
|
delete [] KeyName;
|
||||||
|
|
||||||
SaveVersionHeader (stringInfoStream, 0, 0, 0, KeyName.c_str(), &ZEROS);
|
for ( int i = 0; i < pChildStrings->getnum(); i++ )
|
||||||
|
{
|
||||||
|
PadStream (stringInfoStream);
|
||||||
|
|
||||||
for ( int i = 0; i < m_ChildStrings.getnum(); i++ )
|
p = stringInfoStream.getlen();
|
||||||
{
|
KeyName = StrToWstrAlloc(pChildStrings->getname(i), codepage);
|
||||||
PadStream (stringInfoStream);
|
KeyValue = StrToWstrAlloc(pChildStrings->getvalue(i), codepage);
|
||||||
|
SaveVersionHeader (stringInfoStream, 0, wcslen(KeyValue) + 1, 1, KeyName, (void*)KeyValue);
|
||||||
|
delete [] KeyName;
|
||||||
|
delete [] KeyValue;
|
||||||
|
wSize = stringInfoStream.getlen() - p;
|
||||||
|
|
||||||
p = stringInfoStream.getlen();
|
*(WORD*)((PBYTE)stringInfoStream.get()+p)=wSize;
|
||||||
KeyName = StrToWstr(m_ChildStrings.getname(i));
|
}
|
||||||
KeyValue = StrToWstr(m_ChildStrings.getvalue(i));
|
|
||||||
SaveVersionHeader (stringInfoStream, 0, KeyValue.length() + 1, 1, KeyName.c_str(), (void*)KeyValue.c_str());
|
|
||||||
wSize = stringInfoStream.getlen() - p;
|
|
||||||
|
|
||||||
*(WORD*)((PBYTE)stringInfoStream.get()+p)=wSize;
|
wSize = stringInfoStream.getlen();
|
||||||
}
|
*(WORD*)((PBYTE)stringInfoStream.get())=wSize;
|
||||||
|
|
||||||
wSize = stringInfoStream.getlen();
|
PadStream (strm);
|
||||||
*(WORD*)((PBYTE)stringInfoStream.get())=wSize;
|
p = strm.getlen();
|
||||||
|
SaveVersionHeader (strm, 0, 0, 0, L"StringFileInfo", &ZEROS);
|
||||||
|
strm.add (stringInfoStream.get(), stringInfoStream.getlen());
|
||||||
|
wSize = strm.getlen() - p;
|
||||||
|
|
||||||
PadStream (strm);
|
*(WORD*)((PBYTE)strm.get()+p)=wSize;
|
||||||
p = strm.getlen();
|
|
||||||
SaveVersionHeader (strm, 0, 0, 0, L"StringFileInfo", &ZEROS);
|
|
||||||
strm.add (stringInfoStream.get(), stringInfoStream.getlen());
|
|
||||||
wSize = strm.getlen() - p;
|
|
||||||
|
|
||||||
*(WORD*)((PBYTE)strm.get()+p)=wSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_Translations.size() > 0 )
|
// Show all languages avaiable using Var-Translations
|
||||||
|
if ( m_ChildStringLists.getnum() > 0 )
|
||||||
{
|
{
|
||||||
PadStream (strm);
|
PadStream (strm);
|
||||||
p = strm.getlen();
|
p = strm.getlen();
|
||||||
SaveVersionHeader (strm, 0, 0, 0, L"VarFileInfo", &ZEROS);
|
SaveVersionHeader (strm, 0, 0, 0, L"VarFileInfo", &ZEROS);
|
||||||
PadStream (strm);
|
PadStream (strm);
|
||||||
|
|
||||||
p1 = strm.getlen();
|
p1 = strm.getlen();
|
||||||
SaveVersionHeader (strm, 0, 0, 0, L"Translation", &ZEROS);
|
SaveVersionHeader (strm, 0, 0, 0, L"Translation", &ZEROS);
|
||||||
|
|
||||||
for ( int i = 0; i < m_Translations.size(); i++ )
|
// First add selected code language translation
|
||||||
|
v = MAKELONG(m_ChildStringLists.get_lang(Index), m_ChildStringLists.get_codepage(Index));
|
||||||
|
strm.add (&v, sizeof (v));
|
||||||
|
|
||||||
|
for ( int k =0; k < m_ChildStringLists.getnum(); k++ )
|
||||||
|
{
|
||||||
|
if ( k != Index )
|
||||||
{
|
{
|
||||||
v = m_Translations[i];
|
v = MAKELONG(m_ChildStringLists.get_lang(k), m_ChildStringLists.get_codepage(k));
|
||||||
strm.add (&v, sizeof (v));
|
strm.add (&v, sizeof (v));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wSize = strm.getlen() - p1;
|
wSize = strm.getlen() - p1;
|
||||||
*(WORD*)((PBYTE)strm.get()+p1)=wSize;
|
*(WORD*)((PBYTE)strm.get()+p1)=wSize;
|
||||||
wSize = sizeof (int) * m_Translations.size();
|
wSize = sizeof (int) * m_ChildStringLists.getnum();
|
||||||
p1+=sizeof(WORD);
|
p1+=sizeof(WORD);
|
||||||
*(WORD*)((PBYTE)strm.get()+p1)=wSize;
|
*(WORD*)((PBYTE)strm.get()+p1)=wSize;
|
||||||
|
|
||||||
wSize = strm.getlen() - p;
|
wSize = strm.getlen() - p;
|
||||||
*(WORD*)((PBYTE)strm.get()+p)=wSize;
|
*(WORD*)((PBYTE)strm.get()+p)=wSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
wSize = strm.getlen();
|
wSize = strm.getlen();
|
||||||
*(WORD*)((PBYTE)strm.get())=wSize;
|
*(WORD*)((PBYTE)strm.get())=wSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CResourceVersionInfo::SetKeyValue(char* AKeyName, char* AValue)
|
// Returns 0 if success, 1 if already defined
|
||||||
|
int CResourceVersionInfo::SetKeyValue(LANGID lang_id, int codepage, char* AKeyName, char* AValue)
|
||||||
{
|
{
|
||||||
m_ChildStrings.add(AKeyName, AValue);
|
int pos = m_ChildStringLists.find(lang_id, codepage);
|
||||||
|
if ( pos == -1 )
|
||||||
|
{
|
||||||
|
pos = m_ChildStringLists.add(lang_id, codepage);
|
||||||
|
}
|
||||||
|
DefineList *pStrings = m_ChildStringLists.get_strings(pos);
|
||||||
|
return pStrings->add(AKeyName, AValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CResourceVersionInfo::AddTranslation(WORD CodePage, WORD LangID )
|
int CResourceVersionInfo::GetStringTablesCount()
|
||||||
{
|
{
|
||||||
if ( !b_CustomTranslations )
|
return m_ChildStringLists.getnum();
|
||||||
{
|
|
||||||
b_CustomTranslations = true;
|
|
||||||
m_Translations.clear(); // remove local system default, user want to customize
|
|
||||||
}
|
|
||||||
DWORD dwTrans = MAKELONG(LangID, CodePage);
|
|
||||||
if ( find(m_Translations.begin(), m_Translations.end(), dwTrans) == m_Translations.end() )
|
|
||||||
m_Translations.push_back(dwTrans);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CResourceVersionInfo::GetKeyCount()
|
LANGID CResourceVersionInfo::GetLangID(int Index)
|
||||||
{
|
{
|
||||||
return m_ChildStrings.getnum();
|
return m_ChildStringLists.get_lang(Index);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CResourceVersionInfo::GetTranslationCount()
|
int CResourceVersionInfo::GetCodePage(int Index)
|
||||||
{
|
{
|
||||||
return m_Translations.size();
|
return m_ChildStringLists.get_codepage(Index);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *CResourceVersionInfo::FindKey(char *pKeyName)
|
char *CResourceVersionInfo::FindKey(LANGID LangID, int codepage, char *pKeyName)
|
||||||
{
|
{
|
||||||
return m_ChildStrings.find(pKeyName);
|
int pos = m_ChildStringLists.find(LangID, codepage);
|
||||||
}
|
if ( pos == -1 )
|
||||||
|
{
|
||||||
void CResourceVersionInfo::SetVersionInfoLang(char *pLandCp)
|
return NULL;
|
||||||
{
|
}
|
||||||
m_VersionInfoLang = pLandCp;
|
DefineList *pStrings = m_ChildStringLists.get_strings(pos);
|
||||||
|
return pStrings->find(pKeyName);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CResourceVersionInfo::IsValidCodePage(WORD codePage )
|
bool CResourceVersionInfo::IsValidCodePage(WORD codePage )
|
||||||
|
|
|
@ -14,28 +14,83 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
struct version_string_list {
|
||||||
|
int codepage;
|
||||||
|
LANGID lang_id;
|
||||||
|
int name;
|
||||||
|
DefineList *pChildStrings;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CVersionStrigList : public SortedStringListND<struct version_string_list>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int add(LANGID langid, int codepage)
|
||||||
|
{
|
||||||
|
char Buff[10];
|
||||||
|
sprintf(Buff, "%04x", langid);
|
||||||
|
int pos = SortedStringListND<struct version_string_list>::add(Buff);
|
||||||
|
if (pos == -1) return false;
|
||||||
|
((struct version_string_list*)gr.get())[pos].pChildStrings = new DefineList;
|
||||||
|
((struct version_string_list*)gr.get())[pos].codepage = codepage;
|
||||||
|
((struct version_string_list*)gr.get())[pos].lang_id = langid;
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
LANGID get_lang(int idx)
|
||||||
|
{
|
||||||
|
version_string_list *data=(version_string_list *)gr.get();
|
||||||
|
return data[idx].lang_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_codepage(int idx)
|
||||||
|
{
|
||||||
|
version_string_list *data=(version_string_list *)gr.get();
|
||||||
|
return data[idx].codepage;
|
||||||
|
}
|
||||||
|
|
||||||
|
DefineList* get_strings(int idx)
|
||||||
|
{
|
||||||
|
version_string_list *data=(version_string_list *)gr.get();
|
||||||
|
return data[idx].pChildStrings;
|
||||||
|
}
|
||||||
|
|
||||||
|
int find(LANGID lang_id, int codepage)
|
||||||
|
{
|
||||||
|
char Buff[10];
|
||||||
|
sprintf(Buff, "%04x", lang_id);
|
||||||
|
return SortedStringListND<struct version_string_list>::find(Buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
int getlen()
|
||||||
|
{
|
||||||
|
return strings.getlen();
|
||||||
|
}
|
||||||
|
|
||||||
|
int getnum()
|
||||||
|
{
|
||||||
|
return gr.getlen()/sizeof(struct version_string_list);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
class CResourceVersionInfo
|
class CResourceVersionInfo
|
||||||
{
|
{
|
||||||
VS_FIXEDFILEINFO m_FixedInfo;
|
VS_FIXEDFILEINFO m_FixedInfo;
|
||||||
DefineList m_ChildStrings;
|
CVersionStrigList m_ChildStringLists;
|
||||||
vector< DWORD > m_Translations;
|
char m_VersionInfoLang[10];
|
||||||
string m_VersionInfoLang;
|
|
||||||
bool b_CustomTranslations;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CResourceVersionInfo();
|
CResourceVersionInfo();
|
||||||
virtual ~CResourceVersionInfo();
|
virtual ~CResourceVersionInfo();
|
||||||
void SetKeyValue (char *AKeyName, char *AValue);
|
int SetKeyValue(LANGID lang_id, int codepage, char* AKeyName, char* AValue);
|
||||||
void AddTranslation(WORD CodePage, WORD LangID );
|
|
||||||
void SetFileFlags(int Value);
|
void SetFileFlags(int Value);
|
||||||
void SetFileVersion(int HighPart, int LowPart);
|
void SetFileVersion(int HighPart, int LowPart);
|
||||||
void SetProductVersion(int HighPart, int LowPart);
|
void SetProductVersion(int HighPart, int LowPart);
|
||||||
void ExportToStream(GrowBuf &strm);
|
void ExportToStream(GrowBuf &strm, int Index);
|
||||||
int GetKeyCount();
|
int GetStringTablesCount();
|
||||||
int GetTranslationCount();
|
LANGID GetLangID(int Index);
|
||||||
char *FindKey(char *pKeyName);
|
int GetCodePage(int Index);
|
||||||
void SetVersionInfoLang(char *pLandCp);
|
char *FindKey(LANGID LangID, int codepage, char *pKeyName);
|
||||||
bool IsValidCodePage(WORD codePage );
|
bool IsValidCodePage(WORD codePage );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
193
Source/build.cpp
193
Source/build.cpp
|
@ -13,6 +13,11 @@
|
||||||
#include "exehead/lang.h"
|
#include "exehead/lang.h"
|
||||||
#include "ResourceVersionInfo.h"
|
#include "ResourceVersionInfo.h"
|
||||||
|
|
||||||
|
bool isSimpleChar(char ch)
|
||||||
|
{
|
||||||
|
return (ch == '_' ) || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
|
||||||
|
}
|
||||||
|
|
||||||
void CEXEBuild::define(const char *p, const char *v)
|
void CEXEBuild::define(const char *p, const char *v)
|
||||||
{
|
{
|
||||||
definedlist.add(p,v);
|
definedlist.add(p,v);
|
||||||
|
@ -241,8 +246,6 @@ CEXEBuild::CEXEBuild()
|
||||||
|
|
||||||
// Added by ramon 6 jun 2003
|
// Added by ramon 6 jun 2003
|
||||||
#ifdef NSIS_SUPPORT_VERSION_INFO
|
#ifdef NSIS_SUPPORT_VERSION_INFO
|
||||||
version_codePage=0;
|
|
||||||
version_lang=0;
|
|
||||||
version_product_v[0]=0;
|
version_product_v[0]=0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -305,6 +308,9 @@ CEXEBuild::CEXEBuild()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
last_used_lang=MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
|
last_used_lang=MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
|
||||||
|
char lang_id[16];
|
||||||
|
wsprintf(lang_id, "%u", last_used_lang);
|
||||||
|
definedlist.add("LANG_ENGLISH",lang_id);
|
||||||
|
|
||||||
build_header.common.num_pages=0;
|
build_header.common.num_pages=0;
|
||||||
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
|
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
|
||||||
|
@ -335,6 +341,37 @@ CEXEBuild::CEXEBuild()
|
||||||
use_first_insttype=true;
|
use_first_insttype=true;
|
||||||
|
|
||||||
build_header.license_bg=-COLOR_BTNFACE;
|
build_header.license_bg=-COLOR_BTNFACE;
|
||||||
|
|
||||||
|
#ifdef NSIS_SUPPORT_NAMED_USERVARS
|
||||||
|
// Register user variables $0, $1 and so one
|
||||||
|
char Aux[3];
|
||||||
|
for ( int i = 0; i < 10; i++ ) // 0 - 9
|
||||||
|
{
|
||||||
|
sprintf(Aux, "%d", i);
|
||||||
|
DeclaredUserVar(Aux);
|
||||||
|
}
|
||||||
|
for ( i = 0; i < 10; i++ ) // 10 - 19
|
||||||
|
{
|
||||||
|
sprintf(Aux, "R%d", i);
|
||||||
|
DeclaredUserVar(Aux);
|
||||||
|
}
|
||||||
|
DeclaredUserVar("CMDLINE"); // 20 everything before here doesn't have trailing slash removal
|
||||||
|
DeclaredUserVar("INSTDIR"); // 21
|
||||||
|
DeclaredUserVar("OUTDIR"); // 22
|
||||||
|
DeclaredUserVar("EXEDIR"); // 23
|
||||||
|
DeclaredUserVar("LANGUAGE"); // 24
|
||||||
|
DeclaredUserVar("PLUGINSDIR"); // 25
|
||||||
|
DeclaredUserVar("PROGRAMFILES"); // 26
|
||||||
|
DeclaredUserVar("SMPROGRAMS"); // 27
|
||||||
|
DeclaredUserVar("SMSTARTUP"); // 28
|
||||||
|
DeclaredUserVar("DESKTOP"); // 29
|
||||||
|
DeclaredUserVar("STARTMENU"); // 30
|
||||||
|
DeclaredUserVar("QUICKLAUNCH"); // 31
|
||||||
|
DeclaredUserVar("TEMP"); // 32
|
||||||
|
DeclaredUserVar("WINDIR"); // 33
|
||||||
|
DeclaredUserVar("SYSDIR"); // 34 everything after here doesn't have trailing slash removal
|
||||||
|
DeclaredUserVar("HWNDPARENT"); // 35
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int CEXEBuild::getcurdbsize() { return cur_datablock->getlen(); }
|
int CEXEBuild::getcurdbsize() { return cur_datablock->getlen(); }
|
||||||
|
@ -355,6 +392,7 @@ int CEXEBuild::add_intstring(const int i) // returns offset in stringblock
|
||||||
// based on Dave Laundon's code
|
// based on Dave Laundon's code
|
||||||
int CEXEBuild::preprocess_string(char *out, const char *in)
|
int CEXEBuild::preprocess_string(char *out, const char *in)
|
||||||
{
|
{
|
||||||
|
#ifndef NSIS_SUPPORT_NAMED_USERVARS
|
||||||
static const char VarNames[] =
|
static const char VarNames[] =
|
||||||
"HWNDPARENT\0" // 0
|
"HWNDPARENT\0" // 0
|
||||||
"0\0" // 1
|
"0\0" // 1
|
||||||
|
@ -394,6 +432,7 @@ int CEXEBuild::preprocess_string(char *out, const char *in)
|
||||||
"WINDIR\0" // 34
|
"WINDIR\0" // 34
|
||||||
"SYSDIR\0" // 35
|
"SYSDIR\0" // 35
|
||||||
;
|
;
|
||||||
|
#endif
|
||||||
|
|
||||||
const char *p=in;
|
const char *p=in;
|
||||||
while (*p)
|
while (*p)
|
||||||
|
@ -406,9 +445,15 @@ int CEXEBuild::preprocess_string(char *out, const char *in)
|
||||||
while (l--)
|
while (l--)
|
||||||
{
|
{
|
||||||
int i = (unsigned char)*p++;
|
int i = (unsigned char)*p++;
|
||||||
|
#ifndef NSIS_SUPPORT_NAMED_USERVARS
|
||||||
if (i >= VAR_CODES_START) {
|
if (i >= VAR_CODES_START) {
|
||||||
*out++ = (char)255;
|
*out++ = (char)255;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
if (i == VAR_CODES_START || i == 255 ) {
|
||||||
|
*out++ = (char)255;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
*out++=i;
|
*out++=i;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
@ -418,16 +463,25 @@ int CEXEBuild::preprocess_string(char *out, const char *in)
|
||||||
|
|
||||||
p=np;
|
p=np;
|
||||||
|
|
||||||
|
#ifndef NSIS_SUPPORT_NAMED_USERVARS
|
||||||
// Test for characters extending into the variable codes
|
// Test for characters extending into the variable codes
|
||||||
if (i >= VAR_CODES_START) {
|
if (i >= VAR_CODES_START) {
|
||||||
*out++ = (char)255;
|
*out++ = (char)255;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
// Test for characters that equals to control char of variable codes
|
||||||
|
if (i == VAR_CODES_START || i == 255 ) {
|
||||||
|
*out++ = (char)255;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else if (i == '$')
|
else if (i == '$')
|
||||||
{
|
{
|
||||||
if (*p == '$')
|
if (*p == '$')
|
||||||
p++; // Can simply convert $$ to $ now
|
p++; // Can simply convert $$ to $ now
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#ifndef NSIS_SUPPORT_NAMED_USERVARS
|
||||||
|
|
||||||
const char *pVarName;
|
const char *pVarName;
|
||||||
for (
|
for (
|
||||||
pVarName = VarNames, i = VAR_CODES_START;
|
pVarName = VarNames, i = VAR_CODES_START;
|
||||||
|
@ -444,43 +498,30 @@ int CEXEBuild::preprocess_string(char *out, const char *in)
|
||||||
p += strlen(pVarName);
|
p += strlen(pVarName);
|
||||||
}
|
}
|
||||||
else // warning should go here
|
else // warning should go here
|
||||||
|
#endif // not NSIS_SUPPORT_NAMED_USERVARS
|
||||||
{
|
{
|
||||||
#ifdef NSIS_SUPPORT_NAMED_USERVARS
|
#ifdef NSIS_SUPPORT_NAMED_USERVARS
|
||||||
bool bProceced=false;
|
bool bProceced=false;
|
||||||
if ( *p == '[' )
|
if ( *p )
|
||||||
{
|
{
|
||||||
char *pUserVarName = (char *)p+1;
|
const char *pUserVarName = p;
|
||||||
while ( *pUserVarName )
|
while ( isSimpleChar(*pUserVarName) )
|
||||||
|
pUserVarName++;
|
||||||
|
|
||||||
|
while ( pUserVarName > p )
|
||||||
{
|
{
|
||||||
if ( *pUserVarName == ']' )
|
const char * Debug = p-(pUserVarName-p);
|
||||||
{
|
int idxUserVar = m_UserVarNames.get((char*)p, pUserVarName-p);
|
||||||
*pUserVarName='\0';
|
|
||||||
int idxUserVar = m_UserVarNames.get((char*)p+1);
|
|
||||||
int varLen = strlen(p)+1;
|
|
||||||
*pUserVarName=']'; // restore
|
|
||||||
if ( idxUserVar >= 0 )
|
if ( idxUserVar >= 0 )
|
||||||
{
|
{
|
||||||
*out++=(unsigned int)VAR_CODES_START + 36; // Named user variable;
|
*out++=(unsigned int)VAR_CODES_START; // Named user variable;
|
||||||
*(WORD*)out=((WORD)idxUserVar+USER_VARS_COUNT) | 0xF000;
|
*(WORD*)out=((WORD)idxUserVar+1) | 0xF000;
|
||||||
out += sizeof(WORD);
|
out += sizeof(WORD);
|
||||||
p += varLen;
|
p += pUserVarName-p;
|
||||||
bProceced = true;
|
bProceced = true;
|
||||||
{
|
break;
|
||||||
for ( WORD i = 0; i < 0x0FFF; i++ )
|
|
||||||
{
|
|
||||||
WORD bb = i | 0xF000;
|
|
||||||
WORD ok = bb & 0x0FFF;
|
|
||||||
if ( ok != i )
|
|
||||||
{
|
|
||||||
warning("Problems with %d",i);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
pUserVarName--;
|
||||||
}
|
|
||||||
pUserVarName++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( bProceced )
|
if ( bProceced )
|
||||||
|
@ -1273,7 +1314,7 @@ int CEXEBuild::write_output(void)
|
||||||
GrowBuf VerInfoStream;
|
GrowBuf VerInfoStream;
|
||||||
bool bNeedVInfo = false;
|
bool bNeedVInfo = false;
|
||||||
|
|
||||||
if ( rVersionInfo.GetKeyCount() > 0 )
|
if ( rVersionInfo.GetStringTablesCount() > 0 )
|
||||||
{
|
{
|
||||||
if ( !version_product_v[0] )
|
if ( !version_product_v[0] )
|
||||||
{
|
{
|
||||||
|
@ -1291,19 +1332,23 @@ int CEXEBuild::write_output(void)
|
||||||
rVersionInfo.SetFileVersion(MAKELONG(iml, imm),MAKELONG(ill, ilm));
|
rVersionInfo.SetFileVersion(MAKELONG(iml, imm),MAKELONG(ill, ilm));
|
||||||
rVersionInfo.SetProductVersion(MAKELONG(iml, imm),MAKELONG(ill, ilm));
|
rVersionInfo.SetProductVersion(MAKELONG(iml, imm),MAKELONG(ill, ilm));
|
||||||
|
|
||||||
//rVersionInfo.AddTranslation(0x0,0x0409);
|
|
||||||
rVersionInfo.ExportToStream(VerInfoStream);
|
|
||||||
init_res_editor();
|
init_res_editor();
|
||||||
res_editor->UpdateResource(RT_VERSION, 1, 0, (BYTE*)VerInfoStream.get(), VerInfoStream.getlen());
|
for ( int i = 0; i < rVersionInfo.GetStringTablesCount(); i++ )
|
||||||
|
{
|
||||||
|
LANGID lang_id = rVersionInfo.GetLangID(i);
|
||||||
|
int code_page = rVersionInfo.GetCodePage(i);
|
||||||
|
StringTable * Table = GetTable(lang_id);
|
||||||
|
|
||||||
if ( !rVersionInfo.GetTranslationCount() )
|
if ( !rVersionInfo.FindKey(lang_id, code_page, "FileVersion") )
|
||||||
warning("Generating version information without any language/codepage defined.");
|
warning("Generating version information for language \"%04d-%s\" without standard key \"FileVersion\"", lang_id, Table->nlf ? Table->nlf->m_szName : lang_id == 1033 ? "English" : "???");
|
||||||
if ( !rVersionInfo.FindKey("FileVersion") )
|
if ( !rVersionInfo.FindKey(lang_id, code_page, "FileDescription") )
|
||||||
warning("Generating version information without standard key \"FileVersion\"");
|
warning("Generating version information for language \"%04d-%s\" without standard key \"FileDescription\"", lang_id, Table->nlf ? Table->nlf->m_szName : lang_id == 1033 ? "English" : "???");
|
||||||
if ( !rVersionInfo.FindKey("FileDescription") )
|
if ( !rVersionInfo.FindKey(lang_id, code_page, "LegalCopyright") )
|
||||||
warning("Generating version information without standard key \"FileDescription\"");
|
warning("Generating version information for language \"%04d-%s\" without standard key \"LegalCopyright\"", lang_id, Table->nlf ? Table->nlf->m_szName : lang_id == 1033 ? "English" : "???");
|
||||||
if ( !rVersionInfo.FindKey("LegalCopyright") )
|
|
||||||
warning("Generating version information without standard key \"LegalCopyright\"");
|
rVersionInfo.ExportToStream(VerInfoStream, i);
|
||||||
|
res_editor->UpdateResource(RT_VERSION, 1, lang_id, (BYTE*)VerInfoStream.get(), VerInfoStream.getlen());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2419,6 +2464,11 @@ int CEXEBuild::add_plugins_dir_initializer(void)
|
||||||
int ret;
|
int ret;
|
||||||
int zero_offset;
|
int zero_offset;
|
||||||
|
|
||||||
|
#ifdef NSIS_SUPPORT_NAMED_USERVARS
|
||||||
|
int var_zero;
|
||||||
|
var_zero=m_UserVarNames.get("0");
|
||||||
|
#endif
|
||||||
|
|
||||||
again:
|
again:
|
||||||
// Function [un.]Initialize_____Plugins
|
// Function [un.]Initialize_____Plugins
|
||||||
ret=add_function(uninstall?"un.Initialize_____Plugins":"Initialize_____Plugins");
|
ret=add_function(uninstall?"un.Initialize_____Plugins":"Initialize_____Plugins");
|
||||||
|
@ -2441,7 +2491,11 @@ again:
|
||||||
ret=add_entry_direct(EW_SETFLAG, FLAG_OFFSET(exec_error));
|
ret=add_entry_direct(EW_SETFLAG, FLAG_OFFSET(exec_error));
|
||||||
if (ret != PS_OK) return ret;
|
if (ret != PS_OK) return ret;
|
||||||
// GetTempFileName $0
|
// GetTempFileName $0
|
||||||
|
#ifdef NSIS_SUPPORT_NAMED_USERVARS
|
||||||
|
ret=add_entry_direct(EW_GETTEMPFILENAME, var_zero);
|
||||||
|
#else
|
||||||
ret=add_entry_direct(EW_GETTEMPFILENAME);
|
ret=add_entry_direct(EW_GETTEMPFILENAME);
|
||||||
|
#endif
|
||||||
if (ret != PS_OK) return ret;
|
if (ret != PS_OK) return ret;
|
||||||
// Delete $0 - the temp file created
|
// Delete $0 - the temp file created
|
||||||
ret=add_entry_direct(EW_DELETEFILE, zero_offset);
|
ret=add_entry_direct(EW_DELETEFILE, zero_offset);
|
||||||
|
@ -2453,10 +2507,18 @@ again:
|
||||||
ret=add_entry_direct(EW_IFFLAG, ns_label.add("Initialize_____Plugins_error",0), 0, FIELD_OFFSET(installer_flags, exec_error)/sizeof(int));
|
ret=add_entry_direct(EW_IFFLAG, ns_label.add("Initialize_____Plugins_error",0), 0, FIELD_OFFSET(installer_flags, exec_error)/sizeof(int));
|
||||||
if (ret != PS_OK) return ret;
|
if (ret != PS_OK) return ret;
|
||||||
// Copy $0 to $PLUGINSDIR
|
// Copy $0 to $PLUGINSDIR
|
||||||
|
#ifdef NSIS_SUPPORT_NAMED_USERVARS
|
||||||
|
ret=add_entry_direct(EW_ASSIGNVAR, m_UserVarNames.get("PLUGINSDIR"), zero_offset);
|
||||||
|
#else
|
||||||
ret=add_entry_direct(EW_ASSIGNVAR, 25, zero_offset);
|
ret=add_entry_direct(EW_ASSIGNVAR, 25, zero_offset);
|
||||||
|
#endif
|
||||||
if (ret != PS_OK) return ret;
|
if (ret != PS_OK) return ret;
|
||||||
// Pop $0
|
// Pop $0
|
||||||
|
#ifdef NSIS_SUPPORT_NAMED_USERVARS
|
||||||
|
ret=add_entry_direct(EW_PUSHPOP, var_zero, 1);
|
||||||
|
#else
|
||||||
ret=add_entry_direct(EW_PUSHPOP, 0, 1);
|
ret=add_entry_direct(EW_PUSHPOP, 0, 1);
|
||||||
|
#endif
|
||||||
if (ret != PS_OK) return ret;
|
if (ret != PS_OK) return ret;
|
||||||
|
|
||||||
// done
|
// done
|
||||||
|
@ -2532,12 +2594,9 @@ int CEXEBuild::DeclaredUserVar(const char *szVarName)
|
||||||
{
|
{
|
||||||
while ( *pVarName )
|
while ( *pVarName )
|
||||||
{
|
{
|
||||||
if ((*pVarName < '0') ||
|
if ( !isSimpleChar(*pVarName) )
|
||||||
(*pVarName > '9' && *pVarName < 'A' ) ||
|
|
||||||
(*pVarName > 'Z' && *pVarName < 'a' && *pVarName != '_' ) ||
|
|
||||||
(*pVarName > 'z') )
|
|
||||||
{
|
{
|
||||||
ERROR_MSG("Error: invalid charaters in variable name \"%s\"\n", szVarName);
|
ERROR_MSG("Error: invalid charaters in variable name \"%s\", use only charaters [a-z][A-Z][0-9] and '_'\n", szVarName);
|
||||||
return PS_ERROR;
|
return PS_ERROR;
|
||||||
}
|
}
|
||||||
pVarName++;
|
pVarName++;
|
||||||
|
@ -2556,35 +2615,23 @@ int CEXEBuild::DeclaredUserVar(const char *szVarName)
|
||||||
|
|
||||||
int CEXEBuild::GetUserVarIndex(LineParser &line, int token)
|
int CEXEBuild::GetUserVarIndex(LineParser &line, int token)
|
||||||
{
|
{
|
||||||
|
#ifdef NSIS_SUPPORT_NAMED_USERVARS
|
||||||
|
|
||||||
|
char *p = line.gettoken_str(token);
|
||||||
|
if ( *p == '$' && *(p+1) )
|
||||||
|
{
|
||||||
|
int idxUserVar = m_UserVarNames.get((char *)p+1);
|
||||||
|
if ( idxUserVar >= 0 )
|
||||||
|
{
|
||||||
|
return idxUserVar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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"
|
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"
|
"$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";
|
"$CMDLINE\0$INSTDIR\0$OUTDIR\0$EXEDIR\0$LANGUAGE\0";
|
||||||
int res = line.gettoken_enum(token, usrvars);
|
return line.gettoken_enum(token, usrvars);
|
||||||
// Added by ramon 3 jun 2003
|
|
||||||
#ifdef NSIS_SUPPORT_NAMED_USERVARS
|
|
||||||
if ( res < 0 )
|
|
||||||
{
|
|
||||||
char *p = line.gettoken_str(token);
|
|
||||||
if ( *p == '$' && *(p+1) == '[' )
|
|
||||||
{
|
|
||||||
char *pUserVarName = (char *)p+2;
|
|
||||||
while ( *pUserVarName )
|
|
||||||
{
|
|
||||||
if ( *pUserVarName == ']' )
|
|
||||||
{
|
|
||||||
*pUserVarName='\0';
|
|
||||||
int idxUserVar = m_UserVarNames.get((char*)p+2);
|
|
||||||
*pUserVarName=']'; // restore
|
|
||||||
if ( idxUserVar >= 0 )
|
|
||||||
{
|
|
||||||
res=idxUserVar+USER_VARS_COUNT; // User named variable;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pUserVarName++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ using namespace std;
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
#include "ResourceEditor.h"
|
#include "ResourceEditor.h"
|
||||||
#include "ResourceVersionInfo.h"
|
#include "ResourceVersionInfo.h"
|
||||||
|
#include "uservars.h"
|
||||||
|
|
||||||
#include "exehead/fileform.h"
|
#include "exehead/fileform.h"
|
||||||
#include "exehead/config.h"
|
#include "exehead/config.h"
|
||||||
|
@ -173,7 +174,7 @@ class CEXEBuild {
|
||||||
int GetUserVarIndex(LineParser &line, int token);
|
int GetUserVarIndex(LineParser &line, int token);
|
||||||
// Added by ramon 3 jun 2003
|
// Added by ramon 3 jun 2003
|
||||||
#ifdef NSIS_SUPPORT_NAMED_USERVARS
|
#ifdef NSIS_SUPPORT_NAMED_USERVARS
|
||||||
LangStringList m_UserVarNames;
|
UserVarsStringList m_UserVarNames;
|
||||||
int DeclaredUserVar(const char *VarName);
|
int DeclaredUserVar(const char *VarName);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -214,7 +215,6 @@ class CEXEBuild {
|
||||||
// Added by ramon 6 jun 2003
|
// Added by ramon 6 jun 2003
|
||||||
#ifdef NSIS_SUPPORT_VERSION_INFO
|
#ifdef NSIS_SUPPORT_VERSION_INFO
|
||||||
CResourceVersionInfo rVersionInfo;
|
CResourceVersionInfo rVersionInfo;
|
||||||
int version_codePage, version_lang;
|
|
||||||
char version_product_v[1024];
|
char version_product_v[1024];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -515,7 +515,7 @@ DWORD NSISCALL SetSelfFilePointer(LONG lDistanceToMove, DWORD dwMoveMethod);
|
||||||
// $0..$9, $INSTDIR, etc are encoded as ASCII bytes starting from this value.
|
// $0..$9, $INSTDIR, etc are encoded as ASCII bytes starting from this value.
|
||||||
// Added by ramon 3 jun 2003
|
// Added by ramon 3 jun 2003
|
||||||
#ifdef NSIS_SUPPORT_NAMED_USERVARS
|
#ifdef NSIS_SUPPORT_NAMED_USERVARS
|
||||||
#define VAR_CODES_START (256 - 38)
|
#define VAR_CODES_START 250
|
||||||
#else
|
#else
|
||||||
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
|
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
|
||||||
#define VAR_CODES_START (256 - 37)
|
#define VAR_CODES_START (256 - 37)
|
||||||
|
|
|
@ -400,6 +400,7 @@ char * NSISCALL process_string(const char *in)
|
||||||
while (*in && out - ps_tmpbuf < NSIS_MAX_STRLEN)
|
while (*in && out - ps_tmpbuf < NSIS_MAX_STRLEN)
|
||||||
{
|
{
|
||||||
int nVarIdx = (unsigned char)*in++;
|
int nVarIdx = (unsigned char)*in++;
|
||||||
|
#ifndef NSIS_SUPPORT_NAMED_USERVARS
|
||||||
if (nVarIdx < VAR_CODES_START)
|
if (nVarIdx < VAR_CODES_START)
|
||||||
{
|
{
|
||||||
*out++ = nVarIdx;
|
*out++ = nVarIdx;
|
||||||
|
@ -443,24 +444,9 @@ char * NSISCALL process_string(const char *in)
|
||||||
case VAR_CODES_START + 24: // EXEDIR
|
case VAR_CODES_START + 24: // EXEDIR
|
||||||
case VAR_CODES_START + 25: // LANGUAGE
|
case VAR_CODES_START + 25: // LANGUAGE
|
||||||
case VAR_CODES_START + 26: // PLUGINSDIR
|
case VAR_CODES_START + 26: // PLUGINSDIR
|
||||||
#ifdef NSIS_SUPPORT_NAMED_USERVARS
|
|
||||||
case VAR_CODES_START + 36: // NAMED USER VARS
|
|
||||||
{
|
|
||||||
if ( nVarIdx == (VAR_CODES_START + 36) )
|
|
||||||
{
|
|
||||||
//char Buf[200];
|
|
||||||
nVarIdx = *(WORD*)in & 0x0FFF; in+=sizeof(WORD);
|
|
||||||
//wsprintf(Buf, "Request var index %d", nVarIdx);
|
|
||||||
//MessageBox(0,Buf,0,0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
nVarIdx = nVarIdx - (VAR_CODES_START + 1);
|
|
||||||
mystrcpy(out, g_usrvars[nVarIdx]);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
mystrcpy(out, g_usrvars[nVarIdx - (VAR_CODES_START + 1)]);
|
mystrcpy(out, g_usrvars[nVarIdx - (VAR_CODES_START + 1)]);
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
case VAR_CODES_START + 27: // PROGRAMFILES
|
case VAR_CODES_START + 27: // PROGRAMFILES
|
||||||
smwcvesf[41]=0;
|
smwcvesf[41]=0;
|
||||||
myRegGetStr(HKEY_LOCAL_MACHINE, smwcvesf, "ProgramFilesDir", out);
|
myRegGetStr(HKEY_LOCAL_MACHINE, smwcvesf, "ProgramFilesDir", out);
|
||||||
|
@ -522,27 +508,112 @@ char * NSISCALL process_string(const char *in)
|
||||||
GetSystemDirectory(out, NSIS_MAX_STRLEN);
|
GetSystemDirectory(out, NSIS_MAX_STRLEN);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef NSIS_SUPPORT_NAMED_USERVARS
|
|
||||||
#if USER_VARS_COUNT + MAX_NAMED_USER_VARS > 0x0FFF
|
|
||||||
#error "Too many named variables! Decrease MAX_NAMED_USER_VARS"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if VAR_CODES_START + 36 >= 255
|
|
||||||
#error "Too many variables! Extend VAR_CODES_START!"
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#if VAR_CODES_START + 35 >= 255
|
#if VAR_CODES_START + 35 >= 255
|
||||||
#error "Too many variables! Extend VAR_CODES_START!"
|
#error "Too many variables! Extend VAR_CODES_START!"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
} // switch
|
} // switch
|
||||||
// validate the directory name
|
// validate the directory name
|
||||||
if (nVarIdx > 21+VAR_CODES_START && nVarIdx < VAR_CODES_START + 36 ) { // only if not $0 to $R9, $CMDLINE, or $HWNDPARENT
|
if (nVarIdx > 21+VAR_CODES_START ) { // only if not $0 to $R9, $CMDLINE, or $HWNDPARENT
|
||||||
// ($LANGUAGE can't have trailing backslash anyway...)
|
// ($LANGUAGE can't have trailing backslash anyway...)
|
||||||
validate_filename(out);
|
validate_filename(out);
|
||||||
}
|
}
|
||||||
out+=mystrlen(out);
|
out+=mystrlen(out);
|
||||||
} // >= VAR_CODES_START
|
} // >= VAR_CODES_START
|
||||||
|
#else
|
||||||
|
|
||||||
|
if (nVarIdx == 255)
|
||||||
|
{
|
||||||
|
*out++ = *in++;
|
||||||
|
}
|
||||||
|
else if (nVarIdx != VAR_CODES_START)
|
||||||
|
{
|
||||||
|
*out++ = nVarIdx;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DWORD f;
|
||||||
|
static char smwcvesf[]="Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
|
||||||
|
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
|
||||||
|
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
|
||||||
|
{
|
||||||
|
static const char *tab[]={
|
||||||
|
"Programs",
|
||||||
|
"Startup",
|
||||||
|
"Desktop",
|
||||||
|
"Start Menu",
|
||||||
|
"AppData"
|
||||||
|
};
|
||||||
|
static char name[20]="Common ";
|
||||||
|
const char *name_=tab[nVarIdx-27];
|
||||||
|
mystrcpy(name+7,name_);
|
||||||
|
f=g_flags.all_user_var & (nVarIdx != 31);
|
||||||
|
|
||||||
|
again:
|
||||||
|
|
||||||
|
smwcvesf[41]='\\';
|
||||||
|
myRegGetStr(f?HKEY_LOCAL_MACHINE:HKEY_CURRENT_USER,
|
||||||
|
smwcvesf,
|
||||||
|
f?name:name_,out);
|
||||||
|
if (!out[0])
|
||||||
|
{
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
f=0; goto again;
|
||||||
|
}
|
||||||
|
mystrcpy(out,temp_directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nVarIdx == 31) {
|
||||||
|
lstrcat(out, "\\Microsoft\\Internet Explorer\\Quick Launch");
|
||||||
|
f = GetFileAttributes(out);
|
||||||
|
if (f != (DWORD)-1 && (f & FILE_ATTRIBUTE_DIRECTORY))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 32: // TEMP
|
||||||
|
mystrcpy(out,temp_directory);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 33: // WINDIR
|
||||||
|
GetWindowsDirectory(out, NSIS_MAX_STRLEN);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 34: // SYSDIR
|
||||||
|
GetSystemDirectory(out, NSIS_MAX_STRLEN);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 35: // HWNDPARENT
|
||||||
|
myitoa(out, (unsigned int)g_hwnd);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
mystrcpy(out, g_usrvars[nVarIdx]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
} // switch
|
||||||
|
// validate the directory name
|
||||||
|
if (nVarIdx > 21 && nVarIdx < 36 ) { // only if not $0 to $R9, $CMDLINE, or $HWNDPARENT and not great than $SYSDIR
|
||||||
|
// ($LANGUAGE can't have trailing backslash anyway...)
|
||||||
|
validate_filename(out);
|
||||||
|
}
|
||||||
|
out+=mystrlen(out);
|
||||||
|
} // == VAR_CODES_START
|
||||||
|
#endif
|
||||||
} // while
|
} // while
|
||||||
*out = 0;
|
*out = 0;
|
||||||
return ps_tmpbuf;
|
return ps_tmpbuf;
|
||||||
|
|
|
@ -69,8 +69,8 @@ LINK32=link.exe
|
||||||
# PROP Target_Dir ""
|
# 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
|
# 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
|
# 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" /FD /c
|
# 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 /Fr /YX /Yc /Yu
|
# SUBTRACT CPP /YX /Yc /Yu
|
||||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||||
BSC32=bscmake.exe
|
BSC32=bscmake.exe
|
||||||
|
@ -260,6 +260,10 @@ SOURCE=.\tokens.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\uservars.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\util.h
|
SOURCE=.\util.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
|
|
|
@ -1968,8 +1968,15 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
|
||||||
uDefCodePage = newNLF->m_uCodePage;
|
uDefCodePage = newNLF->m_uCodePage;
|
||||||
}
|
}
|
||||||
build_nlfs.push_back(newNLF);
|
build_nlfs.push_back(newNLF);
|
||||||
LANGID lang = newNLF->m_wLangId;
|
StringTable * Table = GetTable(newNLF->m_wLangId);
|
||||||
GetTable(lang);
|
|
||||||
|
for (i = 0; i < build_nlfs.size(); i++) {
|
||||||
|
if (build_nlfs[i]->m_wLangId == Table->lang_id) {
|
||||||
|
Table->nlf = build_nlfs[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
last_used_lang = newNLF->m_wLangId;
|
last_used_lang = newNLF->m_wLangId;
|
||||||
// define LANG_LangName as "####" (lang id)
|
// define LANG_LangName as "####" (lang id)
|
||||||
// for example ${LANG_ENGLISH} = 1033
|
// for example ${LANG_ENGLISH} = 1033
|
||||||
|
@ -4391,8 +4398,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
|
||||||
#ifdef NSIS_SUPPORT_VERSION_INFO
|
#ifdef NSIS_SUPPORT_VERSION_INFO
|
||||||
case TOK_VI_ADDKEY:
|
case TOK_VI_ADDKEY:
|
||||||
{
|
{
|
||||||
char *pKey = line.gettoken_str(1);
|
LANGID LangID = line.gettoken_int(1);
|
||||||
char *pValue = line.gettoken_str(2);
|
char *pKey = line.gettoken_str(2);
|
||||||
|
char *pValue = line.gettoken_str(3);
|
||||||
if ( !(*pKey) )
|
if ( !(*pKey) )
|
||||||
{
|
{
|
||||||
ERROR_MSG("Error: empty name for version info key!\n");
|
ERROR_MSG("Error: empty name for version info key!\n");
|
||||||
|
@ -4400,64 +4408,27 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SCRIPT_MSG("%s = \"%s\"=\"%s\" \n",line.gettoken_str(0), line.gettoken_str(1), line.gettoken_str(2));
|
SCRIPT_MSG("%s: \"%s\" \"%s\" \"%s\"\n", line.gettoken_str(0), line.gettoken_str(1), line.gettoken_str(2), line.gettoken_str(3));
|
||||||
rVersionInfo.SetKeyValue(pKey, pValue);
|
StringTable *strTable = GetTable(LangID);
|
||||||
return PS_OK;
|
if ( line.gettoken_int(1) == 0 && !strTable->nlf )
|
||||||
}
|
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) )
|
||||||
case TOK_VI_ADDTRANSLATION:
|
{
|
||||||
{
|
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" : "???");
|
||||||
int s1, s2;
|
return PS_ERROR;
|
||||||
int language = line.gettoken_int(1, &s1);
|
}
|
||||||
int codepage = line.gettoken_int(2, &s2);
|
|
||||||
if ( !s1 || !s2 )
|
|
||||||
PRINTHELP()
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( !rVersionInfo.IsValidCodePage(codepage) )
|
|
||||||
{
|
|
||||||
ERROR_MSG("Error: invalid codepage id %d!\n", codepage);
|
|
||||||
return PS_ERROR;
|
|
||||||
}
|
|
||||||
if ( !IsValidLocale(language, LCID_SUPPORTED) )
|
|
||||||
{
|
|
||||||
ERROR_MSG("Error: invalid language id %d!\n", language);
|
|
||||||
return PS_ERROR;
|
|
||||||
}
|
|
||||||
rVersionInfo.AddTranslation(codepage, language);
|
|
||||||
return PS_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return make_sure_not_in_secorfunc(line.gettoken_str(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
case TOK_VI_SETPRODUCTVERSION:
|
case TOK_VI_SETPRODUCTVERSION:
|
||||||
strcpy(version_product_v, line.gettoken_str(1));
|
if ( version_product_v[0] )
|
||||||
return PS_OK;
|
|
||||||
|
|
||||||
case TOK_VI_SETVERSIONLANGUAGE:
|
|
||||||
{
|
|
||||||
int s1, s2;
|
|
||||||
int language = line.gettoken_int(1, &s1);
|
|
||||||
int codepage = line.gettoken_int(2, &s2);
|
|
||||||
if ( !s1 || !s2 )
|
|
||||||
PRINTHELP()
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if ( !rVersionInfo.IsValidCodePage(codepage) )
|
ERROR_MSG("Error: %s already defined!\n", line.gettoken_str(0));
|
||||||
{
|
|
||||||
ERROR_MSG("Error: invalid codepage id %d!\n", codepage);
|
|
||||||
return PS_ERROR;
|
return PS_ERROR;
|
||||||
}
|
|
||||||
if ( !IsValidLocale(language, LCID_SUPPORTED) )
|
|
||||||
{
|
|
||||||
ERROR_MSG("Error: invalid language id %d!\n", language);
|
|
||||||
return PS_ERROR;
|
|
||||||
}
|
|
||||||
char Buf[10];
|
|
||||||
sprintf(Buf, "%04x%04x", language, codepage);
|
|
||||||
rVersionInfo.SetVersionInfoLang(Buf);
|
|
||||||
return PS_OK;
|
|
||||||
}
|
}
|
||||||
}
|
strcpy(version_product_v, line.gettoken_str(1));
|
||||||
|
return make_sure_not_in_secorfunc(line.gettoken_str(0));
|
||||||
|
|
||||||
#else
|
#else
|
||||||
case TOK_VI_ADDKEY:
|
case TOK_VI_ADDKEY:
|
||||||
|
|
|
@ -278,7 +278,7 @@ class SortedStringListND // no delete - can be placed in GrowBuf
|
||||||
{
|
{
|
||||||
int where;
|
int where;
|
||||||
T newstruct={0,};
|
T newstruct={0,};
|
||||||
int pos=find(name,case_sensitive,1,&where);
|
int pos=find(name,-1,case_sensitive,1,&where);
|
||||||
if (pos==-1) return alwaysreturnpos ? where : -1;
|
if (pos==-1) return alwaysreturnpos ? where : -1;
|
||||||
newstruct.name=strings.add(name,strlen(name)+1);
|
newstruct.name=strings.add(name,strlen(name)+1);
|
||||||
|
|
||||||
|
@ -292,7 +292,8 @@ class SortedStringListND // no delete - can be placed in GrowBuf
|
||||||
|
|
||||||
// returns -1 if not found, position if found
|
// returns -1 if not found, position if found
|
||||||
// if returnbestpos=1 returns -1 if found, best pos to insert if not found
|
// if returnbestpos=1 returns -1 if found, best pos to insert if not found
|
||||||
int find(const char *str, int case_sensitive=0, int returnbestpos=0, int *where=0)
|
// if n_chars equal to -1 all string is tested
|
||||||
|
int find(const char *str, size_t n_chars=-1, int case_sensitive=0, int returnbestpos=0, int *where=0)
|
||||||
{
|
{
|
||||||
T *data=(T *)gr.get();
|
T *data=(T *)gr.get();
|
||||||
int ul=gr.getlen()/sizeof(T);
|
int ul=gr.getlen()/sizeof(T);
|
||||||
|
@ -302,10 +303,22 @@ class SortedStringListND // no delete - can be placed in GrowBuf
|
||||||
while (ul > ll)
|
while (ul > ll)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
if (case_sensitive)
|
const char *pCurr = (char*)strings.get() + data[nextpos].name;
|
||||||
res=strcmp(str, (char*)strings.get() + data[nextpos].name);
|
if (n_chars == -1 || n_chars != strlen(pCurr) )
|
||||||
|
{
|
||||||
|
if (case_sensitive)
|
||||||
|
res=strcmp(str, pCurr);
|
||||||
|
else
|
||||||
|
res=stricmp(str, pCurr);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
res=stricmp(str, (char*)strings.get() + data[nextpos].name);
|
{
|
||||||
|
if (case_sensitive)
|
||||||
|
res=strncmp(str, pCurr, n_chars);
|
||||||
|
else
|
||||||
|
res=strnicmp(str, pCurr, n_chars);
|
||||||
|
}
|
||||||
|
|
||||||
if (res==0)
|
if (res==0)
|
||||||
{
|
{
|
||||||
if (where) *where = nextpos;
|
if (where) *where = nextpos;
|
||||||
|
|
|
@ -230,9 +230,7 @@ static tokenType tokenlist[TOK__LAST] =
|
||||||
// Added by ramon 3 jun 2003
|
// Added by ramon 3 jun 2003
|
||||||
{TOK_DEFVAR,"dim",1,0,"VarName"},
|
{TOK_DEFVAR,"dim",1,0,"VarName"},
|
||||||
// Added by ramon 6 jun 2003
|
// Added by ramon 6 jun 2003
|
||||||
{TOK_VI_ADDKEY,"VIAddVersionKey", 2, 0, "[keyname] [value]"},
|
{TOK_VI_ADDKEY,"VIAddVersionKey", 3, 0, "lang_id keyname value"},
|
||||||
{TOK_VI_ADDTRANSLATION,"VIAddTranslation", 2, 0, "[short language id] [short codepage id]"},
|
|
||||||
{TOK_VI_SETVERSIONLANGUAGE,"VISetVersionLanguage", 2, 0, "[short language id] [short codepage id]"},
|
|
||||||
{TOK_VI_SETPRODUCTVERSION,"VIProductVersion", 1, 0, "[version string X.X.X.X]"},
|
{TOK_VI_SETPRODUCTVERSION,"VIProductVersion", 1, 0, "[version string X.X.X.X]"},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -217,9 +217,7 @@ enum
|
||||||
// Added by ramon 3 jun 2003
|
// Added by ramon 3 jun 2003
|
||||||
TOK_DEFVAR,
|
TOK_DEFVAR,
|
||||||
TOK_VI_ADDKEY,
|
TOK_VI_ADDKEY,
|
||||||
TOK_VI_ADDTRANSLATION,
|
|
||||||
TOK_VI_SETPRODUCTVERSION,
|
TOK_VI_SETPRODUCTVERSION,
|
||||||
TOK_VI_SETVERSIONLANGUAGE,
|
|
||||||
|
|
||||||
TOK__LAST,
|
TOK__LAST,
|
||||||
TOK__PLUGINCOMMAND
|
TOK__PLUGINCOMMAND
|
||||||
|
|
27
Source/uservars.h
Normal file
27
Source/uservars.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// uservars.h by Ramon 10 Jun 2003
|
||||||
|
|
||||||
|
#ifndef ___USERVARS___H_____
|
||||||
|
#define ___USERVARS___H_____
|
||||||
|
|
||||||
|
#ifdef NSIS_SUPPORT_NAMED_USERVARS
|
||||||
|
|
||||||
|
#include "Lang.h"
|
||||||
|
|
||||||
|
class UserVarsStringList : public LangStringList
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UserVarsStringList()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
~UserVarsStringList() { }
|
||||||
|
|
||||||
|
int get(char *name, size_t n_chars = -1)
|
||||||
|
{
|
||||||
|
int v=SortedStringListND<struct langstring>::find(name, n_chars);
|
||||||
|
if (v==-1) return -1;
|
||||||
|
return (((struct langstring*)gr.get())[v].index);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif //NSIS_SUPPORT_NAMED_USERVARS
|
||||||
|
|
||||||
|
#endif
|
Loading…
Add table
Add a link
Reference in a new issue