Fixed problem in IO dirreq/filereq, optimized code, nsExec with /CMD param to allow execute 16Bits DOS applications
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@2762 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
da9d5eb4db
commit
21f668de9c
5 changed files with 91 additions and 88 deletions
|
@ -6,15 +6,15 @@ without opening a dos box.
|
|||
|
||||
Usage
|
||||
-----
|
||||
nsExec::Exec [/TIMEOUT=x] path
|
||||
nsExec::Exec [/TIMEOUT=x] [/CMD] path
|
||||
|
||||
-or-
|
||||
|
||||
nsExec::ExecToLog [/TIMEOUT=x] path
|
||||
nsExec::ExecToLog [/TIMEOUT=x] [/CMD] path
|
||||
|
||||
-or-
|
||||
|
||||
nsExec::ExecToStack [/TIMEOUT=x] path
|
||||
nsExec::ExecToStack [/TIMEOUT=x] [/CMD] path
|
||||
|
||||
All functions are the same except ExecToLog will print the output
|
||||
to the logwindow and ExecToStack will push up to ${NSIS_MAX_STRLEN}
|
||||
|
@ -26,6 +26,18 @@ process is received, the timeout value is reset and it will
|
|||
again wait for more output using the timeout value. See Return
|
||||
Value for how to check if there was a timeout.
|
||||
|
||||
The /CMD param is optional. The /CMD indicates that the exec procedure should use
|
||||
command processor to execute the command, ie, %COMSPEC% path
|
||||
|
||||
*IMPORTANT NOTICE* The /CMD param should be used for 16bits MS-DOS applications
|
||||
or applications that create windows, or any form of user interface
|
||||
|
||||
To ensure that command are executed without problems on all windows versions,
|
||||
is recommended to use the following syntax:
|
||||
|
||||
nsExec::ExecToStack [OPTIONS] '"PATH" param1 param2 paramN'
|
||||
|
||||
This way the application path may contain non 8.3 paths (with spaces)
|
||||
|
||||
Return Value
|
||||
------------
|
||||
|
|
|
@ -40,6 +40,7 @@ void ExecScript(BOOL log);
|
|||
void LogMessage(const char *pStr);
|
||||
char *my_strstr(const char *string, const char *strCharSet);
|
||||
unsigned int my_atoi(char *s);
|
||||
void * mini_memcpy(void *outBuf, const void *inBuf, int len);
|
||||
|
||||
void __declspec(dllexport) Exec(HWND hwndParent, int string_size, char *variables, stack_t **stacktop) {
|
||||
g_hwndParent=hwndParent;
|
||||
|
@ -69,23 +70,50 @@ BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lp
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#define TAB_REPLACE " "
|
||||
#define TAB_REPLACE_SIZE (sizeof(TAB_REPLACE)-1)
|
||||
|
||||
void ExecScript(int log) {
|
||||
char szRet[128] = "";
|
||||
char *pExec;
|
||||
char sAux[MAX_PATH];
|
||||
char *pRoot = NULL;
|
||||
int nComSpecSize;
|
||||
BOOL bUseComSpec=false;
|
||||
|
||||
nComSpecSize = ExpandEnvironmentStrings("%ComSpec% /c ", sAux, MAX_PATH);
|
||||
g_to = 0; // default is no timeout
|
||||
g_hwndList = FindWindowEx(FindWindowEx(g_hwndParent,NULL,"#32770",NULL),NULL,"SysListView32",NULL);
|
||||
g_exec = (char *)GlobalAlloc(GPTR, sizeof(char)*g_stringsize+1);
|
||||
if (!popstring(g_exec)) {
|
||||
g_exec = (char *)GlobalAlloc(GPTR, sizeof(char)*g_stringsize+nComSpecSize+1);
|
||||
lstrcpy(g_exec, sAux);
|
||||
pExec = g_exec + nComSpecSize - 1;
|
||||
|
||||
while ( !popstring(pExec) ) {
|
||||
if (my_strstr(g_exec,"/TIMEOUT=")) {
|
||||
char *szTimeout = g_exec + 9;
|
||||
g_to = my_atoi(szTimeout);
|
||||
popstring(g_exec);
|
||||
}
|
||||
else if (my_strstr(g_exec,"/CMD")) {
|
||||
bUseComSpec = true;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (!g_exec[0]) {
|
||||
|
||||
if (!pExec[0] )
|
||||
{
|
||||
lstrcpy(szRet, "error");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ( bUseComSpec )
|
||||
{
|
||||
GetWindowsDirectory(sAux, MAX_PATH); // UNC paths not supported on cmd.exe / command.com
|
||||
pRoot = sAux;
|
||||
}
|
||||
else
|
||||
lstrcpy(g_exec, pExec);
|
||||
|
||||
{
|
||||
STARTUPINFO si={sizeof(si),};
|
||||
SECURITY_ATTRIBUTES sa={sizeof(sa),};
|
||||
|
@ -128,7 +156,7 @@ void ExecScript(int log) {
|
|||
si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
|
||||
si.hStdOutput = newstdout;
|
||||
si.hStdError = newstdout;
|
||||
if (!CreateProcess(NULL,g_exec,NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi)) {
|
||||
if (!CreateProcess(NULL,g_exec,NULL,NULL,TRUE,0,NULL,pRoot,&si,&pi)) {
|
||||
lstrcpy(szRet, "error");
|
||||
goto done;
|
||||
}
|
||||
|
@ -160,12 +188,21 @@ void ExecScript(int log) {
|
|||
}
|
||||
|
||||
if (!(log & 2)) {
|
||||
while ( p = my_strstr(p, "\t") )
|
||||
{
|
||||
mini_memcpy(p+TAB_REPLACE_SIZE, p+1, lstrlen(p));
|
||||
lstrcpy(p, TAB_REPLACE);
|
||||
p += TAB_REPLACE_SIZE;
|
||||
*p = ' ';
|
||||
}
|
||||
|
||||
p = szUnusedBuf; // get the old left overs
|
||||
while (lineBreak = my_strstr(p, "\r\n")) {
|
||||
*lineBreak = 0;
|
||||
LogMessage(p);
|
||||
p = lineBreak + 2;
|
||||
}
|
||||
|
||||
|
||||
// If data was taken out from the unused buffer, move p contents to the start of szUnusedBuf
|
||||
if (p != szUnusedBuf) {
|
||||
char *p2 = szUnusedBuf;
|
||||
|
@ -270,3 +307,14 @@ unsigned int my_atoi(char *s) {
|
|||
}
|
||||
return (int)v;
|
||||
}
|
||||
|
||||
void * mini_memcpy(void *outBuf, const void *inBuf, int len)
|
||||
{
|
||||
char *c_out=(char*)outBuf+(len-1);
|
||||
char *c_in=(char *)inBuf+(len-1);
|
||||
while (len-- > 0)
|
||||
{
|
||||
*c_out--=*c_in--;
|
||||
}
|
||||
return outBuf;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue