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
This commit is contained in:
anders_k 2015-11-21 13:12:40 +00:00
parent b519aae63b
commit 8f65eb3c23
4 changed files with 34 additions and 25 deletions

View file

@ -20,6 +20,8 @@ Released on ? ?th, 201?
\b FileWriteUTF16LE can add a BOM with the /BOM switch \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 !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 \b Added support for 0o octal radix prefix on number literals in the preprocessor

View file

@ -1049,6 +1049,8 @@ static int NSISCALL ExecuteEntry(entry *entry_)
TCHAR *buf0=GetStringFromParm(0x02); TCHAR *buf0=GetStringFromParm(0x02);
TCHAR *buf3=GetStringFromParm(-0x33); TCHAR *buf3=GetStringFromParm(-0x33);
TCHAR *buf4=GetStringFromParm(0x45); 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; HRESULT hres;
IShellLink* psl; IShellLink* psl;
@ -1057,7 +1059,7 @@ static int NSISCALL ExecuteEntry(entry *entry_)
GetStringFromParm(0x21); GetStringFromParm(0x21);
log_printf8(_T("CreateShortcut: out: \"%s\", in: \"%s %s\", icon: %s,%d, sw=%d, hk=%d"), 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, hres = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
&IID_IShellLink, (void **) &psl); &IID_IShellLink, (void **) &psl);
@ -1069,10 +1071,10 @@ static int NSISCALL ExecuteEntry(entry *entry_)
if (SUCCEEDED(hres)) if (SUCCEEDED(hres))
{ {
hres = psl->lpVtbl->SetPath(psl,buf2); hres = psl->lpVtbl->SetPath(psl,buf2);
if (!(parm4&0x8000)) psl->lpVtbl->SetWorkingDirectory(psl,state_output_directory); if (!nwd) psl->lpVtbl->SetWorkingDirectory(psl,state_output_directory);
if ((parm4&0x7f00)>>8) psl->lpVtbl->SetShowCmd(psl,(parm4&0x7f00)>>8); if (sc) psl->lpVtbl->SetShowCmd(psl,sc);
psl->lpVtbl->SetHotkey(psl,(unsigned short)(parm4>>16)); psl->lpVtbl->SetHotkey(psl,(unsigned short) hk);
if (buf3[0]) psl->lpVtbl->SetIconLocation(psl,buf3,parm4&0xff); if (buf3[0]) psl->lpVtbl->SetIconLocation(psl,buf3,icoi);
psl->lpVtbl->SetArguments(psl,buf0); psl->lpVtbl->SetArguments(psl,buf0);
psl->lpVtbl->SetDescription(psl,buf4); psl->lpVtbl->SetDescription(psl,buf4);

View file

@ -510,6 +510,17 @@ typedef struct {
#define DEL_REBOOT 4 #define DEL_REBOOT 4
#define DEL_SIMPLE 8 #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) // 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_LANG_CODE _T('\x01') // for a langstring
#define NS_SHELL_CODE _T('\x02') // for a shell folder path #define NS_SHELL_CODE _T('\x02') // for a shell folder path

View file

@ -4288,27 +4288,26 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
ent.offsets[2]=add_string(line.gettoken_str(3)); ent.offsets[2]=add_string(line.gettoken_str(3));
ent.offsets[3]=add_string(line.gettoken_str(4)); ent.offsets[3]=add_string(line.gettoken_str(4));
ent.offsets[5]=add_string(line.gettoken_str(8)); ent.offsets[5]=add_string(line.gettoken_str(8));
ent.offsets[4]=line.gettoken_int(5,&s)&0xff; ent.offsets[4]=(line.gettoken_int(5,&s) << CS_II_SHIFT) & CS_II_MASK;
if (!s) if (!s || ent.offsets[4] < 0 || ent.offsets[4] > CS_II_MAX)
{ {
if (line.getnumtokens() > 5 && *line.gettoken_str(5)) if (line.getnumtokens() > 5 && *line.gettoken_str(5))
{ {
ERROR_MSG(_T("CreateShortcut: cannot interpret icon index\n")); ERROR_MSG(_T("CreateShortcut: cannot interpret icon index\n"));
PRINTHELPEX(cmdnam) 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)) 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")); 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)); ERROR_MSG(_T("CreateShortcut: unknown show mode \"%") NPRIs _T("\"\n"),line.gettoken_str(6));
PRINTHELPEX(cmdnam) PRINTHELPEX(cmdnam)
} }
ent.offsets[4] |= tab[a]<<8; ent.offsets[4] |= tab[a] << CS_SC_SHIFT;
} }
if (line.getnumtokens() > 7) 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++) for (unsigned int spos=0; (spos <= _tcslen(s)) && (spos <= 255); spos++)
b[spos]=_totupper(*(s+spos)); b[spos]=_totupper(*(s+spos));
_tcscpy(s,b); _tcscpy(s,b);
if (*s) if (*s)
{ {
int c=0; int c=0;
if (_tcsstr(s,_T("ALT|"))) ent.offsets[4]|=HOTKEYF_ALT << 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 << 24; if (_tcsstr(s,_T("CONTROL|"))) ent.offsets[4] |= HOTKEYF_CONTROL << (CS_HK_SHIFT+8);
if (_tcsstr(s,_T("EXT|"))) ent.offsets[4]|=HOTKEYF_EXT << 24; if (_tcsstr(s,_T("EXT|"))) ent.offsets[4] |= HOTKEYF_EXT << (CS_HK_SHIFT+8);
if (_tcsstr(s,_T("SHIFT|"))) ent.offsets[4]|=HOTKEYF_SHIFT << 24; if (_tcsstr(s,_T("SHIFT|"))) ent.offsets[4] |= HOTKEYF_SHIFT << (CS_HK_SHIFT+8);
while (_tcsstr(s,_T("|"))) while (_tcsstr(s,_T("|")))
{
s=_tcsstr(s,_T("|"))+1; s=_tcsstr(s,_T("|"))+1;
}
if ((s[0] == _T('F')) && (s[1] >= _T('1') && s[1] <= _T('9'))) if ((s[0] == _T('F')) && (s[1] >= _T('1') && s[1] <= _T('9')))
{ {
c=VK_F1-1+_ttoi(s+1); c=VK_F1-1+_ttoi(s+1);
if (_ttoi(s+1) < 1 || _ttoi(s+1) > 24) if (_ttoi(s+1) < 1 || _ttoi(s+1) > 24)
{
warning_fl(_T("CreateShortcut: F-key \"%") NPRIs _T("\" out of range"),s); 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]) else if (((s[0] >= _T('A') && s[0] <= _T('Z')) || (s[0] >= _T('0') && s[0] <= _T('9'))) && !s[1])
c=s[0]; c=s[0];
@ -4343,12 +4337,12 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
c=s[0]; c=s[0];
warning_fl(_T("CreateShortcut: unrecognized hotkey \"%") NPRIs _T("\""),s); 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"), 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(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),
line.gettoken_str(4),ent.offsets[4]&0xff,(ent.offsets[4]>>8)&0xff,ent.offsets[4]>>16,line.gettoken_str(8)); (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_CREATE_SHORTCUT);
DefineInnerLangString(NLF_ERR_CREATING_SHORTCUT); DefineInnerLangString(NLF_ERR_CREATING_SHORTCUT);