Timeout now works

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@1302 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
kichik 2002-10-04 18:11:13 +00:00
parent 89c7fa3204
commit dfbd9e93c0
2 changed files with 201 additions and 202 deletions

View file

@ -10,11 +10,11 @@ including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions: freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not 1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be in a product, an acknowledgment in the product documentation would be
appreciated but is not required. appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be 2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software. misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution. 3. This notice may not be removed or altered from any source distribution.
*/ */
@ -28,242 +28,241 @@ freely, subject to the following restrictions:
#ifndef false #ifndef false
#define false FALSE #define false FALSE
#endif #endif
#define TIMEOUT 15000 #define LOOPTIMEOUT 100
#define NOLOG_TIMEOUT 600000
#define LOOPTIMEOUT 100
HINSTANCE g_hInstance; HWND g_hwndParent;
HWND g_hwndParent; HWND g_hwndList;
HWND g_hwndList; char * g_exec;
HWND g_hwndDlg; unsigned int g_to;
char * g_exec;
char * g_szto;
BOOL g_foundto;
int g_to;
void ExecScript(BOOL log); void ExecScript(BOOL log);
void LogMessage(const char *pStr); void LogMessage(const char *pStr);
char *my_strstr(const char *string, const char *strCharSet); char *my_strstr(const char *string, const char *strCharSet);
int my_atoi(char *s); unsigned int my_atoi(char *s);
void __declspec(dllexport) Exec(HWND hwndParent, int string_size, char *variables, stack_t **stacktop) { void __declspec(dllexport) Exec(HWND hwndParent, int string_size, char *variables, stack_t **stacktop) {
g_hwndParent=hwndParent; g_hwndParent=hwndParent;
EXDLL_INIT(); EXDLL_INIT();
{ {
ExecScript(false); ExecScript(false);
} }
} }
void __declspec(dllexport) ExecToLog(HWND hwndParent, int string_size, char *variables, stack_t **stacktop) { void __declspec(dllexport) ExecToLog(HWND hwndParent, int string_size, char *variables, stack_t **stacktop) {
g_hwndParent=hwndParent; g_hwndParent=hwndParent;
EXDLL_INIT(); EXDLL_INIT();
{ {
ExecScript(true); ExecScript(true);
} }
} }
BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) { BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) {
g_hInstance=hInst; return TRUE;
return TRUE;
} }
void ExecScript(BOOL log) { void ExecScript(BOOL log) {
g_to = INFINITE; g_to = 0; // default is no timeout
g_foundto = FALSE; g_hwndList = FindWindowEx(FindWindowEx(g_hwndParent,NULL,"#32770",NULL),NULL,"SysListView32",NULL);
g_hwndDlg = FindWindowEx(g_hwndParent,NULL,"#32770",NULL); g_exec = (char *)GlobalAlloc(GPTR, sizeof(char)*g_stringsize+1);
g_hwndList = FindWindowEx(g_hwndDlg,NULL,"SysListView32",NULL); if (!popstring(g_exec)) {
g_exec = (char *)GlobalAlloc(GPTR, sizeof(char)*g_stringsize+1); if (my_strstr(g_exec,"/TIMEOUT=")) {
g_szto = (char *)GlobalAlloc(GPTR, sizeof(char)*g_stringsize+1); char *szTimeout = g_exec + 9;
if (!popstring(g_szto)) { g_to = my_atoi(szTimeout);
if (my_strstr(g_szto,"/TIMEOUT=")) { popstring(g_exec);
g_szto += 9;
g_to = my_atoi(g_szto);
if (g_to<0) g_to = log?TIMEOUT:NOLOG_TIMEOUT;
g_foundto = TRUE;
}
} }
if (g_foundto) { }
if (popstring(g_exec)) { if (!g_exec[0]) {
pushstring("error"); pushstring("error");
return; return;
} }
} {
else { STARTUPINFO si={sizeof(si),};
lstrcpy(g_exec,g_szto); SECURITY_ATTRIBUTES sa={sizeof(sa),};
} SECURITY_DESCRIPTOR sd={0,};
{ PROCESS_INFORMATION pi={0,};
STARTUPINFO si={sizeof(si),}; OSVERSIONINFO osv={sizeof(osv)};
SECURITY_ATTRIBUTES sa={sizeof(sa),}; HANDLE newstdout=0,read_stdout=0;
SECURITY_DESCRIPTOR sd={0,}; DWORD dwRead = 1;
PROCESS_INFORMATION pi={0,}; DWORD dwExit = !STILL_ACTIVE;
OSVERSIONINFO osv={sizeof(osv)}; DWORD dwLastOutput;
HANDLE newstdout=0,read_stdout=0; static char szBuf[1024];
DWORD dwRead = 1; char szRet[128] = "";
DWORD dwExit = !STILL_ACTIVE; HGLOBAL hUnusedBuf;
static char szBuf[1024]; char *szUnusedBuf = 0;
static char szRet[128];
HGLOBAL hUnusedBuf;
static char *szUnusedBuf;
if (log) {
hUnusedBuf = GlobalAlloc(GHND, sizeof(szBuf)*4);
if (!hUnusedBuf) {
pushstring("error");
return;
}
szUnusedBuf = (char *)GlobalLock(hUnusedBuf);
}
GetVersionEx(&osv);
if (osv.dwPlatformId == VER_PLATFORM_WIN32_NT) {
InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd,true,NULL,false);
sa.lpSecurityDescriptor = &sd;
}
else sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = true;
if (!CreatePipe(&read_stdout,&newstdout,&sa,0)) {
pushstring("error");
return;
}
GetStartupInfo(&si);
si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
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;
}
dwLastOutput = GetTickCount();
while (dwExit == STILL_ACTIVE || dwRead) {
PeekNamedPipe(read_stdout, 0, 0, 0, &dwRead, NULL);
if (dwRead) {
dwLastOutput = GetTickCount();
ReadFile(read_stdout, szBuf, sizeof(szBuf)-1, &dwRead, NULL);
szBuf[dwRead] = 0;
if (log) { if (log) {
hUnusedBuf = GlobalAlloc(GHND, sizeof(szBuf)*4); char *p, *lineBreak;
SIZE_T iReqLen = lstrlen(szBuf) + lstrlen(szUnusedBuf);
if (GlobalSize(hUnusedBuf) < iReqLen) {
GlobalUnlock(hUnusedBuf);
hUnusedBuf = GlobalReAlloc(hUnusedBuf, iReqLen+sizeof(szBuf), GHND);
if (!hUnusedBuf) { if (!hUnusedBuf) {
pushstring("error"); pushstring("error");
return; CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(newstdout);
CloseHandle(read_stdout);
if (log) {
GlobalUnlock(hUnusedBuf);
GlobalFree(hUnusedBuf);
}
return;
} }
szUnusedBuf = (char *)GlobalLock(hUnusedBuf); szUnusedBuf = (char *)GlobalLock(hUnusedBuf);
}
p = szUnusedBuf; // get the old left overs
lstrcat(p, szBuf);
GetVersionEx(&osv); while (lineBreak = my_strstr(p, "\r\n")) {
if (osv.dwPlatformId == VER_PLATFORM_WIN32_NT) { *lineBreak = 0;
InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION); LogMessage(p);
SetSecurityDescriptorDacl(&sd,true,NULL,false); p = lineBreak + 2;
sa.lpSecurityDescriptor = &sd; }
}
else sa.lpSecurityDescriptor = NULL; // If data was taken out from the unused buffer, move p contents to the start of szUnusedBuf
sa.bInheritHandle = true; if (p != szUnusedBuf) {
if (!CreatePipe(&read_stdout,&newstdout,&sa,0)) { char *p2 = szUnusedBuf;
pushstring("error"); while (*p) *p2++ = *p++;
return; *p2 = 0;
} }
} }
}
GetStartupInfo(&si); else {
si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; if (g_to && GetTickCount() > dwLastOutput+g_to) {
si.wShowWindow = SW_HIDE; TerminateProcess(pi.hProcess, -1);
si.hStdOutput = newstdout; lstrcpy(szRet, "timeout");
si.hStdError = newstdout;
if (!CreateProcess(NULL,g_exec,NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi)) {
CloseHandle(newstdout);
CloseHandle(read_stdout);
pushstring("error");
return;
} }
else Sleep(LOOPTIMEOUT);
if (log) { }
while (dwExit == STILL_ACTIVE || dwRead) { GetExitCodeProcess(pi.hProcess, &dwExit);
PeekNamedPipe(read_stdout, 0, 0, 0, &dwRead, NULL); if (dwExit != STILL_ACTIVE) {
if (dwRead) { PeekNamedPipe(read_stdout, 0, 0, 0, &dwRead, NULL);
ReadFile(read_stdout, szBuf, sizeof(szBuf)-1, &dwRead, NULL); }
szBuf[dwRead] = 0;
{
char *p, *lineBreak;
SIZE_T iReqLen = lstrlen(szBuf) + lstrlen(szUnusedBuf);
if (GlobalSize(hUnusedBuf) < iReqLen) {
GlobalUnlock(hUnusedBuf);
hUnusedBuf = GlobalReAlloc(hUnusedBuf, iReqLen+sizeof(szBuf), GHND);
if (!hUnusedBuf) {
pushstring("error");
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(newstdout);
CloseHandle(read_stdout);
return;
}
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 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;
}
}
}
else Sleep(LOOPTIMEOUT);
GetExitCodeProcess(pi.hProcess, &dwExit);
if (dwExit != STILL_ACTIVE) {
PeekNamedPipe(read_stdout, 0, 0, 0, &dwRead, NULL);
}
}
if (*szUnusedBuf) LogMessage(szUnusedBuf);
}
else WaitForSingleObject(pi.hProcess, g_to);
wsprintf(szRet,"%d",dwExit);
pushstring(szRet);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(newstdout);
CloseHandle(read_stdout);
if (log) GlobalUnlock(hUnusedBuf);
} }
if (log && *szUnusedBuf) LogMessage(szUnusedBuf);
if (!szRet[0]) wsprintf(szRet,"%d",dwExit);
pushstring(szRet);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(newstdout);
CloseHandle(read_stdout);
if (log) {
GlobalUnlock(hUnusedBuf);
GlobalFree(hUnusedBuf);
}
}
} }
// Tim Kosse's LogMessage // Tim Kosse's LogMessage
void LogMessage(const char *pStr) { void LogMessage(const char *pStr) {
LVITEM item={0}; LVITEM item={0};
int nItemCount; int nItemCount;
if (!g_hwndList) return; if (!g_hwndList) return;
if (!lstrlen(pStr)) return; if (!lstrlen(pStr)) return;
nItemCount=SendMessage(g_hwndList, LVM_GETITEMCOUNT, 0, 0); nItemCount=SendMessage(g_hwndList, LVM_GETITEMCOUNT, 0, 0);
item.mask=LVIF_TEXT; item.mask=LVIF_TEXT;
item.pszText=(char *)pStr; item.pszText=(char *)pStr;
item.cchTextMax=0; item.cchTextMax=0;
item.iItem=nItemCount; item.iItem=nItemCount;
ListView_InsertItem(g_hwndList, &item); ListView_InsertItem(g_hwndList, &item);
ListView_EnsureVisible(g_hwndList, item.iItem, 0); ListView_EnsureVisible(g_hwndList, item.iItem, 0);
} }
char *my_strstr(const char *string, const char *strCharSet) { char *my_strstr(const char *string, const char *strCharSet) {
char *s1, *s2; char *s1, *s2;
size_t chklen; size_t chklen;
size_t i; size_t i;
if (lstrlen(string) < lstrlen(strCharSet)) return 0; if (lstrlen(string) < lstrlen(strCharSet)) return 0;
if (!*strCharSet) return (char*)string; if (!*strCharSet) return (char*)string;
chklen=lstrlen(string)-lstrlen(strCharSet); chklen=lstrlen(string)-lstrlen(strCharSet);
for (i = 0; i <= chklen; i++) { for (i = 0; i <= chklen; i++) {
s1=&((char*)string)[i]; s1=&((char*)string)[i];
s2=(char*)strCharSet; s2=(char*)strCharSet;
while (*s1++ == *s2++) while (*s1++ == *s2++)
if (!*s2) return &((char*)string)[i]; if (!*s2) return &((char*)string)[i];
} }
return 0; return 0;
} }
int my_atoi(char *s) { unsigned int my_atoi(char *s) {
unsigned int v=0; unsigned int v=0;
if (*s == '0' && (s[1] == 'x' || s[1] == 'X')) { if (*s == '0' && (s[1] == 'x' || s[1] == 'X')) {
s+=2; s+=2;
for (;;) { for (;;) {
int c=*s++; int c=*s++;
if (c >= '0' && c <= '9') c-='0'; if (c >= '0' && c <= '9') c-='0';
else if (c >= 'a' && c <= 'f') c-='a'-10; else if (c >= 'a' && c <= 'f') c-='a'-10;
else if (c >= 'A' && c <= 'F') c-='A'-10; else if (c >= 'A' && c <= 'F') c-='A'-10;
else break; else break;
v<<=4; v<<=4;
v+=c; v+=c;
}
} }
else if (*s == '0' && s[1] <= '7' && s[1] >= '0') { }
s++; else if (*s == '0' && s[1] <= '7' && s[1] >= '0') {
for (;;) { s++;
int c=*s++; for (;;) {
if (c >= '0' && c <= '7') c-='0'; int c=*s++;
else break; if (c >= '0' && c <= '7') c-='0';
v<<=3; else break;
v+=c; v<<=3;
} v+=c;
} }
else { }
int sign=0; else {
if (*s == '-') { s++; sign++; } for (;;) {
for (;;) { int c=*s++ - '0';
int c=*s++ - '0'; if (c < 0 || c > 9) break;
if (c < 0 || c > 9) break; v*=10;
v*=10; v+=c;
v+=c;
}
if (sign) return -(int) v;
} }
return (int)v; }
return (int)v;
} }

Binary file not shown.