Added ReserveFile command (usable anywhere) that allows you to put a file in the datablock so that it is preloaded for use later. Useful for when you use plugins in .onInit, and bz2 mode. Need to document this stuff. Anyone? :)
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@1099 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
5ede2c5e93
commit
5b66661b0a
4 changed files with 98 additions and 84 deletions
|
@ -82,7 +82,7 @@ class CEXEBuild {
|
||||||
void ps_addtoline(const char *str, GrowBuf &linedata, StringList &hist);
|
void ps_addtoline(const char *str, GrowBuf &linedata, StringList &hist);
|
||||||
int doParse(const char *str, FILE *fp, const char *curfilename, int *lineptr, int ignore);
|
int doParse(const char *str, FILE *fp, const char *curfilename, int *lineptr, int ignore);
|
||||||
int doCommand(int which_token, LineParser &line, FILE *fp, const char *curfilename, int linecnt);
|
int doCommand(int which_token, LineParser &line, FILE *fp, const char *curfilename, int linecnt);
|
||||||
int do_add_file(const char *lgss, int attrib, int recurse, int linecnt, int *total_files, const char *name_override=0);
|
int do_add_file(const char *lgss, int attrib, int recurse, int linecnt, int *total_files, const char *name_override=0, int generatecode=1);
|
||||||
GrowBuf m_linebuild; // used for concatenating lines
|
GrowBuf m_linebuild; // used for concatenating lines
|
||||||
|
|
||||||
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
|
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
|
||||||
|
|
|
@ -2422,11 +2422,12 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char
|
||||||
ERROR_MSG("Error: %s specified, NSIS_SUPPORT_RMDIR not defined.\n", line.gettoken_str(0));
|
ERROR_MSG("Error: %s specified, NSIS_SUPPORT_RMDIR not defined.\n", line.gettoken_str(0));
|
||||||
return PS_ERROR;
|
return PS_ERROR;
|
||||||
#endif//!NSIS_SUPPORT_RMDIR
|
#endif//!NSIS_SUPPORT_RMDIR
|
||||||
|
case TOK_RESERVEFILE:
|
||||||
case TOK_FILE:
|
case TOK_FILE:
|
||||||
#ifdef NSIS_SUPPORT_FILE
|
#ifdef NSIS_SUPPORT_FILE
|
||||||
{
|
{
|
||||||
int a=1,attrib=0,rec=0;
|
int a=1,attrib=0,rec=0;
|
||||||
if (!stricmp(line.gettoken_str(a),"/a"))
|
if (which_token == TOK_FILE && !stricmp(line.gettoken_str(a),"/a"))
|
||||||
{
|
{
|
||||||
attrib=1;
|
attrib=1;
|
||||||
a++;
|
a++;
|
||||||
|
@ -2436,7 +2437,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char
|
||||||
rec=1;
|
rec=1;
|
||||||
a++;
|
a++;
|
||||||
}
|
}
|
||||||
else if (!strnicmp(line.gettoken_str(a),"/oname=",7))
|
else if (which_token == TOK_FILE && !strnicmp(line.gettoken_str(a),"/oname=",7))
|
||||||
{
|
{
|
||||||
char *on=line.gettoken_str(a)+7;
|
char *on=line.gettoken_str(a)+7;
|
||||||
a++;
|
a++;
|
||||||
|
@ -2448,7 +2449,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char
|
||||||
if (tf > 1) PRINTHELP()
|
if (tf > 1) PRINTHELP()
|
||||||
if (!tf)
|
if (!tf)
|
||||||
{
|
{
|
||||||
ERROR_MSG("File: \"%s\" -> no files found.\n",line.gettoken_str(a));
|
ERROR_MSG("%sFile: \"%s\" -> no files found.\n",(which_token == TOK_FILE)?"":"Reserve",line.gettoken_str(a));
|
||||||
PRINTHELP()
|
PRINTHELP()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2468,11 +2469,11 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char
|
||||||
t=buf;
|
t=buf;
|
||||||
}
|
}
|
||||||
int tf=0;
|
int tf=0;
|
||||||
int v=do_add_file(t, attrib, rec, linecnt,&tf);
|
int v=do_add_file(t, attrib, rec, linecnt,&tf,NULL,which_token == TOK_FILE);
|
||||||
if (v != PS_OK) return v;
|
if (v != PS_OK) return v;
|
||||||
if (!tf)
|
if (!tf)
|
||||||
{
|
{
|
||||||
ERROR_MSG("File: \"%s\" -> no files found.\n",t);
|
ERROR_MSG("%sFile: \"%s\" -> no files found.\n",(which_token == TOK_FILE)?"":"Reserve",t);
|
||||||
PRINTHELP()
|
PRINTHELP()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3609,7 +3610,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NSIS_SUPPORT_FILE
|
#ifdef NSIS_SUPPORT_FILE
|
||||||
int CEXEBuild::do_add_file(const char *lgss, int attrib, int recurse, int linecnt, int *total_files, const char *name_override)
|
int CEXEBuild::do_add_file(const char *lgss, int attrib, int recurse, int linecnt, int *total_files, const char *name_override, int generatecode)
|
||||||
{
|
{
|
||||||
char dir[1024];
|
char dir[1024];
|
||||||
char newfn[1024], *s;
|
char newfn[1024], *s;
|
||||||
|
@ -3659,34 +3660,37 @@ int CEXEBuild::do_add_file(const char *lgss, int attrib, int recurse, int linecn
|
||||||
*o=0;
|
*o=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*total_files)++;
|
if (generatecode)
|
||||||
ent.which=EW_CREATEDIR;
|
|
||||||
ent.offsets[0]=add_string(cur_out_path);
|
|
||||||
ent.offsets[1]=1;
|
|
||||||
a=add_entry(&ent);
|
|
||||||
if (a != PS_OK)
|
|
||||||
{
|
{
|
||||||
FindClose(h);
|
(*total_files)++;
|
||||||
return a;
|
ent.which=EW_CREATEDIR;
|
||||||
}
|
|
||||||
if (attrib)
|
|
||||||
{
|
|
||||||
ent.which=EW_SETFILEATTRIBUTES;
|
|
||||||
ent.offsets[0]=add_string(cur_out_path);
|
ent.offsets[0]=add_string(cur_out_path);
|
||||||
ent.offsets[1]=d.dwFileAttributes;
|
ent.offsets[1]=1;
|
||||||
|
|
||||||
a=add_entry(&ent);
|
a=add_entry(&ent);
|
||||||
if (a != PS_OK)
|
if (a != PS_OK)
|
||||||
{
|
{
|
||||||
FindClose(h);
|
FindClose(h);
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
if (attrib)
|
||||||
|
{
|
||||||
|
ent.which=EW_SETFILEATTRIBUTES;
|
||||||
|
ent.offsets[0]=add_string(cur_out_path);
|
||||||
|
ent.offsets[1]=d.dwFileAttributes;
|
||||||
|
|
||||||
|
a=add_entry(&ent);
|
||||||
|
if (a != PS_OK)
|
||||||
|
{
|
||||||
|
FindClose(h);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
char spec[1024];
|
char spec[1024];
|
||||||
sprintf(spec,"%s%s%s",dir,dir[0]?"\\":"",d.cFileName);
|
sprintf(spec,"%s%s%s",dir,dir[0]?"\\":"",d.cFileName);
|
||||||
SCRIPT_MSG("File: Descending to: \"%s\" -> \"%s\"\n",spec,cur_out_path);
|
SCRIPT_MSG("%sFile: Descending to: \"%s\" -> \"%s\"\n",generatecode?"":"Reserve",spec,cur_out_path);
|
||||||
strcat(spec,"\\*.*");
|
strcat(spec,"\\*.*");
|
||||||
a=do_add_file(spec,attrib,recurse,linecnt,total_files);
|
a=do_add_file(spec,attrib,recurse,linecnt,total_files,NULL,generatecode);
|
||||||
if (a != PS_OK)
|
if (a != PS_OK)
|
||||||
{
|
{
|
||||||
FindClose(h);
|
FindClose(h);
|
||||||
|
@ -3696,7 +3700,7 @@ int CEXEBuild::do_add_file(const char *lgss, int attrib, int recurse, int linecn
|
||||||
cur_out_path[wd_save]=0;
|
cur_out_path[wd_save]=0;
|
||||||
ent.which=EW_CREATEDIR;
|
ent.which=EW_CREATEDIR;
|
||||||
ent.offsets[1]=1;
|
ent.offsets[1]=1;
|
||||||
SCRIPT_MSG("File: Returning to: \"%s\" -> \"%s\"\n",dir,cur_out_path);
|
SCRIPT_MSG("%sFile: Returning to: \"%s\" -> \"%s\"\n",generatecode?"":"Reserve",dir,cur_out_path);
|
||||||
ent.offsets[0]=add_string(cur_out_path);
|
ent.offsets[0]=add_string(cur_out_path);
|
||||||
a=add_entry(&ent);
|
a=add_entry(&ent);
|
||||||
if (a != PS_OK)
|
if (a != PS_OK)
|
||||||
|
@ -3715,7 +3719,7 @@ int CEXEBuild::do_add_file(const char *lgss, int attrib, int recurse, int linecn
|
||||||
hFile=CreateFile(newfn,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
|
hFile=CreateFile(newfn,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
|
||||||
if (hFile == INVALID_HANDLE_VALUE)
|
if (hFile == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
ERROR_MSG("File: failed opening file \"%s\"\n",newfn);
|
ERROR_MSG("%sFile: failed opening file \"%s\"\n",generatecode?"":"Reserve",newfn);
|
||||||
return PS_ERROR;
|
return PS_ERROR;
|
||||||
}
|
}
|
||||||
hFileMap=NULL;
|
hFileMap=NULL;
|
||||||
|
@ -3723,7 +3727,7 @@ int CEXEBuild::do_add_file(const char *lgss, int attrib, int recurse, int linecn
|
||||||
if (len && !(hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL)))
|
if (len && !(hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL)))
|
||||||
{
|
{
|
||||||
CloseHandle(hFile);
|
CloseHandle(hFile);
|
||||||
ERROR_MSG("File: failed creating mmap of \"%s\"\n",newfn);
|
ERROR_MSG("%sFile: failed creating mmap of \"%s\"\n",generatecode?"":"Reserve",newfn);
|
||||||
return PS_ERROR;
|
return PS_ERROR;
|
||||||
}
|
}
|
||||||
char *filedata=NULL;
|
char *filedata=NULL;
|
||||||
|
@ -3734,37 +3738,41 @@ int CEXEBuild::do_add_file(const char *lgss, int attrib, int recurse, int linecn
|
||||||
{
|
{
|
||||||
if (hFileMap) CloseHandle(hFileMap);
|
if (hFileMap) CloseHandle(hFileMap);
|
||||||
CloseHandle(hFile);
|
CloseHandle(hFile);
|
||||||
ERROR_MSG("File: failed mmapping file \"%s\"\n",newfn);
|
ERROR_MSG("%sFile: failed mmapping file \"%s\"\n",generatecode?"":"Reserve",newfn);
|
||||||
return PS_ERROR;
|
return PS_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
section_add_size_kb((len+1023)/1024);
|
if (generatecode)
|
||||||
if (name_override) SCRIPT_MSG("File: \"%s\"->\"%s\"",d.cFileName,name_override);
|
section_add_size_kb((len+1023)/1024);
|
||||||
else SCRIPT_MSG("File: \"%s\"",d.cFileName);
|
if (name_override) SCRIPT_MSG("%sFile: \"%s\"->\"%s\"",generatecode?"":"Reserve",d.cFileName,name_override);
|
||||||
|
else SCRIPT_MSG("%sFile: \"%s\"",generatecode?"":"Reserve",d.cFileName);
|
||||||
if (!build_compress_whole)
|
if (!build_compress_whole)
|
||||||
if (build_compress) SCRIPT_MSG(" [compress]");
|
if (build_compress) SCRIPT_MSG(" [compress]");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
int last_build_datablock_used=getcurdbsize();
|
int last_build_datablock_used=getcurdbsize();
|
||||||
entry ent={0,};
|
entry ent={0,};
|
||||||
ent.which=EW_EXTRACTFILE;
|
if (generatecode)
|
||||||
ent.offsets[0]=build_overwrite;
|
|
||||||
if (name_override)
|
|
||||||
{
|
{
|
||||||
ent.offsets[1]=add_string(name_override);
|
ent.which=EW_EXTRACTFILE;
|
||||||
}
|
ent.offsets[0]=build_overwrite;
|
||||||
else
|
if (name_override)
|
||||||
{
|
|
||||||
char *i=d.cFileName,*o=buf;
|
|
||||||
while (*i)
|
|
||||||
{
|
{
|
||||||
char c=*i++;
|
ent.offsets[1]=add_string(name_override);
|
||||||
*o++=c;
|
}
|
||||||
if (c == '$') *o++='$';
|
else
|
||||||
|
{
|
||||||
|
char *i=d.cFileName,*o=buf;
|
||||||
|
while (*i)
|
||||||
|
{
|
||||||
|
char c=*i++;
|
||||||
|
*o++=c;
|
||||||
|
if (c == '$') *o++='$';
|
||||||
|
}
|
||||||
|
*o=0;
|
||||||
|
ent.offsets[1]=add_string(buf);
|
||||||
}
|
}
|
||||||
*o=0;
|
|
||||||
ent.offsets[1]=add_string(buf);
|
|
||||||
}
|
}
|
||||||
ent.offsets[2]=add_data(filedata?filedata:"",len);
|
ent.offsets[2]=add_data(filedata?filedata:"",len);
|
||||||
|
|
||||||
|
@ -3784,59 +3792,65 @@ int CEXEBuild::do_add_file(const char *lgss, int attrib, int recurse, int linecn
|
||||||
else SCRIPT_MSG(" %d bytes\n",len);
|
else SCRIPT_MSG(" %d bytes\n",len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (build_datesave || build_overwrite==0x3 /*ifnewer*/)
|
if (generatecode)
|
||||||
{
|
{
|
||||||
FILETIME ft;
|
if (build_datesave || build_overwrite==0x3 /*ifnewer*/)
|
||||||
if (GetFileTime(hFile,NULL,NULL,&ft))
|
|
||||||
{
|
{
|
||||||
ent.offsets[3]=ft.dwLowDateTime;
|
FILETIME ft;
|
||||||
ent.offsets[4]=ft.dwHighDateTime;
|
if (GetFileTime(hFile,NULL,NULL,&ft))
|
||||||
|
{
|
||||||
|
ent.offsets[3]=ft.dwLowDateTime;
|
||||||
|
ent.offsets[4]=ft.dwHighDateTime;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CloseHandle(hFile);
|
||||||
|
ERROR_MSG("%sFile: failed getting file date from \"%s\"\n",generatecode?"":"Reserve",newfn);
|
||||||
|
return PS_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CloseHandle(hFile);
|
ent.offsets[3]=0xffffffff;
|
||||||
ERROR_MSG("File: failed getting file date from \"%s\"\n",newfn);
|
ent.offsets[4]=0xffffffff;
|
||||||
return PS_ERROR;
|
|
||||||
}
|
}
|
||||||
|
if (uninstall_mode) m_uninst_fileused++;
|
||||||
|
else m_inst_fileused++;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
ent.offsets[3]=0xffffffff;
|
|
||||||
ent.offsets[4]=0xffffffff;
|
|
||||||
}
|
|
||||||
if (uninstall_mode) m_uninst_fileused++;
|
|
||||||
else m_inst_fileused++;
|
|
||||||
|
|
||||||
CloseHandle(hFile);
|
CloseHandle(hFile);
|
||||||
|
|
||||||
int a=add_entry(&ent);
|
if (generatecode)
|
||||||
if (a != PS_OK)
|
|
||||||
{
|
{
|
||||||
FindClose(h);
|
int a=add_entry(&ent);
|
||||||
return a;
|
|
||||||
}
|
|
||||||
if (attrib)
|
|
||||||
{
|
|
||||||
char tmp_path[1024];
|
|
||||||
ent.which=EW_SETFILEATTRIBUTES;
|
|
||||||
if (name_override)
|
|
||||||
{
|
|
||||||
sprintf(tmp_path,"%s\\%s",cur_out_path,name_override);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprintf(tmp_path,"%s\\%s",cur_out_path,buf);
|
|
||||||
}
|
|
||||||
ent.offsets[0]=add_string(tmp_path);
|
|
||||||
ent.offsets[1]=d.dwFileAttributes;
|
|
||||||
|
|
||||||
a=add_entry(&ent);
|
|
||||||
if (a != PS_OK)
|
if (a != PS_OK)
|
||||||
{
|
{
|
||||||
FindClose(h);
|
FindClose(h);
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
}
|
if (attrib)
|
||||||
|
{
|
||||||
|
char tmp_path[1024];
|
||||||
|
ent.which=EW_SETFILEATTRIBUTES;
|
||||||
|
if (name_override)
|
||||||
|
{
|
||||||
|
sprintf(tmp_path,"%s\\%s",cur_out_path,name_override);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(tmp_path,"%s\\%s",cur_out_path,buf);
|
||||||
|
}
|
||||||
|
ent.offsets[0]=add_string(tmp_path);
|
||||||
|
ent.offsets[1]=d.dwFileAttributes;
|
||||||
|
|
||||||
|
a=add_entry(&ent);
|
||||||
|
if (a != PS_OK)
|
||||||
|
{
|
||||||
|
FindClose(h);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} while (FindNextFile(h,&d));
|
} while (FindNextFile(h,&d));
|
||||||
FindClose(h);
|
FindClose(h);
|
||||||
|
|
|
@ -62,6 +62,7 @@ static tokenType tokenlist[TOK__LAST] =
|
||||||
{TOK_FINDFIRST,"FindFirst",3,0,"$(user_var: handle output) $(user_var: filename output) filespec"},
|
{TOK_FINDFIRST,"FindFirst",3,0,"$(user_var: handle output) $(user_var: filename output) filespec"},
|
||||||
{TOK_FINDNEXT,"FindNext",2,0,"$(user_var: handle input) $(user_var: filename output)"},
|
{TOK_FINDNEXT,"FindNext",2,0,"$(user_var: handle input) $(user_var: filename output)"},
|
||||||
{TOK_FILE,"File",1,-1,"([/a] [/r] filespec [...]|/oname=outfile one_file_only)"},
|
{TOK_FILE,"File",1,-1,"([/a] [/r] filespec [...]|/oname=outfile one_file_only)"},
|
||||||
|
{TOK_RESERVEFILE,"ReserveFile",1,-1,"[/r] file [file...]"},
|
||||||
{TOK_FILECLOSE,"FileClose",1,0,"$(user_var: handle input)"},
|
{TOK_FILECLOSE,"FileClose",1,0,"$(user_var: handle input)"},
|
||||||
{TOK_FILEERRORTEXT,"FileErrorText",0,2,"[/LANG=lang_id] [text (can contain $0)]"},
|
{TOK_FILEERRORTEXT,"FileErrorText",0,2,"[/LANG=lang_id] [text (can contain $0)]"},
|
||||||
{TOK_FILEOPEN,"FileOpen",3,0,"$(user_var: handle output) filename openmode\n openmode=r|w|a"},
|
{TOK_FILEOPEN,"FileOpen",3,0,"$(user_var: handle output) filename openmode\n openmode=r|w|a"},
|
||||||
|
@ -184,7 +185,6 @@ static tokenType tokenlist[TOK__LAST] =
|
||||||
{TOK_P_MACROEND,"!macroend",0,0,""},
|
{TOK_P_MACROEND,"!macroend",0,0,""},
|
||||||
{TOK_P_INSERTMACRO,"!insertmacro",1,-1,"macroname [parms ...]"},
|
{TOK_P_INSERTMACRO,"!insertmacro",1,-1,"macroname [parms ...]"},
|
||||||
|
|
||||||
|
|
||||||
{TOK_MISCBUTTONTEXT,"MiscButtonText",0,5,"[/LANG=lang_id] [back button text] [next button text] [cancel button text] [close button text]"},
|
{TOK_MISCBUTTONTEXT,"MiscButtonText",0,5,"[/LANG=lang_id] [back button text] [next button text] [cancel button text] [close button text]"},
|
||||||
{TOK_DETAILSBUTTONTEXT,"DetailsButtonText",0,2,"[/LANG=lang_id] [details button text]"},
|
{TOK_DETAILSBUTTONTEXT,"DetailsButtonText",0,2,"[/LANG=lang_id] [details button text]"},
|
||||||
{TOK_UNINSTBUTTONTEXT,"UninstallButtonText",0,2,"[/LANG=lang_id] [uninstall button text]"},
|
{TOK_UNINSTBUTTONTEXT,"UninstallButtonText",0,2,"[/LANG=lang_id] [uninstall button text]"},
|
||||||
|
@ -196,8 +196,7 @@ static tokenType tokenlist[TOK__LAST] =
|
||||||
{TOK_GETLABELADDR,"GetLabelAddress",2,0,"output label"},
|
{TOK_GETLABELADDR,"GetLabelAddress",2,0,"output label"},
|
||||||
{TOK_GETCURRENTADDR,"GetCurrentAddress",1,0,"output"},
|
{TOK_GETCURRENTADDR,"GetCurrentAddress",1,0,"output"},
|
||||||
|
|
||||||
{TOK_PLUGINDIR,"PluginDir",1,0,"SetPluginDir directory"},
|
{TOK_PLUGINDIR,"PluginDir",1,0,"new_plugin_directory"},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void CEXEBuild::print_help(char *commandname)
|
void CEXEBuild::print_help(char *commandname)
|
||||||
|
|
|
@ -45,6 +45,7 @@ enum
|
||||||
TOK_SETFONT,
|
TOK_SETFONT,
|
||||||
TOK_SETCOMPRESSOR,
|
TOK_SETCOMPRESSOR,
|
||||||
TOK_LOADNLF,
|
TOK_LOADNLF,
|
||||||
|
TOK_RESERVEFILE,
|
||||||
|
|
||||||
TOK_MISCBUTTONTEXT,
|
TOK_MISCBUTTONTEXT,
|
||||||
TOK_DETAILSBUTTONTEXT,
|
TOK_DETAILSBUTTONTEXT,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue