From 637db8940ca19632d2fab3c8fad60c716ae537c7 Mon Sep 17 00:00:00 2001 From: wizou Date: Wed, 14 Apr 2010 16:02:51 +0000 Subject: [PATCH] Unicode port: fixing special NSIS escape characters in strings. No change in exehead size. git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6055 212acab6-be3b-0410-9dea-997c60f758d6 --- Source/ResourceVersionInfo.cpp | 5 ----- Source/ResourceVersionInfo.h | 5 ----- Source/build.cpp | 4 ++++ Source/exehead/Main.c | 2 +- Source/exehead/fileform.h | 27 ++++++++++++++++----------- Source/exehead/util.c | 10 +++++++++- Source/strlist.h | 6 ------ 7 files changed, 30 insertions(+), 29 deletions(-) diff --git a/Source/ResourceVersionInfo.cpp b/Source/ResourceVersionInfo.cpp index 68fed4d8..815c57ab 100644 --- a/Source/ResourceVersionInfo.cpp +++ b/Source/ResourceVersionInfo.cpp @@ -93,11 +93,6 @@ int CVersionStrigList::find(LANGID lang_id, int codepage) return SortedStringListND::find(Buff); } -int CVersionStrigList::getlen() -{ - return m_strings.getlen(); -} - int CVersionStrigList::getnum() { return m_gr.getlen()/sizeof(struct version_string_list); diff --git a/Source/ResourceVersionInfo.h b/Source/ResourceVersionInfo.h index 6937ec7a..cdcedbc5 100644 --- a/Source/ResourceVersionInfo.h +++ b/Source/ResourceVersionInfo.h @@ -67,11 +67,6 @@ public: */ int find(LANGID lang_id, int codepage); - /** - * Get the length of the buffer of strings in count of TCHARs. - */ - int getlen(); - /** * Get the number of version_string_list objects stored in this list. */ diff --git a/Source/build.cpp b/Source/build.cpp index d47a812b..4d76f052 100644 --- a/Source/build.cpp +++ b/Source/build.cpp @@ -582,8 +582,12 @@ int CEXEBuild::preprocess_string(TCHAR *out, const TCHAR *in, WORD codepage/*=CP int CSIDL_Value_current = m_ShellConstants.get_value1(idxConst); int CSIDL_Value_all = m_ShellConstants.get_value2(idxConst); *out++=(TCHAR)NS_SHELL_CODE; // Constant code identifier +#ifdef _UNICODE + *out++=MAKEWORD(CSIDL_Value_current, CSIDL_Value_all); +#else *out++=(TCHAR)CSIDL_Value_current; *out++=(TCHAR)CSIDL_Value_all; +#endif p = pShellConstName; // zip past the shell constant string. bProceced = true; break; diff --git a/Source/exehead/Main.c b/Source/exehead/Main.c index d488a54e..5a18eed2 100644 --- a/Source/exehead/Main.c +++ b/Source/exehead/Main.c @@ -159,7 +159,7 @@ int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,LPTSTR lpszCmdPara if (CMP4CHAR(cmdline-2, _T(" /D="))) { - *(LPDWORD)(cmdline-2)=0; // keep this from being passed to uninstaller if necessary + *(cmdline-2)=_T('\0'); // keep this from being passed to uninstaller if necessary mystrcpy(state_install_directory,cmdline+2); break; // /D= must always be last } diff --git a/Source/exehead/fileform.h b/Source/exehead/fileform.h index 75d810a6..ffb5fa45 100644 --- a/Source/exehead/fileform.h +++ b/Source/exehead/fileform.h @@ -475,21 +475,26 @@ typedef struct { #define DEL_REBOOT 4 #define DEL_SIMPLE 8 -// $0..$9, $INSTDIR, etc are encoded as ASCII bytes starting from this value. -// Added by ramon 3 jun 2003 -#define NS_SKIP_CODE 252 -#define NS_VAR_CODE 253 -#define NS_SHELL_CODE 254 -#define NS_LANG_CODE 255 -#define NS_CODES_START NS_SKIP_CODE -#define NS_IS_CODE(x) ((x) >= NS_SKIP_CODE) +// special escape characters used in strings: (we use control codes in order to minimize conflicts with normal characters) +#define NS_LANG_CODE _T('\x01') // for a langstring +#define NS_SHELL_CODE _T('\x02') // for a shell folder path +#define NS_VAR_CODE _T('\x03') // for a variable +#define NS_SKIP_CODE _T('\x04') // to consider next character as a normal character +#define NS_IS_CODE(x) ((x) <= NS_SKIP_CODE) // NS_SKIP_CODE must always be the higher code // We are doing this to store an integer value into a char string and we -// don't want false end of string values so we shift then OR with 0x8080 +// don't want false end of string values +#if _UNICODE +#define CODE_SHORT(x) ((WORD)x + 1) +#define MAX_CODED 0xFFFE +// This macro takes a pointer to WCHAR +#define DECODE_SHORT(c) (c[0]-1) +#else #define CODE_SHORT(x) (WORD)((((WORD)(x) & 0x7F) | (((WORD)(x) & 0x3F80) << 1) | 0x8080)) -#define MAX_CODED 16383 // 0x3FFF -// This macro takes a pointer to char +#define MAX_CODED 0x3FFF +// This macro takes a pointer to CHAR #define DECODE_SHORT(c) (((c[1] & 0x7F) << 7) | (c[0] & 0x7F)) +#endif #define NSIS_INSTDIR_INVALID 1 #define NSIS_INSTDIR_NOT_ENOUGH_SPACE 2 diff --git a/Source/exehead/util.c b/Source/exehead/util.c index cc1b98f7..3d786635 100644 --- a/Source/exehead/util.c +++ b/Source/exehead/util.c @@ -662,14 +662,21 @@ TCHAR * NSISCALL GetNSISString(TCHAR *outbuf, int strtab) _TUCHAR nVarIdx = (_TUCHAR)*in++; int nData; int fldrs[4]; - if (nVarIdx > NS_CODES_START) + if (nVarIdx < NS_SKIP_CODE) { // the next 2 BYTEs in the string might be coding either a value 0..MAX_CODED (nData), or 2 CSIDL of Special folders (for NS_SHELL_CODE) nData = DECODE_SHORT(in); +#ifdef _UNICODE + fldrs[1] = LOBYTE(*in); // current user + fldrs[0] = fldrs[1] | CSIDL_FLAG_CREATE; + fldrs[3] = HIBYTE(*in); // all users + fldrs[2] = fldrs[3] | CSIDL_FLAG_CREATE; +#else fldrs[0] = in[0] | CSIDL_FLAG_CREATE; // current user fldrs[1] = in[0]; fldrs[2] = in[1] | CSIDL_FLAG_CREATE; // all users fldrs[3] = in[1]; +#endif //TODO: are fldrs[1] and fldrs[3] really useful? why not force folder creation directly? in += sizeof(SHORT)/sizeof(TCHAR); @@ -828,6 +835,7 @@ void NSISCALL validate_filename(TCHAR *in) { in = CharNext(in); } *out = 0; + // now trim rightmost backslashes & spaces do { out = CharPrev(out_save, out); diff --git a/Source/strlist.h b/Source/strlist.h index f8d46ef1..8c6718b7 100644 --- a/Source/strlist.h +++ b/Source/strlist.h @@ -121,9 +121,6 @@ private: * is assumed to be a string (TCHAR*). So it's really sort of a * map where X is whatever else is defined in T. But T must define * a TCHAR* name. - * - * The T struct should have the 'name' as the first element in its list of - * members. Otherwise, all kinds of bad things will happen. */ template class SortedStringList @@ -262,9 +259,6 @@ class SortedStringList * map where X is whatever else is defined in T. But T must define * a int name. * - * The T struct should have the 'name' as the first element in its list of - * members. Otherwise, all kinds of bad things will happen. - * * This version does not have a delete function, hence the ND designation. * Also, because nothing is malloc'ed and free'd, this structure can be * placed in a single flat buffer. (Of course, T itself can be holding