mirror of https://github.com/FreeRDP/FreeRDP
add optional support for win32 console
* add option to build as console by using WITH_WIN_CONSOLE * add passphrase read from stdin for Win32 * fix windows authentication with stdin password * allow redirected stdin to be used for stdin input * flush stdout to help with automation * use stdin when /from-stdin is present * add error log for stdin flag but stdin redirected
This commit is contained in:
parent
0e991a1078
commit
07ea60e960
|
@ -58,6 +58,12 @@ if (WIN32 AND BUILD_SHARED_LIBS)
|
|||
set ( ${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
|
||||
endif()
|
||||
|
||||
if(WITH_WIN_CONSOLE)
|
||||
add_definitions("-DWITH_WIN_CONSOLE")
|
||||
set(WIN32_GUI_FLAG "")
|
||||
else()
|
||||
set(WIN32_GUI_FLAG "WIN32")
|
||||
endif()
|
||||
|
||||
if(WITH_CLIENT_INTERFACE)
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME ${MODULE_NAME}${FREERDP_API_VERSION})
|
||||
|
@ -72,7 +78,7 @@ if(WITH_CLIENT_INTERFACE)
|
|||
|
||||
else()
|
||||
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} cli/wfreerdp.c cli/wfreerdp.h)
|
||||
add_executable(${MODULE_NAME} WIN32 ${${MODULE_PREFIX}_SRCS})
|
||||
add_executable(${MODULE_NAME} ${WIN32_GUI_FLAG} ${${MODULE_PREFIX}_SRCS})
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "wfreerdp")
|
||||
endif()
|
||||
|
|
|
@ -25,6 +25,14 @@ set(${MODULE_PREFIX}_SRCS
|
|||
wfreerdp.h
|
||||
../wfreerdp.rc)
|
||||
|
||||
|
||||
if(WITH_WIN_CONSOLE)
|
||||
add_definitions("-DWITH_WIN_CONSOLE")
|
||||
set(WIN32_GUI_FLAG "")
|
||||
else()
|
||||
set(WIN32_GUI_FLAG "WIN32")
|
||||
endif()
|
||||
|
||||
# On windows create dll version information.
|
||||
# Vendor, product and year are already set in top level CMakeLists.txt
|
||||
if (WIN32)
|
||||
|
@ -40,7 +48,7 @@ if (WIN32)
|
|||
|
||||
set ( ${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
|
||||
endif()
|
||||
add_executable(${MODULE_NAME} WIN32 ${${MODULE_PREFIX}_SRCS})
|
||||
add_executable(${MODULE_NAME} ${WIN32_GUI_FLAG} ${${MODULE_PREFIX}_SRCS})
|
||||
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} wfreerdp-client)
|
||||
|
||||
|
|
|
@ -142,3 +142,10 @@ out:
|
|||
LocalFree(args);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef WITH_WIN_CONSOLE
|
||||
int main()
|
||||
{
|
||||
return WinMain(NULL, NULL, NULL, 0);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <tchar.h>
|
||||
#include <winpr/assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <io.h>
|
||||
|
||||
#include <freerdp/log.h>
|
||||
#include <freerdp/event.h>
|
||||
|
@ -59,28 +60,9 @@
|
|||
|
||||
#define TAG CLIENT_TAG("windows")
|
||||
|
||||
static BOOL wf_create_console(void)
|
||||
static BOOL wf_has_console(void)
|
||||
{
|
||||
#if defined(WITH_WIN_CONSOLE)
|
||||
if (!AttachConsole(ATTACH_PARENT_PROCESS))
|
||||
return FALSE;
|
||||
|
||||
freopen("CONOUT$", "w", stdout);
|
||||
freopen("CONOUT$", "w", stderr);
|
||||
clearerr(stdout);
|
||||
clearerr(stderr);
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
freopen("CONIN$", "r", stdin);
|
||||
clearerr(stdin);
|
||||
|
||||
WLog_INFO(TAG, "Debug console created.");
|
||||
|
||||
return TRUE;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
return _isatty(_fileno(stdin));
|
||||
}
|
||||
|
||||
static BOOL wf_end_paint(rdpContext* context)
|
||||
|
@ -446,24 +428,49 @@ static BOOL wf_authenticate_raw(freerdp* instance, const char* title, char** use
|
|||
dwFlags = CREDUI_FLAGS_DO_NOT_PERSIST | CREDUI_FLAGS_EXCLUDE_CERTIFICATES;
|
||||
|
||||
if (username && *username)
|
||||
strncpy(UserName, *username, CREDUI_MAX_USERNAME_LENGTH);
|
||||
if (wfc->isConsole)
|
||||
status = CredUICmdLinePromptForCredentialsA(
|
||||
title, NULL, 0, UserName, CREDUI_MAX_USERNAME_LENGTH + 1, Password,
|
||||
CREDUI_MAX_PASSWORD_LENGTH + 1, &fSave, dwFlags);
|
||||
else
|
||||
status = CredUIPromptForCredentialsA(&wfUiInfo, title, NULL, 0, UserName,
|
||||
CREDUI_MAX_USERNAME_LENGTH + 1, Password,
|
||||
CREDUI_MAX_PASSWORD_LENGTH + 1, &fSave, dwFlags);
|
||||
|
||||
if (status != NO_ERROR)
|
||||
{
|
||||
WLog_ERR(TAG, "CredUIPromptForCredentials unexpected status: 0x%08lX", status);
|
||||
return FALSE;
|
||||
strncpy(UserName, *username, CREDUI_MAX_USERNAME_LENGTH);
|
||||
strncpy(User, UserName, CREDUI_MAX_USERNAME_LENGTH);
|
||||
}
|
||||
|
||||
status = CredUIParseUserNameA(UserName, User, sizeof(User), Domain, sizeof(Domain));
|
||||
// WLog_ERR(TAG, "User: %s Domain: %s Password: %s", User, Domain, Password);
|
||||
if (password && *password)
|
||||
{
|
||||
strncpy(Password, *password, CREDUI_MAX_PASSWORD_LENGTH);
|
||||
}
|
||||
|
||||
if (domain && *domain)
|
||||
{
|
||||
strncpy(Domain, *domain, CREDUI_MAX_DOMAIN_TARGET_LENGTH);
|
||||
}
|
||||
|
||||
if (!(username && *username && password && *password))
|
||||
{
|
||||
if (!wfc->isConsole && wfc->context.settings->CredentialsFromStdin)
|
||||
WLog_ERR(TAG, "Flag for stdin read present but stdin is redirected; using GUI");
|
||||
if (wfc->isConsole && wfc->context.settings->CredentialsFromStdin)
|
||||
status = CredUICmdLinePromptForCredentialsA(
|
||||
title, NULL, 0, UserName, CREDUI_MAX_USERNAME_LENGTH + 1, Password,
|
||||
CREDUI_MAX_PASSWORD_LENGTH + 1, &fSave, dwFlags);
|
||||
else
|
||||
status = CredUIPromptForCredentialsA(&wfUiInfo, title, NULL, 0, UserName,
|
||||
CREDUI_MAX_USERNAME_LENGTH + 1, Password,
|
||||
CREDUI_MAX_PASSWORD_LENGTH + 1, &fSave, dwFlags);
|
||||
|
||||
if (status != NO_ERROR)
|
||||
{
|
||||
WLog_ERR(TAG, "CredUIPromptForCredentials unexpected status: 0x%08lX", status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
status = CredUIParseUserNameA(UserName, User, CREDUI_MAX_USERNAME_LENGTH, Domain,
|
||||
CREDUI_MAX_DOMAIN_TARGET_LENGTH);
|
||||
if (status != NO_ERROR)
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to parse UserName: %s into User: %s Domain: %s", UserName, User,
|
||||
Domain);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
*username = _strdup(User);
|
||||
|
||||
if (!(*username))
|
||||
|
@ -1031,7 +1038,7 @@ static BOOL wfreerdp_client_new(freerdp* instance, rdpContext* context)
|
|||
|
||||
// AttachConsole and stdin do not work well.
|
||||
// Use GUI input dialogs instead of command line ones.
|
||||
wfc->isConsole = wf_create_console();
|
||||
wfc->isConsole = wf_has_console();
|
||||
|
||||
if (!(wfreerdp_client_global_init()))
|
||||
return FALSE;
|
||||
|
|
|
@ -26,8 +26,73 @@
|
|||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <stdio.h>
|
||||
#include <io.h>
|
||||
|
||||
char read_chr(int isTty)
|
||||
{
|
||||
if (isTty)
|
||||
return _getch();
|
||||
char chr;
|
||||
if (scanf_s("%c", &chr, (UINT32)sizeof(char)) && !feof(stdin))
|
||||
return chr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* freerdp_passphrase_read(const char* prompt, char* buf, size_t bufsiz, int from_stdin)
|
||||
{
|
||||
const char CTRLC = 3;
|
||||
const char BACKSPACE = '\b';
|
||||
const char NEWLINE = '\n';
|
||||
const char CARRIAGERETURN = '\r';
|
||||
const char SHOW_ASTERISK = TRUE;
|
||||
|
||||
if (from_stdin)
|
||||
{
|
||||
printf("%s ", prompt);
|
||||
fflush(stdout);
|
||||
size_t read_cnt = 0, chr;
|
||||
char isTty = _isatty(_fileno(stdin));
|
||||
while (read_cnt < bufsiz - 1 && (chr = read_chr(isTty)) && chr != NEWLINE &&
|
||||
chr != CARRIAGERETURN)
|
||||
{
|
||||
if (chr == BACKSPACE)
|
||||
{
|
||||
if (read_cnt > 0)
|
||||
{
|
||||
if (SHOW_ASTERISK)
|
||||
printf("\b \b");
|
||||
read_cnt--;
|
||||
}
|
||||
}
|
||||
else if (chr == CTRLC)
|
||||
{
|
||||
if (read_cnt != 0)
|
||||
{
|
||||
while (read_cnt > 0)
|
||||
{
|
||||
if (SHOW_ASTERISK)
|
||||
printf("\b \b");
|
||||
read_cnt--;
|
||||
}
|
||||
}
|
||||
else
|
||||
goto fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(buf + read_cnt) = chr;
|
||||
read_cnt++;
|
||||
if (SHOW_ASTERISK)
|
||||
printf("*");
|
||||
}
|
||||
}
|
||||
*(buf + read_cnt) = '\0';
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
return buf;
|
||||
}
|
||||
fail:
|
||||
errno = ENOSYS;
|
||||
return NULL;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue