kernel32: Move AllocConsole to kernelbase.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e43f51640a
commit
2175c7c25e
|
@ -519,176 +519,6 @@ DWORD WINAPI GetConsoleTitleA(LPSTR title, DWORD size)
|
|||
static WCHAR* S_EditString /* = NULL */;
|
||||
static unsigned S_EditStrPos /* = 0 */;
|
||||
|
||||
/******************************************************************
|
||||
* start_console_renderer
|
||||
*
|
||||
* helper for AllocConsole
|
||||
* starts the renderer process
|
||||
*/
|
||||
static BOOL start_console_renderer_helper(const char* appname, STARTUPINFOA* si,
|
||||
HANDLE hEvent)
|
||||
{
|
||||
char buffer[1024];
|
||||
int ret;
|
||||
PROCESS_INFORMATION pi;
|
||||
|
||||
/* FIXME: use dynamic allocation for most of the buffers below */
|
||||
ret = snprintf(buffer, sizeof(buffer), "%s --use-event=%ld", appname, (DWORD_PTR)hEvent);
|
||||
if ((ret > -1) && (ret < sizeof(buffer)) &&
|
||||
CreateProcessA(NULL, buffer, NULL, NULL, TRUE, DETACHED_PROCESS,
|
||||
NULL, NULL, si, &pi))
|
||||
{
|
||||
HANDLE wh[2];
|
||||
DWORD res;
|
||||
|
||||
wh[0] = hEvent;
|
||||
wh[1] = pi.hProcess;
|
||||
res = WaitForMultipleObjects(2, wh, FALSE, INFINITE);
|
||||
|
||||
CloseHandle(pi.hThread);
|
||||
CloseHandle(pi.hProcess);
|
||||
|
||||
if (res != WAIT_OBJECT_0) return FALSE;
|
||||
|
||||
TRACE("Started wineconsole pid=%08x tid=%08x\n",
|
||||
pi.dwProcessId, pi.dwThreadId);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL start_console_renderer(STARTUPINFOA* si)
|
||||
{
|
||||
HANDLE hEvent = 0;
|
||||
LPSTR p;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = 0;
|
||||
attr.Attributes = OBJ_INHERIT;
|
||||
attr.ObjectName = NULL;
|
||||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
|
||||
NtCreateEvent(&hEvent, EVENT_ALL_ACCESS, &attr, NotificationEvent, FALSE);
|
||||
if (!hEvent) return FALSE;
|
||||
|
||||
/* first try environment variable */
|
||||
if ((p = getenv("WINECONSOLE")) != NULL)
|
||||
{
|
||||
ret = start_console_renderer_helper(p, si, hEvent);
|
||||
if (!ret)
|
||||
ERR("Couldn't launch Wine console from WINECONSOLE env var (%s)... "
|
||||
"trying default access\n", p);
|
||||
}
|
||||
|
||||
/* then try the regular PATH */
|
||||
if (!ret)
|
||||
ret = start_console_renderer_helper("wineconsole", si, hEvent);
|
||||
|
||||
CloseHandle(hEvent);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* AllocConsole (KERNEL32.@)
|
||||
*
|
||||
* creates an xterm with a pty to our program
|
||||
*/
|
||||
BOOL WINAPI AllocConsole(void)
|
||||
{
|
||||
HANDLE handle_in = INVALID_HANDLE_VALUE;
|
||||
HANDLE handle_out = INVALID_HANDLE_VALUE;
|
||||
HANDLE handle_err = INVALID_HANDLE_VALUE;
|
||||
STARTUPINFOA siCurrent;
|
||||
STARTUPINFOA siConsole;
|
||||
char buffer[1024];
|
||||
|
||||
TRACE("()\n");
|
||||
|
||||
handle_in = OpenConsoleW( coninW, GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE,
|
||||
FALSE, OPEN_EXISTING );
|
||||
|
||||
if (VerifyConsoleIoHandle(handle_in))
|
||||
{
|
||||
/* we already have a console opened on this process, don't create a new one */
|
||||
CloseHandle(handle_in);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GetStartupInfoA(&siCurrent);
|
||||
|
||||
memset(&siConsole, 0, sizeof(siConsole));
|
||||
siConsole.cb = sizeof(siConsole);
|
||||
/* setup a view arguments for wineconsole (it'll use them as default values) */
|
||||
if (siCurrent.dwFlags & STARTF_USECOUNTCHARS)
|
||||
{
|
||||
siConsole.dwFlags |= STARTF_USECOUNTCHARS;
|
||||
siConsole.dwXCountChars = siCurrent.dwXCountChars;
|
||||
siConsole.dwYCountChars = siCurrent.dwYCountChars;
|
||||
}
|
||||
if (siCurrent.dwFlags & STARTF_USEFILLATTRIBUTE)
|
||||
{
|
||||
siConsole.dwFlags |= STARTF_USEFILLATTRIBUTE;
|
||||
siConsole.dwFillAttribute = siCurrent.dwFillAttribute;
|
||||
}
|
||||
if (siCurrent.dwFlags & STARTF_USESHOWWINDOW)
|
||||
{
|
||||
siConsole.dwFlags |= STARTF_USESHOWWINDOW;
|
||||
siConsole.wShowWindow = siCurrent.wShowWindow;
|
||||
}
|
||||
/* FIXME (should pass the unicode form) */
|
||||
if (siCurrent.lpTitle)
|
||||
siConsole.lpTitle = siCurrent.lpTitle;
|
||||
else if (GetModuleFileNameA(0, buffer, sizeof(buffer)))
|
||||
{
|
||||
buffer[sizeof(buffer) - 1] = '\0';
|
||||
siConsole.lpTitle = buffer;
|
||||
}
|
||||
|
||||
if (!start_console_renderer(&siConsole))
|
||||
goto the_end;
|
||||
|
||||
if( !(siCurrent.dwFlags & STARTF_USESTDHANDLES) ) {
|
||||
/* all std I/O handles are inheritable by default */
|
||||
handle_in = OpenConsoleW( coninW, GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE,
|
||||
TRUE, OPEN_EXISTING );
|
||||
if (handle_in == INVALID_HANDLE_VALUE) goto the_end;
|
||||
|
||||
handle_out = OpenConsoleW( conoutW, GENERIC_READ|GENERIC_WRITE,
|
||||
TRUE, OPEN_EXISTING );
|
||||
if (handle_out == INVALID_HANDLE_VALUE) goto the_end;
|
||||
|
||||
if (!DuplicateHandle(GetCurrentProcess(), handle_out, GetCurrentProcess(),
|
||||
&handle_err, 0, TRUE, DUPLICATE_SAME_ACCESS))
|
||||
goto the_end;
|
||||
} else {
|
||||
/* STARTF_USESTDHANDLES flag: use handles from StartupInfo */
|
||||
handle_in = siCurrent.hStdInput;
|
||||
handle_out = siCurrent.hStdOutput;
|
||||
handle_err = siCurrent.hStdError;
|
||||
}
|
||||
|
||||
/* NT resets the STD_*_HANDLEs on console alloc */
|
||||
SetStdHandle(STD_INPUT_HANDLE, handle_in);
|
||||
SetStdHandle(STD_OUTPUT_HANDLE, handle_out);
|
||||
SetStdHandle(STD_ERROR_HANDLE, handle_err);
|
||||
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
|
||||
return TRUE;
|
||||
|
||||
the_end:
|
||||
ERR("Can't allocate console\n");
|
||||
if (handle_in != INVALID_HANDLE_VALUE) CloseHandle(handle_in);
|
||||
if (handle_out != INVALID_HANDLE_VALUE) CloseHandle(handle_out);
|
||||
if (handle_err != INVALID_HANDLE_VALUE) CloseHandle(handle_err);
|
||||
FreeConsole();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* ReadConsoleA (KERNEL32.@)
|
||||
|
|
|
@ -150,7 +150,7 @@
|
|||
@ stdcall AddVectoredContinueHandler(long ptr) ntdll.RtlAddVectoredContinueHandler
|
||||
@ stdcall AddVectoredExceptionHandler(long ptr) ntdll.RtlAddVectoredExceptionHandler
|
||||
# @ stub AdjustCalendarDate
|
||||
@ stdcall AllocConsole()
|
||||
@ stdcall -import AllocConsole()
|
||||
@ stub -i386 AllocLSCallback
|
||||
@ stdcall -i386 -private AllocSLCallback(ptr ptr) krnl386.exe16.AllocSLCallback
|
||||
@ stdcall -import AllocateUserPhysicalPages(long ptr ptr)
|
||||
|
|
|
@ -198,6 +198,112 @@ BOOL WINAPI DECLSPEC_HOTPATCH AttachConsole( DWORD pid )
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* AllocConsole (kernelbase.@)
|
||||
*/
|
||||
BOOL WINAPI AllocConsole(void)
|
||||
{
|
||||
SECURITY_ATTRIBUTES inheritable_attr = { sizeof(inheritable_attr), NULL, TRUE };
|
||||
HANDLE std_in = INVALID_HANDLE_VALUE;
|
||||
HANDLE std_out = INVALID_HANDLE_VALUE;
|
||||
HANDLE std_err = INVALID_HANDLE_VALUE;
|
||||
STARTUPINFOW app_si, console_si;
|
||||
WCHAR buffer[1024], cmd[256];
|
||||
PROCESS_INFORMATION pi;
|
||||
HANDLE event;
|
||||
DWORD mode;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("()\n");
|
||||
|
||||
std_in = CreateFileW( L"CONIN$", GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 0, NULL, OPEN_EXISTING, 0, 0 );
|
||||
if (GetConsoleMode( std_in, &mode ))
|
||||
{
|
||||
/* we already have a console opened on this process, don't create a new one */
|
||||
CloseHandle( std_in );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GetStartupInfoW(&app_si);
|
||||
|
||||
memset(&console_si, 0, sizeof(console_si));
|
||||
console_si.cb = sizeof(console_si);
|
||||
/* setup a view arguments for wineconsole (it'll use them as default values) */
|
||||
if (app_si.dwFlags & STARTF_USECOUNTCHARS)
|
||||
{
|
||||
console_si.dwFlags |= STARTF_USECOUNTCHARS;
|
||||
console_si.dwXCountChars = app_si.dwXCountChars;
|
||||
console_si.dwYCountChars = app_si.dwYCountChars;
|
||||
}
|
||||
if (app_si.dwFlags & STARTF_USEFILLATTRIBUTE)
|
||||
{
|
||||
console_si.dwFlags |= STARTF_USEFILLATTRIBUTE;
|
||||
console_si.dwFillAttribute = app_si.dwFillAttribute;
|
||||
}
|
||||
if (app_si.dwFlags & STARTF_USESHOWWINDOW)
|
||||
{
|
||||
console_si.dwFlags |= STARTF_USESHOWWINDOW;
|
||||
console_si.wShowWindow = app_si.wShowWindow;
|
||||
}
|
||||
if (app_si.lpTitle)
|
||||
console_si.lpTitle = app_si.lpTitle;
|
||||
else if (GetModuleFileNameW(0, buffer, ARRAY_SIZE(buffer)))
|
||||
{
|
||||
buffer[ARRAY_SIZE(buffer) - 1] = 0;
|
||||
console_si.lpTitle = buffer;
|
||||
}
|
||||
|
||||
if (!(event = CreateEventW( &inheritable_attr, TRUE, FALSE, NULL ))) return FALSE;
|
||||
|
||||
swprintf( cmd, ARRAY_SIZE(cmd), L"wineconsole --use-event=%ld", (DWORD_PTR)event );
|
||||
if ((ret = CreateProcessW( NULL, cmd, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &console_si, &pi )))
|
||||
{
|
||||
HANDLE wait_handles[2] = { event, pi.hProcess };
|
||||
ret = WaitForMultipleObjects( ARRAY_SIZE(wait_handles), wait_handles, FALSE, INFINITE ) == WAIT_OBJECT_0;
|
||||
CloseHandle( pi.hThread );
|
||||
CloseHandle( pi.hProcess );
|
||||
}
|
||||
CloseHandle( event );
|
||||
if (!ret) goto error;
|
||||
TRACE( "Started wineconsole pid=%08x tid=%08x\n", pi.dwProcessId, pi.dwThreadId );
|
||||
|
||||
if (!(app_si.dwFlags & STARTF_USESTDHANDLES))
|
||||
{
|
||||
|
||||
std_in = CreateFileW( L"CONIN$", GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 0, &inheritable_attr,
|
||||
OPEN_EXISTING, 0, 0);
|
||||
if (std_in == INVALID_HANDLE_VALUE) goto error;
|
||||
|
||||
std_out = CreateFileW( L"CONOUT$", GENERIC_READ | GENERIC_WRITE, 0, &inheritable_attr, OPEN_EXISTING, 0, 0);
|
||||
if (std_out == INVALID_HANDLE_VALUE) goto error;
|
||||
|
||||
if (!DuplicateHandle( GetCurrentProcess(), std_out, GetCurrentProcess(),
|
||||
&std_err, 0, TRUE, DUPLICATE_SAME_ACCESS) )
|
||||
goto error;
|
||||
}
|
||||
else
|
||||
{
|
||||
std_in = app_si.hStdInput;
|
||||
std_out = app_si.hStdOutput;
|
||||
std_err = app_si.hStdError;
|
||||
}
|
||||
|
||||
SetStdHandle( STD_INPUT_HANDLE, std_in );
|
||||
SetStdHandle( STD_OUTPUT_HANDLE, std_out );
|
||||
SetStdHandle( STD_ERROR_HANDLE, std_err );
|
||||
SetLastError( ERROR_SUCCESS );
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
ERR("Can't allocate console\n");
|
||||
if (std_in != INVALID_HANDLE_VALUE) CloseHandle(std_in);
|
||||
if (std_out != INVALID_HANDLE_VALUE) CloseHandle(std_out);
|
||||
if (std_err != INVALID_HANDLE_VALUE) CloseHandle(std_err);
|
||||
FreeConsole();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* CreateConsoleScreenBuffer (kernelbase.@)
|
||||
*/
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
@ stdcall AddVectoredExceptionHandler(long ptr) ntdll.RtlAddVectoredExceptionHandler
|
||||
@ stdcall AdjustTokenGroups(long long ptr long ptr ptr)
|
||||
@ stdcall AdjustTokenPrivileges(long long ptr long ptr ptr)
|
||||
@ stdcall AllocConsole() kernel32.AllocConsole
|
||||
@ stdcall AllocConsole()
|
||||
@ stdcall AllocateAndInitializeSid(ptr long long long long long long long long long ptr)
|
||||
@ stdcall AllocateLocallyUniqueId(ptr)
|
||||
@ stdcall AllocateUserPhysicalPages(long ptr ptr)
|
||||
|
|
Loading…
Reference in New Issue