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 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

View file

@ -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);

View file

@ -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

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[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);