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 WCHAR* S_EditString /* = NULL */;
|
||||||
static unsigned S_EditStrPos /* = 0 */;
|
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.@)
|
* ReadConsoleA (KERNEL32.@)
|
||||||
|
|
|
@ -150,7 +150,7 @@
|
||||||
@ stdcall AddVectoredContinueHandler(long ptr) ntdll.RtlAddVectoredContinueHandler
|
@ stdcall AddVectoredContinueHandler(long ptr) ntdll.RtlAddVectoredContinueHandler
|
||||||
@ stdcall AddVectoredExceptionHandler(long ptr) ntdll.RtlAddVectoredExceptionHandler
|
@ stdcall AddVectoredExceptionHandler(long ptr) ntdll.RtlAddVectoredExceptionHandler
|
||||||
# @ stub AdjustCalendarDate
|
# @ stub AdjustCalendarDate
|
||||||
@ stdcall AllocConsole()
|
@ stdcall -import AllocConsole()
|
||||||
@ stub -i386 AllocLSCallback
|
@ stub -i386 AllocLSCallback
|
||||||
@ stdcall -i386 -private AllocSLCallback(ptr ptr) krnl386.exe16.AllocSLCallback
|
@ stdcall -i386 -private AllocSLCallback(ptr ptr) krnl386.exe16.AllocSLCallback
|
||||||
@ stdcall -import AllocateUserPhysicalPages(long ptr ptr)
|
@ 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.@)
|
* CreateConsoleScreenBuffer (kernelbase.@)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
@ stdcall AddVectoredExceptionHandler(long ptr) ntdll.RtlAddVectoredExceptionHandler
|
@ stdcall AddVectoredExceptionHandler(long ptr) ntdll.RtlAddVectoredExceptionHandler
|
||||||
@ stdcall AdjustTokenGroups(long long ptr long ptr ptr)
|
@ stdcall AdjustTokenGroups(long long ptr long ptr ptr)
|
||||||
@ stdcall AdjustTokenPrivileges(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 AllocateAndInitializeSid(ptr long long long long long long long long long ptr)
|
||||||
@ stdcall AllocateLocallyUniqueId(ptr)
|
@ stdcall AllocateLocallyUniqueId(ptr)
|
||||||
@ stdcall AllocateUserPhysicalPages(long ptr ptr)
|
@ stdcall AllocateUserPhysicalPages(long ptr ptr)
|
||||||
|
|
Loading…
Reference in New Issue