From 8f65eb3c234909cbf0ea184c21f2023ddeebfe23 Mon Sep 17 00:00:00 2001 From: anders_k Date: Sat, 21 Nov 2015 13:12:40 +0000 Subject: [PATCH] CreateShortcut icon index can now be larger than 255 (Bug #1123) git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6638 212acab6-be3b-0410-9dea-997c60f758d6 --- Docs/src/history.but | 2 ++ Source/exehead/exec.c | 12 +++++++----- Source/exehead/fileform.h | 11 +++++++++++ Source/script.cpp | 34 ++++++++++++++-------------------- 4 files changed, 34 insertions(+), 25 deletions(-) diff --git a/Docs/src/history.but b/Docs/src/history.but index 20ba5da9..5a767f2c 100644 --- a/Docs/src/history.but +++ b/Docs/src/history.but @@ -20,6 +20,8 @@ Released on ? ?th, 201? \b FileWriteUTF16LE can add a BOM with the /BOM switch +\b CreateShortcut icon index can now be larger than 255 (\W{http://sf.net/p/nsis/bugs/1123/}{bug #1123}) + \b !system and !execute now provide a empty StdIn pipe to work around bugs in some Windows utilities \b Added support for 0o octal radix prefix on number literals in the preprocessor diff --git a/Source/exehead/exec.c b/Source/exehead/exec.c index 459cf354..3487ded0 100644 --- a/Source/exehead/exec.c +++ b/Source/exehead/exec.c @@ -1049,6 +1049,8 @@ static int NSISCALL ExecuteEntry(entry *entry_) TCHAR *buf0=GetStringFromParm(0x02); TCHAR *buf3=GetStringFromParm(-0x33); TCHAR *buf4=GetStringFromParm(0x45); + const int icoi = (parm4>>CS_II_SHIFT)&(CS_II_MASK>>CS_II_SHIFT), nwd = parm4&CS_NWD, + sc = (parm4>>CS_SC_SHIFT)&(CS_SC_MASK>>CS_SC_SHIFT), hk = (parm4>>CS_HK_SHIFT)&(CS_HK_MASK>>CS_HK_SHIFT); HRESULT hres; IShellLink* psl; @@ -1057,7 +1059,7 @@ static int NSISCALL ExecuteEntry(entry *entry_) GetStringFromParm(0x21); log_printf8(_T("CreateShortcut: out: \"%s\", in: \"%s %s\", icon: %s,%d, sw=%d, hk=%d"), - buf1,buf2,buf0,buf3,parm4&0xff,(parm4&0xff00)>>8,parm4>>16); + buf1,buf2,buf0,buf3,icoi,sc,hk); hres = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLink, (void **) &psl); @@ -1069,10 +1071,10 @@ static int NSISCALL ExecuteEntry(entry *entry_) if (SUCCEEDED(hres)) { hres = psl->lpVtbl->SetPath(psl,buf2); - if (!(parm4&0x8000)) psl->lpVtbl->SetWorkingDirectory(psl,state_output_directory); - if ((parm4&0x7f00)>>8) psl->lpVtbl->SetShowCmd(psl,(parm4&0x7f00)>>8); - psl->lpVtbl->SetHotkey(psl,(unsigned short)(parm4>>16)); - if (buf3[0]) psl->lpVtbl->SetIconLocation(psl,buf3,parm4&0xff); + if (!nwd) psl->lpVtbl->SetWorkingDirectory(psl,state_output_directory); + if (sc) psl->lpVtbl->SetShowCmd(psl,sc); + psl->lpVtbl->SetHotkey(psl,(unsigned short) hk); + if (buf3[0]) psl->lpVtbl->SetIconLocation(psl,buf3,icoi); psl->lpVtbl->SetArguments(psl,buf0); psl->lpVtbl->SetDescription(psl,buf4); diff --git a/Source/exehead/fileform.h b/Source/exehead/fileform.h index 792e49cd..19630ac4 100644 --- a/Source/exehead/fileform.h +++ b/Source/exehead/fileform.h @@ -510,6 +510,17 @@ typedef struct { #define DEL_REBOOT 4 #define DEL_SIMPLE 8 +#ifdef NSIS_SUPPORT_CREATESHORTCUT +#define CS_HK_MASK 0xffff0000 // HotKey +#define CS_HK_SHIFT 16 +#define CS_NWD 0x00008000 // NoWorkingDirectory flag +#define CS_SC_MASK 0x00007000 // ShowCmd +#define CS_SC_SHIFT 12 +#define CS_II_MASK 0x00000fff // IconIndex +#define CS_II_SHIFT 0 +#define CS_II_MAX (CS_II_MASK >> CS_II_SHIFT) +#endif + // 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 diff --git a/Source/script.cpp b/Source/script.cpp index 0e311696..273506c1 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -4288,27 +4288,26 @@ 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[5]=add_string(line.gettoken_str(8)); - ent.offsets[4]=line.gettoken_int(5,&s)&0xff; - if (!s) + ent.offsets[4]=(line.gettoken_int(5,&s) << CS_II_SHIFT) & CS_II_MASK; + if (!s || ent.offsets[4] < 0 || ent.offsets[4] > CS_II_MAX) { if (line.getnumtokens() > 5 && *line.gettoken_str(5)) { ERROR_MSG(_T("CreateShortcut: cannot interpret icon index\n")); PRINTHELPEX(cmdnam) } - ent.offsets[4]=0; } - if (noLnkWorkDir) ent.offsets[4] |= 0x8000; + if (noLnkWorkDir) ent.offsets[4] |= CS_NWD; if (line.getnumtokens() > 6 && *line.gettoken_str(6)) { - int tab[3]={SW_SHOWNORMAL,SW_SHOWMAXIMIZED,SW_SHOWMINNOACTIVE/*SW_SHOWMINIMIZED doesn't work*/}; + const int tab[3]={SW_SHOWNORMAL,SW_SHOWMAXIMIZED,SW_SHOWMINNOACTIVE/*SW_SHOWMINIMIZED doesn't work*/}; int a=line.gettoken_enum(6,_T("SW_SHOWNORMAL\0SW_SHOWMAXIMIZED\0SW_SHOWMINIMIZED\0")); - if (a < 0) + if (a < 0 || (tab[a] << CS_SC_SHIFT) & ~CS_SC_MASK) { ERROR_MSG(_T("CreateShortcut: unknown show mode \"%") NPRIs _T("\"\n"),line.gettoken_str(6)); PRINTHELPEX(cmdnam) } - ent.offsets[4] |= tab[a]<<8; + ent.offsets[4] |= tab[a] << CS_SC_SHIFT; } if (line.getnumtokens() > 7) { @@ -4316,25 +4315,20 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) for (unsigned int spos=0; (spos <= _tcslen(s)) && (spos <= 255); spos++) b[spos]=_totupper(*(s+spos)); _tcscpy(s,b); - if (*s) { int c=0; - if (_tcsstr(s,_T("ALT|"))) ent.offsets[4]|=HOTKEYF_ALT << 24; - if (_tcsstr(s,_T("CONTROL|"))) ent.offsets[4]|=HOTKEYF_CONTROL << 24; - if (_tcsstr(s,_T("EXT|"))) ent.offsets[4]|=HOTKEYF_EXT << 24; - if (_tcsstr(s,_T("SHIFT|"))) ent.offsets[4]|=HOTKEYF_SHIFT << 24; + if (_tcsstr(s,_T("ALT|"))) ent.offsets[4] |= HOTKEYF_ALT << (CS_HK_SHIFT+8); + if (_tcsstr(s,_T("CONTROL|"))) ent.offsets[4] |= HOTKEYF_CONTROL << (CS_HK_SHIFT+8); + if (_tcsstr(s,_T("EXT|"))) ent.offsets[4] |= HOTKEYF_EXT << (CS_HK_SHIFT+8); + if (_tcsstr(s,_T("SHIFT|"))) ent.offsets[4] |= HOTKEYF_SHIFT << (CS_HK_SHIFT+8); while (_tcsstr(s,_T("|"))) - { s=_tcsstr(s,_T("|"))+1; - } if ((s[0] == _T('F')) && (s[1] >= _T('1') && s[1] <= _T('9'))) { c=VK_F1-1+_ttoi(s+1); if (_ttoi(s+1) < 1 || _ttoi(s+1) > 24) - { warning_fl(_T("CreateShortcut: F-key \"%") NPRIs _T("\" out of range"),s); - } } else if (((s[0] >= _T('A') && s[0] <= _T('Z')) || (s[0] >= _T('0') && s[0] <= _T('9'))) && !s[1]) c=s[0]; @@ -4343,12 +4337,12 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) c=s[0]; warning_fl(_T("CreateShortcut: unrecognized hotkey \"%") NPRIs _T("\""),s); } - ent.offsets[4] |= (c) << 16; + ent.offsets[4] |= ((c) << CS_HK_SHIFT) & CS_HK_MASK; } } - SCRIPT_MSG(_T("CreateShortcut: \"%") NPRIs _T("\"->\"%") NPRIs _T("\" %") NPRIs _T(" icon:%") NPRIs _T(",%d, showmode=0x%X, hotkey=0x%X, comment=%") NPRIs _T("\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)); + SCRIPT_MSG(_T("CreateShortcut: \"%") NPRIs _T("\"->\"%") NPRIs _T("\" %") NPRIs _T(" icon:%") NPRIs _T(",%d, nwd=%d, showmode=0x%X, hotkey=0x%X, comment=%") NPRIs _T("\n"), + line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4),(ent.offsets[4]>>CS_II_SHIFT)&(CS_II_MASK>>CS_II_SHIFT),!!(ent.offsets[4]&CS_NWD), + (ent.offsets[4]>>CS_SC_SHIFT)&(CS_SC_MASK>>CS_SC_SHIFT),(ent.offsets[4]>>CS_HK_SHIFT)&(CS_HK_MASK>>CS_HK_SHIFT),line.gettoken_str(8)); DefineInnerLangString(NLF_CREATE_SHORTCUT); DefineInnerLangString(NLF_ERR_CREATING_SHORTCUT);