Added basic WriteRegMultiStr support (RFE #382, patch #219)

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6829 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2016-12-29 21:59:35 +00:00
parent aee38bfa77
commit 859c2ad6eb
9 changed files with 62 additions and 33 deletions

View file

@ -6,6 +6,10 @@ Released on ? ?th, 2017
\S1{v3.02-cl} Changelog
\S2{} Major Changes
\b Added \R{writeregmultistr}{WriteRegMultiStr} (\W{http://sf.net/p/nsis/feature-requests/382}{RFE #382}, \W{http://sf.net/p/nsis/patches/219}{patch #219})
\S2{} Minor Changes
\b MultiUser now supports $ProgramFiles64 (\W{http://sf.net/p/nsis/bugs/843}{bug #843})

View file

@ -188,6 +188,14 @@ The error flag is set if the string could not be written to the registry. The ty
\c WriteRegExpandStr HKLM "Software\My Company\My Software" "Expand String Value" "%WINDIR%\notepad.exe"
\S2{writeregmultistr} WriteRegMultiStr
\c /REGEDIT5 root_key subkey key_name value
Writes a multi-string value. The /REGEDIT5 switch must be used and specifies that the data is in the hex format used by .reg files on Windows 2000 and later.
\c WriteRegMultiStr /REGEDIT5 HKCU "Software\NSIS\Test" "Multi Value" 66,00,6f,00,6f,00,00,00,62,00,61,00,72,00,00,00,00,00
\S2{setregview} SetRegView
\c \\<b\\>32\\</b\\>|64|lastused

View file

@ -651,6 +651,7 @@ typedef DWORDLONG ULONGLONG,*PULONGLONG;
# define REG_EXPAND_SZ 2
# define REG_BINARY 3
# define REG_DWORD 4
# define REG_MULTI_SZ 7
#endif
// show modes

View file

@ -1274,7 +1274,7 @@ static int NSISCALL ExecuteEntry(entry *entry_)
// use buf2, buf3 and buf4
size = GetCompressedDataFromDataBlockToMemory(parm3, data, (3 * NSIS_MAX_STRLEN)*sizeof(TCHAR));
LogData2Hex(binbuf, COUNTOF(binbuf), data, size);
log_printf5(_T("WriteRegBin: \"%s\\%s\" \"%s\"=\"%s\""),rkn,buf1,buf0,binbuf);
log_printf6(_T("%s: \"%s\\%s\" \"%s\"=\"%s\""),rtype==REG_MULTI_SZ?_T("WriteRegMultiStr"):_T("WriteRegBin"),rkn,buf1,buf0,binbuf);
}
if (size >= 0 && RegSetValueEx(hKey,buf0,0,rtype,data,size) == ERROR_SUCCESS)

View file

@ -149,6 +149,31 @@ double LineParser::gettoken_number(int token, int *success/*=0*/) const
return forceint ? gettoken_int(token,success) : gettoken_float(token,success);
}
int LineParser::gettoken_binstrdata(int token, char*buffer, int bufcap) const
{
const TCHAR*p=gettoken_str(token);
int a,b,c,d=0;
while (*p)
{
a=*p;
if (a >= _T('0') && a <= _T('9')) a-=_T('0');
else if (a >= _T('a') && a <= _T('f')) a-=_T('a')-10;
else if (a >= _T('A') && a <= _T('F')) a-=_T('A')-10;
else if (a == _T(',')) { ++p; continue; } // Allow comma separator (for Regedit5 .reg format)
else break;
b=*++p;
if (b >= _T('0') && b <= _T('9')) b-=_T('0');
else if (b >= _T('a') && b <= _T('f')) b-=_T('a')-10;
else if (b >= _T('A') && b <= _T('F')) b-=_T('A')-10;
else break;
c=(a<<4)|b, p++;
if (d >= bufcap) return -1; // Buffer too small
buffer[d++]=c;
}
if (*p) return -2; // Did not parse the entire buffer
return d;
}
TCHAR* LineParser::gettoken_str(int token) const
{
token+=m_eat;

View file

@ -35,6 +35,7 @@ class LineParser {
double gettoken_float(int token, int *success=0) const;
int gettoken_int(int token, int *success=0) const;
double gettoken_number(int token, int *success=0) const;
int gettoken_binstrdata(int token, char*buffer, int bufcap) const;
TCHAR *gettoken_str(int token) const;
int gettoken_enum(int token, const TCHAR *strlist); // null separated list

View file

@ -5391,60 +5391,47 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
case TOK_WRITEREGSTR:
case TOK_WRITEREGEXPANDSTR:
case TOK_WRITEREGBIN:
case TOK_WRITEREGMULTISZ:
case TOK_WRITEREGDWORD:
{
const TCHAR*cmdname=get_commandtoken_name(which_token);
int reg5=0==line.gettoken_enum(1,_T("/REGEDIT5\0")), multisz=which_token==TOK_WRITEREGMULTISZ;
if (reg5) line.eattoken();
int k=line.gettoken_enum(1,rootkeys[0]);
if (k == -1) k=line.gettoken_enum(1,rootkeys[1]);
if (k == -1) PRINTHELP()
if (k == -1 || reg5 != multisz) PRINTHELPEX(cmdname); // WriteRegMultiStr only supports the /REGEDIT5 serialized format right now but we really should allow variables at some point.
ent.which=EW_WRITEREG;
ent.offsets[0]=REGROOTKEYTOINT(rootkey_tab[k]);
ent.offsets[1]=add_string(line.gettoken_str(2));
if (line.gettoken_str(2)[0] == _T('\\'))
warning_fl(_T("%") NPRIs _T(": registry path name begins with \'\\\', may cause problems"),line.gettoken_str(0));
warning_fl(_T("%") NPRIs _T(": registry path name begins with \'\\\', may cause problems"),cmdname);
ent.offsets[2]=add_string(line.gettoken_str(3));
if (which_token == TOK_WRITEREGSTR || which_token == TOK_WRITEREGEXPANDSTR)
{
SCRIPT_MSG(_T("%") NPRIs _T(": %") NPRIs _T("\\%") NPRIs _T("\\%") NPRIs _T("=%") NPRIs _T("\n"),
line.gettoken_str(0),line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
cmdname,line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
ent.offsets[3]=add_string(line.gettoken_str(4));
ent.offsets[4]=ent.offsets[5]=REG_SZ;
if (which_token == TOK_WRITEREGEXPANDSTR)
ent.offsets[5]=REG_EXPAND_SZ;
}
if (which_token == TOK_WRITEREGBIN)
if (which_token == TOK_WRITEREGBIN || multisz)
{
char data[3*NSIS_MAX_STRLEN]; // Jim Park: Keep the data as char / 8 bits
TCHAR *p=line.gettoken_str(4);
int data_len=0;
while (*p)
char data[3*NSIS_MAX_STRLEN];
int data_len=line.gettoken_binstrdata(4, data, sizeof(data));
if (data_len < 0)
{
int c;
int a,b;
a=*p;
if (a >= _T('0') && a <= _T('9')) a-=_T('0');
else if (a >= _T('a') && a <= _T('f')) a-=_T('a')-10;
else if (a >= _T('A') && a <= _T('F')) a-=_T('A')-10;
else break;
b=*++p;
if (b >= _T('0') && b <= _T('9')) b-=_T('0');
else if (b >= _T('a') && b <= _T('f')) b-=_T('a')-10;
else if (b >= _T('A') && b <= _T('F')) b-=_T('A')-10;
else break;
p++;
c=(a<<4)|b;
if (data_len >= 3*NSIS_MAX_STRLEN)
{
ERROR_MSG(_T("WriteRegBin: %d bytes of data exceeded\n"),3*NSIS_MAX_STRLEN);
return PS_ERROR;
}
data[data_len++]=c;
if (data_len == -2) PRINTHELPEX(cmdname);
ERROR_MSG(_T("%") NPRIs _T(": %d bytes of data exceeded\n"),cmdname,sizeof(data));
return PS_ERROR;
}
if (*p) PRINTHELP()
SCRIPT_MSG(_T("WriteRegBin: %") NPRIs _T("\\%") NPRIs _T("\\%") NPRIs _T("=%") NPRIs _T("\n"),
line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
if (multisz && (data_len < 4 || *(UINT32*)(&data[data_len-4]))) PRINTHELPEX(cmdname);
SCRIPT_MSG(_T("%") NPRIs _T(": %") NPRIs _T("\\%") NPRIs _T("\\%") NPRIs _T("=%") NPRIs _T("\n"),
cmdname,line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
if (multisz && !build_unicode) for (int p1=0, p2=p1; p1 < data_len; data_len--) data[p1++]=data[p2], p2+=2; // BUGBUG: Should convert each string from UTF-16 to DBCS but only exehead knows the codepage, limited to ASCII for now.
ent.offsets[3]=add_db_data(data,data_len);
if (ent.offsets[3] < 0) return PS_ERROR;
ent.offsets[4]=ent.offsets[5]=REG_BINARY;
ent.offsets[4]=REG_BINARY, ent.offsets[5]=multisz?REG_MULTI_SZ:REG_BINARY;
}
if (which_token == TOK_WRITEREGDWORD)
{
@ -5481,6 +5468,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
case TOK_WRITEREGSTR:
case TOK_WRITEREGEXPANDSTR:
case TOK_WRITEREGBIN:
case TOK_WRITEREGMULTISZ:
case TOK_WRITEREGDWORD:
case TOK_ENUMREGKEY:
case TOK_ENUMREGVAL:

View file

@ -236,6 +236,7 @@ static tokenType tokenlist[TOK__LAST] =
{TOK_WINDOWICON,_T("WindowIcon"),1,0,_T("on|off"),TP_GLOBAL},
{TOK_WRITEINISTR,_T("WriteINIStr"),4,0,_T("ini_file section_name entry_name new_value"),TP_CODE},
{TOK_WRITEREGBIN,_T("WriteRegBin"),4,0,_T("rootkey subkey entry_name hex_string_like_12848412AB\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_WRITEREGMULTISZ, _T("WriteRegMultiStr"),5,0,_T("/REGEDIT5 rootkey subkey entry_name hex_string_like_660000000000\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_WRITEREGDWORD,_T("WriteRegDWORD"),4,0,_T("rootkey subkey entry_name new_value_dword\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_WRITEREGSTR,_T("WriteRegStr"),4,0,_T("rootkey subkey entry_name new_value_string\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
{TOK_WRITEREGEXPANDSTR,_T("WriteRegExpandStr"),4,0,_T("rootkey subkey entry_name new_value_string\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},

View file

@ -186,6 +186,7 @@ enum
TOK_WRITEREGSTR,
TOK_WRITEREGEXPANDSTR,
TOK_WRITEREGBIN,
TOK_WRITEREGMULTISZ,
TOK_WRITEREGDWORD,
TOK_DELETEINISEC,
TOK_DELETEINISTR,