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:
ramon18 2003-07-21 19:48:48 +00:00
parent da9d5eb4db
commit 21f668de9c
5 changed files with 91 additions and 88 deletions

View file

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

View file

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