diff --git a/Contrib/ExDLL/exdll.h b/Contrib/ExDLL/exdll.h index 4f57e38c..32c73dbb 100644 --- a/Contrib/ExDLL/exdll.h +++ b/Contrib/ExDLL/exdll.h @@ -19,7 +19,7 @@ typedef struct _stack_t { } stack_t; -static int g_stringsize; +static unsigned int g_stringsize; static stack_t **g_stacktop; static char *g_variables; diff --git a/Contrib/nsExec/nsExec.dsp b/Contrib/nsExec/nsExec.dsp index 81ed9f42..57f38927 100644 --- a/Contrib/nsExec/nsExec.dsp +++ b/Contrib/nsExec/nsExec.dsp @@ -49,7 +49,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"_DllMainCRTStartup" /dll /machine:I386 /nodefaultlib /out:"../../Plugins/nsExec.dll" /opt:nowin98 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"_DllMainCRTStartup" /dll /map /machine:I386 /nodefaultlib /out:"../../Plugins/nsExec.dll" /opt:nowin98 # SUBTRACT LINK32 /pdb:none # Begin Target diff --git a/Contrib/nsExec/nsExec.txt b/Contrib/nsExec/nsExec.txt index 8c8e1bc1..dcf06c92 100644 --- a/Contrib/nsExec/nsExec.txt +++ b/Contrib/nsExec/nsExec.txt @@ -12,8 +12,13 @@ nsExec::Exec [/TIMEOUT=x] path nsExec::ExecToLog [/TIMEOUT=x] path -Both functions are the same except ExecToLog will print the output -to the logwindow. +-or- + +nsExec::ExecToStack [/TIMEOUT=x] path + +All functions are the same except ExecToLog will print the output +to the logwindow and ExecToStack will push up to ${NSIS_MAX_STRLEN} +characters of output onto the stack after the return value. The timeout value is optional. The timeout is the time in milliseconds nsExec will wait for output. If output from the diff --git a/Contrib/nsExec/nsexec.c b/Contrib/nsExec/nsexec.c index b6da251f..e526e71e 100644 --- a/Contrib/nsExec/nsexec.c +++ b/Contrib/nsExec/nsexec.c @@ -45,7 +45,7 @@ void __declspec(dllexport) Exec(HWND hwndParent, int string_size, char *variable g_hwndParent=hwndParent; EXDLL_INIT(); { - ExecScript(false); + ExecScript(0); } } @@ -53,7 +53,15 @@ void __declspec(dllexport) ExecToLog(HWND hwndParent, int string_size, char *var g_hwndParent=hwndParent; EXDLL_INIT(); { - ExecScript(true); + ExecScript(1); + } +} + +void __declspec(dllexport) ExecToStack(HWND hwndParent, int string_size, char *variables, stack_t **stacktop) { + g_hwndParent=hwndParent; + EXDLL_INIT(); + { + ExecScript(2); } } @@ -61,7 +69,9 @@ BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lp return TRUE; } -void ExecScript(BOOL log) { +void ExecScript(int log) { + char szRet[128] = ""; + 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); @@ -73,8 +83,8 @@ void ExecScript(BOOL log) { } } if (!g_exec[0]) { - pushstring("error"); - return; + lstrcpy(szRet, "error"); + goto done; } { STARTUPINFO si={sizeof(si),}; @@ -87,15 +97,14 @@ void ExecScript(BOOL log) { DWORD dwExit = !STILL_ACTIVE; DWORD dwLastOutput; static char szBuf[1024]; - char szRet[128] = ""; HGLOBAL hUnusedBuf; char *szUnusedBuf = 0; if (log) { - hUnusedBuf = GlobalAlloc(GHND, sizeof(szBuf)*4); + hUnusedBuf = GlobalAlloc(GHND, log & 2 ? g_stringsize : sizeof(szBuf)*4); if (!hUnusedBuf) { - pushstring("error"); - return; + lstrcpy(szRet, "error"); + goto done; } szUnusedBuf = (char *)GlobalLock(hUnusedBuf); } @@ -109,8 +118,8 @@ void ExecScript(BOOL log) { else sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = true; if (!CreatePipe(&read_stdout,&newstdout,&sa,0)) { - pushstring("error"); - return; + lstrcpy(szRet, "error"); + goto done; } GetStartupInfo(&si); @@ -119,14 +128,8 @@ void ExecScript(BOOL log) { si.hStdOutput = newstdout; si.hStdError = newstdout; if (!CreateProcess(NULL,g_exec,NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi)) { - pushstring("error"); - CloseHandle(newstdout); - CloseHandle(read_stdout); - if (log) { - GlobalUnlock(hUnusedBuf); - GlobalFree(hUnusedBuf); - } - return; + lstrcpy(szRet, "error"); + goto done; } dwLastOutput = GetTickCount(); @@ -140,37 +143,34 @@ void ExecScript(BOOL log) { if (log) { char *p, *lineBreak; SIZE_T iReqLen = lstrlen(szBuf) + lstrlen(szUnusedBuf); - if (GlobalSize(hUnusedBuf) < iReqLen) { + if (GlobalSize(hUnusedBuf) < iReqLen && (iReqLen < g_stringsize || !(log & 2))) { GlobalUnlock(hUnusedBuf); hUnusedBuf = GlobalReAlloc(hUnusedBuf, iReqLen+sizeof(szBuf), GHND); if (!hUnusedBuf) { - pushstring("error"); - CloseHandle(pi.hThread); - CloseHandle(pi.hProcess); - CloseHandle(newstdout); - CloseHandle(read_stdout); - if (log) { - GlobalUnlock(hUnusedBuf); - GlobalFree(hUnusedBuf); - } - return; + lstrcpy(szRet, "error"); + break; } szUnusedBuf = (char *)GlobalLock(hUnusedBuf); } p = szUnusedBuf; // get the old left overs - lstrcat(p, szBuf); - - while (lineBreak = my_strstr(p, "\r\n")) { - *lineBreak = 0; - LogMessage(p); - p = lineBreak + 2; + if (iReqLen < g_stringsize || !(log & 2)) lstrcat(p, szBuf); + else { + lstrcpyn(p + lstrlen(p), szBuf, g_stringsize - lstrlen(p)); } - // If data was taken out from the unused buffer, move p contents to the start of szUnusedBuf - if (p != szUnusedBuf) { - char *p2 = szUnusedBuf; - while (*p) *p2++ = *p++; - *p2 = 0; + if (!(log & 2)) { + 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; + while (*p) *p2++ = *p++; + *p2 = 0; + } } } } @@ -186,7 +186,9 @@ void ExecScript(BOOL log) { PeekNamedPipe(read_stdout, 0, 0, 0, &dwRead, NULL); } } - if (log && *szUnusedBuf) LogMessage(szUnusedBuf); +done: + if (log & 2) pushstring(szUnusedBuf); + if (log & 1 && *szUnusedBuf) LogMessage(szUnusedBuf); if (!szRet[0]) wsprintf(szRet,"%d",dwExit); pushstring(szRet); CloseHandle(pi.hThread); diff --git a/Contrib/nsExec/test.nsi b/Contrib/nsExec/test.nsi index 39af6d8f..d39b4832 100644 --- a/Contrib/nsExec/test.nsi +++ b/Contrib/nsExec/test.nsi @@ -6,25 +6,19 @@ ShowInstDetails show Section "MakeNSIS commands help" nsExec::ExecToLog '"${NSISDIR}\makensis.exe" /CMDHELP' - Pop $0 + Pop $0 # return value/error/timeout DetailPrint "" DetailPrint " Return value: $0" + DetailPrint "" SectionEnd Section "Output to variable" - ReadEnvStr $0 COMSPEC - GetTempFileName $1 - StrCpy $2 "${NSISDIR}\makensis.exe" - GetFullPathName /SHORT $2 $2 - StrCpy $0 '"$0" /C $2 /VERSION > "$1"' - nsExec::Exec $0 - FileOpen $0 $1 r - FileRead $0 $3 - FileClose $0 - SetDetailsPrint none - Delete $1 - SetDetailsPrint both + nsExec::ExecToStack '"${NSISDIR}\makensis.exe" /VERSION' + Pop $0 # return value/error/timeout + Pop $1 # printed text, up to ${NSIS_MAX_STRLEN} + DetailPrint '"${NSISDIR}\makensis.exe" /VERSION printed: $1' DetailPrint "" - DetailPrint "$2 /VERSION returned: $3" + DetailPrint " Return value: $0" DetailPrint "" + Return SectionEnd \ No newline at end of file diff --git a/Plugins/nsExec.dll b/Plugins/nsExec.dll index 293259e3..65c761ec 100644 Binary files a/Plugins/nsExec.dll and b/Plugins/nsExec.dll differ