Ensure msvcrt's io block is passed down from wcmd's parent process to
child process.
This commit is contained in:
parent
9e96be87ac
commit
81f1ea1c7c
|
@ -43,6 +43,7 @@ const char version_string[] = "WCMD Version 0.17\n\n";
|
||||||
const char anykey[] = "Press Return key to continue: ";
|
const char anykey[] = "Press Return key to continue: ";
|
||||||
char quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH];
|
char quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH];
|
||||||
BATCH_CONTEXT *context = NULL;
|
BATCH_CONTEXT *context = NULL;
|
||||||
|
static HANDLE old_stdin = INVALID_HANDLE_VALUE, old_stdout = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Main entry point. This is a console application so we have a main() not a
|
* Main entry point. This is a console application so we have a main() not a
|
||||||
|
@ -260,7 +261,7 @@ void WCMD_process_command (char *command)
|
||||||
char *cmd, *p;
|
char *cmd, *p;
|
||||||
int status, i, len;
|
int status, i, len;
|
||||||
DWORD count, creationDisposition;
|
DWORD count, creationDisposition;
|
||||||
HANDLE old_stdin = 0, old_stdout = 0, h;
|
HANDLE h;
|
||||||
char *whichcmd;
|
char *whichcmd;
|
||||||
SECURITY_ATTRIBUTES sa;
|
SECURITY_ATTRIBUTES sa;
|
||||||
|
|
||||||
|
@ -465,13 +466,65 @@ void WCMD_process_command (char *command)
|
||||||
WCMD_run_program (whichcmd);
|
WCMD_run_program (whichcmd);
|
||||||
}
|
}
|
||||||
HeapFree( GetProcessHeap(), 0, cmd );
|
HeapFree( GetProcessHeap(), 0, cmd );
|
||||||
if (old_stdin) {
|
if (old_stdin != INVALID_HANDLE_VALUE) {
|
||||||
CloseHandle (GetStdHandle (STD_INPUT_HANDLE));
|
CloseHandle (GetStdHandle (STD_INPUT_HANDLE));
|
||||||
SetStdHandle (STD_INPUT_HANDLE, old_stdin);
|
SetStdHandle (STD_INPUT_HANDLE, old_stdin);
|
||||||
|
old_stdin = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
if (old_stdout) {
|
if (old_stdout != INVALID_HANDLE_VALUE) {
|
||||||
CloseHandle (GetStdHandle (STD_OUTPUT_HANDLE));
|
CloseHandle (GetStdHandle (STD_OUTPUT_HANDLE));
|
||||||
SetStdHandle (STD_OUTPUT_HANDLE, old_stdout);
|
SetStdHandle (STD_OUTPUT_HANDLE, old_stdout);
|
||||||
|
old_stdout = INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_msvcrt_io_block(STARTUPINFO* st)
|
||||||
|
{
|
||||||
|
STARTUPINFO st_p;
|
||||||
|
/* fetch the parent MSVCRT info block if any, so that the child can use the
|
||||||
|
* same handles as its grand-father
|
||||||
|
*/
|
||||||
|
st_p.cb = sizeof(STARTUPINFO);
|
||||||
|
GetStartupInfo(&st_p);
|
||||||
|
st->cbReserved2 = st_p.cbReserved2;
|
||||||
|
st->lpReserved2 = st_p.lpReserved2;
|
||||||
|
if (st_p.cbReserved2 && st_p.lpReserved2 &&
|
||||||
|
(old_stdin != INVALID_HANDLE_VALUE || old_stdout != INVALID_HANDLE_VALUE))
|
||||||
|
{
|
||||||
|
/* Override the entries for fd 0,1,2 if we happened
|
||||||
|
* to change those std handles (this depends on the way wcmd sets
|
||||||
|
* it's new input & output handles)
|
||||||
|
*/
|
||||||
|
size_t sz = max(sizeof(unsigned) + (sizeof(char) + sizeof(HANDLE)) * 3, st_p.cbReserved2);
|
||||||
|
char* ptr = HeapAlloc(GetProcessHeap(), 0, sz);
|
||||||
|
if (ptr)
|
||||||
|
{
|
||||||
|
unsigned num = *(unsigned*)st_p.lpReserved2;
|
||||||
|
char* flags = (char*)(ptr + sizeof(unsigned));
|
||||||
|
HANDLE* handles = (HANDLE*)(flags + num * sizeof(char));
|
||||||
|
|
||||||
|
memcpy(ptr, st_p.lpReserved2, st_p.cbReserved2);
|
||||||
|
st->cbReserved2 = sz;
|
||||||
|
st->lpReserved2 = ptr;
|
||||||
|
|
||||||
|
#define WX_OPEN 0x01 /* see dlls/msvcrt/file.c */
|
||||||
|
if (num <= 0 || (flags[0] & WX_OPEN))
|
||||||
|
{
|
||||||
|
handles[0] = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
|
flags[0] |= WX_OPEN;
|
||||||
|
}
|
||||||
|
if (num <= 1 || (flags[1] & WX_OPEN))
|
||||||
|
{
|
||||||
|
handles[1] = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
flags[1] |= WX_OPEN;
|
||||||
|
}
|
||||||
|
if (num <= 2 || (flags[2] & WX_OPEN))
|
||||||
|
{
|
||||||
|
handles[2] = GetStdHandle(STD_ERROR_HANDLE);
|
||||||
|
flags[2] |= WX_OPEN;
|
||||||
|
}
|
||||||
|
#undef WX_OPEN
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,6 +601,8 @@ char filetorun[MAX_PATH];
|
||||||
console = SHGetFileInfo (filetorun, 0, &psfi, sizeof(psfi), SHGFI_EXETYPE);
|
console = SHGetFileInfo (filetorun, 0, &psfi, sizeof(psfi), SHGFI_EXETYPE);
|
||||||
ZeroMemory (&st, sizeof(STARTUPINFO));
|
ZeroMemory (&st, sizeof(STARTUPINFO));
|
||||||
st.cb = sizeof(STARTUPINFO);
|
st.cb = sizeof(STARTUPINFO);
|
||||||
|
init_msvcrt_io_block(&st);
|
||||||
|
|
||||||
status = CreateProcess (NULL, command, NULL, NULL, TRUE,
|
status = CreateProcess (NULL, command, NULL, NULL, TRUE,
|
||||||
0, NULL, NULL, &st, &pe);
|
0, NULL, NULL, &st, &pe);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
|
|
Loading…
Reference in New Issue