nsExec create a temp console app to spawn commands, can run applications with user interface and also 16bit DOS
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@2765 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
a3c887d456
commit
f7f575a8cb
2 changed files with 102 additions and 39 deletions
|
@ -20,6 +20,7 @@ freely, subject to the following restrictions:
|
|||
*/
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include <Winnt.h>
|
||||
#include "../exdll/exdll.h"
|
||||
|
||||
#ifndef true
|
||||
|
@ -35,12 +36,10 @@ HWND g_hwndList;
|
|||
char * g_exec;
|
||||
unsigned int g_to;
|
||||
|
||||
|
||||
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;
|
||||
|
@ -66,54 +65,77 @@ void __declspec(dllexport) ExecToStack(HWND hwndParent, int string_size, char *v
|
|||
}
|
||||
}
|
||||
|
||||
HINSTANCE g_hInst;
|
||||
BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) {
|
||||
g_hInst = hInst;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define TAB_REPLACE " "
|
||||
#define TAB_REPLACE_SIZE (sizeof(TAB_REPLACE)-1)
|
||||
|
||||
// Turn a pair of chars into a word
|
||||
// Turn four chars into a dword
|
||||
#ifdef __BIG_ENDIAN__ // Not very likely, but, still...
|
||||
#define CHAR2_TO_WORD(a,b) (((WORD)(b))|((a)<<8))
|
||||
#define CHAR4_TO_DWORD(a,b,c,d) (((DWORD)CHAR2_TO_WORD(c,d))|(CHAR2_TO_WORD(a,b)<<16))
|
||||
#else
|
||||
#define CHAR2_TO_WORD(a,b) (((WORD)(a))|((b)<<8))
|
||||
#define CHAR4_TO_DWORD(a,b,c,d) (((DWORD)CHAR2_TO_WORD(a,b))|(CHAR2_TO_WORD(c,d)<<16))
|
||||
#endif
|
||||
|
||||
void ExecScript(int log) {
|
||||
char szRet[128] = "";
|
||||
char *pExec;
|
||||
char sAux[MAX_PATH];
|
||||
char *pRoot = NULL;
|
||||
int nComSpecSize;
|
||||
BOOL bUseComSpec=false;
|
||||
char meDLLPath[MAX_PATH];
|
||||
char *p;
|
||||
|
||||
nComSpecSize = GetModuleFileName(g_hInst, meDLLPath, MAX_PATH);
|
||||
p = meDLLPath + nComSpecSize - 1;
|
||||
g_exec = (char *)GlobalAlloc(GPTR, sizeof(char)*g_stringsize+nComSpecSize+1);
|
||||
|
||||
while ( *p && *p != '\\' )
|
||||
p--;
|
||||
if ( p )
|
||||
*p = 0;
|
||||
GetTempFileName(meDLLPath, "ns", 0, g_exec);
|
||||
*p = '\\';
|
||||
if ( CopyFile(meDLLPath, g_exec, FALSE) )
|
||||
{
|
||||
HANDLE hFile, hMapping;
|
||||
PIMAGE_NT_HEADERS pNTHeaders;
|
||||
hFile = CreateFile(g_exec, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING,0, 0);
|
||||
hMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
|
||||
pNTHeaders = (PIMAGE_NT_HEADERS)MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, 0);
|
||||
if ( pNTHeaders )
|
||||
{
|
||||
pNTHeaders = (PIMAGE_NT_HEADERS)((BYTE*)pNTHeaders + ((PIMAGE_DOS_HEADER)pNTHeaders)->e_lfanew);
|
||||
pNTHeaders->FileHeader.Characteristics = IMAGE_FILE_32BIT_MACHINE | IMAGE_FILE_LOCAL_SYMS_STRIPPED |
|
||||
IMAGE_FILE_LINE_NUMS_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_RELOCS_STRIPPED;
|
||||
pNTHeaders->OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
|
||||
pNTHeaders->OptionalHeader.AddressOfEntryPoint = (DWORD)WinMain - (DWORD)g_hInst;
|
||||
UnmapViewOfFile(pNTHeaders);
|
||||
}
|
||||
CloseHandle(hMapping);
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
|
||||
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+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);
|
||||
}
|
||||
else if (my_strstr(g_exec,"/CMD")) {
|
||||
bUseComSpec = true;
|
||||
}
|
||||
else
|
||||
break;
|
||||
pExec = g_exec + nComSpecSize - 1; *pExec = ' '; pExec++;
|
||||
popstring(pExec);
|
||||
if ( my_strstr(pExec, "/TIMEOUT=") ) {
|
||||
char *szTimeout = pExec + 9;
|
||||
g_to = my_atoi(szTimeout);
|
||||
popstring(pExec);
|
||||
}
|
||||
|
||||
if (!pExec[0] )
|
||||
if (!g_exec[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),};
|
||||
|
@ -143,7 +165,8 @@ void ExecScript(int log) {
|
|||
SetSecurityDescriptorDacl(&sd,true,NULL,false);
|
||||
sa.lpSecurityDescriptor = &sd;
|
||||
}
|
||||
else sa.lpSecurityDescriptor = NULL;
|
||||
else
|
||||
sa.lpSecurityDescriptor = NULL;
|
||||
sa.bInheritHandle = true;
|
||||
if (!CreatePipe(&read_stdout,&newstdout,&sa,0)) {
|
||||
lstrcpy(szRet, "error");
|
||||
|
@ -156,7 +179,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,0,NULL,pRoot,&si,&pi)) {
|
||||
if (!CreateProcess(NULL,g_exec,NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi)) {
|
||||
lstrcpy(szRet, "error");
|
||||
goto done;
|
||||
}
|
||||
|
@ -190,7 +213,14 @@ void ExecScript(int log) {
|
|||
if (!(log & 2)) {
|
||||
while ( p = my_strstr(p, "\t") )
|
||||
{
|
||||
mini_memcpy(p+TAB_REPLACE_SIZE, p+1, lstrlen(p));
|
||||
int len = lstrlen(p);
|
||||
char *c_out=(char*)p+TAB_REPLACE_SIZE+(len-1);
|
||||
char *c_in=(char *)p+1+(len-1);
|
||||
while (len-- > 0)
|
||||
{
|
||||
*c_out--=*c_in--;
|
||||
}
|
||||
|
||||
lstrcpy(p, TAB_REPLACE);
|
||||
p += TAB_REPLACE_SIZE;
|
||||
*p = ' ';
|
||||
|
@ -227,6 +257,8 @@ void ExecScript(int log) {
|
|||
done:
|
||||
if (log & 2) pushstring(szUnusedBuf);
|
||||
if (log & 1 && *szUnusedBuf) LogMessage(szUnusedBuf);
|
||||
if ( dwExit == STATUS_ILLEGAL_INSTRUCTION )
|
||||
lstrcpy(szRet, "error");
|
||||
if (!szRet[0]) wsprintf(szRet,"%d",dwExit);
|
||||
pushstring(szRet);
|
||||
CloseHandle(pi.hThread);
|
||||
|
@ -308,13 +340,44 @@ unsigned int my_atoi(char *s) {
|
|||
return (int)v;
|
||||
}
|
||||
|
||||
void * mini_memcpy(void *outBuf, const void *inBuf, int len)
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
||||
{
|
||||
char *c_out=(char*)outBuf+(len-1);
|
||||
char *c_in=(char *)inBuf+(len-1);
|
||||
while (len-- > 0)
|
||||
DWORD Ret;
|
||||
STARTUPINFO si = {0};
|
||||
PROCESS_INFORMATION pi = {0};
|
||||
char command_line[1024];
|
||||
char seekchar=' ';
|
||||
char *cmdline;
|
||||
|
||||
si.cb = sizeof(si);
|
||||
// Make child process use this app's standard files. Not needed !??
|
||||
//si.dwFlags = STARTF_USESTDHANDLES;
|
||||
//si.hStdInput = GetStdHandle (STD_INPUT_HANDLE);
|
||||
//si.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
|
||||
//si.hStdError = GetStdHandle (STD_ERROR_HANDLE);
|
||||
lstrcpyn(command_line, GetCommandLine(), 1024);
|
||||
|
||||
cmdline = command_line;
|
||||
if (*cmdline == '\"') seekchar = *cmdline++;
|
||||
|
||||
while (*cmdline && *cmdline != seekchar) cmdline=CharNext(cmdline);
|
||||
cmdline=CharNext(cmdline);
|
||||
|
||||
Ret = CreateProcess (NULL, cmdline,
|
||||
NULL, NULL,
|
||||
TRUE, 0,
|
||||
NULL, NULL,
|
||||
&si, &pi
|
||||
);
|
||||
|
||||
if (Ret)
|
||||
{
|
||||
*c_out--=*c_in--;
|
||||
WaitForSingleObject (pi.hProcess, INFINITE);
|
||||
GetExitCodeProcess(pi.hProcess, &Ret);
|
||||
CloseHandle (pi.hProcess);
|
||||
CloseHandle (pi.hThread);
|
||||
return Ret;
|
||||
}
|
||||
return outBuf;
|
||||
else
|
||||
return STATUS_ILLEGAL_INSTRUCTION;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue