Fixes to Unicode issues in scp and sftp

This commit is contained in:
Manoj Ampalam 2016-11-06 15:13:11 -08:00
parent 5c02287fd8
commit 6411a23af7
6 changed files with 39 additions and 29 deletions

Binary file not shown.

View File

@ -398,7 +398,7 @@ void SizeWindow(HANDLE hInput) {
matchingFont.FontWeight = FW_NORMAL; matchingFont.FontWeight = FW_NORMAL;
wcscpy(matchingFont.FaceName, L"Consolas"); wcscpy(matchingFont.FaceName, L"Consolas");
bSuccess = SetCurrentConsoleFontEx(child_out, FALSE, &matchingFont); bSuccess = __SetCurrentConsoleFontEx(child_out, FALSE, &matchingFont);
// This information is the live screen // This information is the live screen
ZeroMemory(&consoleInfo, sizeof(consoleInfo)); ZeroMemory(&consoleInfo, sizeof(consoleInfo));
@ -1069,6 +1069,15 @@ int start_with_pty(int ac, wchar_t **av) {
HANDLE hEventHook = NULL; HANDLE hEventHook = NULL;
HMODULE hm_kernel32 = NULL, hm_user32 = NULL; HMODULE hm_kernel32 = NULL, hm_user32 = NULL;
if ((hm_kernel32 = LoadLibraryW(L"kernel32.dll")) == NULL ||
(hm_user32 = LoadLibraryW(L"user32.dll")) == NULL ||
(__SetCurrentConsoleFontEx = (__t_SetCurrentConsoleFontEx)GetProcAddress(hm_kernel32, "SetCurrentConsoleFontEx")) == NULL ||
(__UnhookWinEvent = (__t_UnhookWinEvent)GetProcAddress(hm_user32, "UnhookWinEvent")) == NULL ||
(__SetWinEventHook = (__t_SetWinEventHook)GetProcAddress(hm_user32, "SetWinEventHook")) == NULL) {
printf("cannot support a pseudo terminal. \n");
return -1;
}
pipe_in = GetStdHandle(STD_INPUT_HANDLE); pipe_in = GetStdHandle(STD_INPUT_HANDLE);
pipe_out = GetStdHandle(STD_OUTPUT_HANDLE); pipe_out = GetStdHandle(STD_OUTPUT_HANDLE);
pipe_err = GetStdHandle(STD_ERROR_HANDLE); pipe_err = GetStdHandle(STD_ERROR_HANDLE);
@ -1093,7 +1102,7 @@ int start_with_pty(int ac, wchar_t **av) {
InitializeCriticalSection(&criticalSection); InitializeCriticalSection(&criticalSection);
hEventHook = SetWinEventHook(EVENT_CONSOLE_CARET, EVENT_CONSOLE_LAYOUT, NULL, hEventHook = __SetWinEventHook(EVENT_CONSOLE_CARET, EVENT_CONSOLE_LAYOUT, NULL,
ConsoleEventProc, 0, 0, WINEVENT_OUTOFCONTEXT); ConsoleEventProc, 0, 0, WINEVENT_OUTOFCONTEXT);
memset(&si, 0, sizeof(STARTUPINFO)); memset(&si, 0, sizeof(STARTUPINFO));
@ -1168,7 +1177,7 @@ cleanup:
if (ux_thread != INVALID_HANDLE_VALUE) if (ux_thread != INVALID_HANDLE_VALUE)
TerminateThread(ux_thread, S_OK); TerminateThread(ux_thread, S_OK);
if (hEventHook) if (hEventHook)
UnhookWinEvent(hEventHook); __UnhookWinEvent(hEventHook);
FreeConsole(); FreeConsole();

View File

@ -240,7 +240,6 @@ refresh_progress_meter(void)
#ifdef WINDOWS #ifdef WINDOWS
wchar_t* wtmp = utf8_to_utf16(buf); wchar_t* wtmp = utf8_to_utf16(buf);
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wtmp, wcslen(wtmp), 0, 0); WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), wtmp, wcslen(wtmp), 0, 0);
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L"\n", 1, 0, 0);
free(wtmp); free(wtmp);
#else #else
atomicio(vwrite, STDOUT_FILENO, buf, win_size - 1); atomicio(vwrite, STDOUT_FILENO, buf, win_size - 1);

16
scp.c
View File

@ -924,7 +924,9 @@ main(int argc, char **argv)
*/ */
w32posix_initialize(); w32posix_initialize();
ConInit(STD_OUTPUT_HANDLE, TRUE); /*scp is invoked on client side*/
if (!(argc >= 2 && ( strcmp(argv[1], "-f" ) == 0 || strcmp(argv[1], "-t") == 0 )))
ConInit(STD_OUTPUT_HANDLE, TRUE);
#endif #endif
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
@ -2037,7 +2039,7 @@ int start_process_io(char *exename, char **argv, char **envv,
char *homedir, char *lpDesktop) char *homedir, char *lpDesktop)
{ {
UNREFERENCED_PARAMETER(envv); UNREFERENCED_PARAMETER(envv);
STARTUPINFO sui; STARTUPINFOW sui;
DWORD ret; DWORD ret;
char cmdbuf[2048]; char cmdbuf[2048];
int ctr; int ctr;
@ -2047,7 +2049,7 @@ int start_process_io(char *exename, char **argv, char **envv,
*/ */
sui.cb = sizeof(STARTUPINFO); sui.cb = sizeof(STARTUPINFO);
sui.lpReserved = 0; sui.lpReserved = 0;
sui.lpDesktop = lpDesktop; sui.lpDesktop = utf8_to_utf16(lpDesktop);
sui.lpTitle = NULL; /* NULL means use exe name as title */ sui.lpTitle = NULL; /* NULL means use exe name as title */
sui.dwX = 0; sui.dwX = 0;
sui.dwY = 0; sui.dwY = 0;
@ -2076,9 +2078,9 @@ int start_process_io(char *exename, char **argv, char **envv,
ctr++; ctr++;
} }
ret = CreateProcess( ret = CreateProcessW(
exename, // given in form like "d:\\util\\cmd.exe" utf8_to_utf16(exename), // given in form like "d:\\util\\cmd.exe"
cmdbuf, /* in "arg0 arg1 arg2" form command line */ utf8_to_utf16(cmdbuf), /* in "arg0 arg1 arg2" form command line */
NULL, /* process security */ NULL, /* process security */
NULL, /* thread security */ NULL, /* thread security */
TRUE, /* inherit handles is YES */ TRUE, /* inherit handles is YES */
@ -2086,7 +2088,7 @@ int start_process_io(char *exename, char **argv, char **envv,
/* give new proc a new screen, suspend it for debugging also */ /* give new proc a new screen, suspend it for debugging also */
NULL, /* in "E1=a0E2=b0E3=c00" form environment, NULL, /* in "E1=a0E2=b0E3=c00" form environment,
NULL means use parent's */ NULL means use parent's */
homedir, /* Current Directory, NULL means use whats for parent */ utf8_to_utf16(homedir), /* Current Directory, NULL means use whats for parent */
&sui, /* start up info */ &sui, /* start up info */
pi); /* process created info kept here */ pi); /* process created info kept here */

View File

@ -444,7 +444,7 @@ typedef struct _REPARSE_DATA_BUFFER {
}; };
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
BOOL ResolveLink(char * tLink, char *ret, DWORD * plen, DWORD Flags) BOOL ResolveLink(wchar_t * tLink, wchar_t *ret, DWORD * plen, DWORD Flags)
{ {
HANDLE fileHandle; HANDLE fileHandle;
BYTE reparseBuffer[MAX_REPARSE_SIZE]; BYTE reparseBuffer[MAX_REPARSE_SIZE];
@ -455,7 +455,7 @@ BOOL ResolveLink(char * tLink, char *ret, DWORD * plen, DWORD Flags)
if (Flags & FILE_ATTRIBUTE_DIRECTORY) if (Flags & FILE_ATTRIBUTE_DIRECTORY)
{ {
fileHandle = CreateFile(tLink, 0, fileHandle = CreateFileW(tLink, 0,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0); FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0);
@ -466,18 +466,18 @@ BOOL ResolveLink(char * tLink, char *ret, DWORD * plen, DWORD Flags)
// //
// Open the file // Open the file
// //
fileHandle = CreateFile(tLink, 0, fileHandle = CreateFileW(tLink, 0,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, OPEN_EXISTING,
FILE_FLAG_OPEN_REPARSE_POINT, 0); FILE_FLAG_OPEN_REPARSE_POINT, 0);
} }
if (fileHandle == INVALID_HANDLE_VALUE) if (fileHandle == INVALID_HANDLE_VALUE)
{ {
sprintf_s(ret, *plen, "%s", tLink); swprintf_s(ret, *plen, L"%ls", tLink);
return TRUE; return TRUE;
} }
if (GetFileAttributes(tLink) & FILE_ATTRIBUTE_REPARSE_POINT) { if (GetFileAttributesW(tLink) & FILE_ATTRIBUTE_REPARSE_POINT) {
if (DeviceIoControl(fileHandle, FSCTL_GET_REPARSE_POINT, if (DeviceIoControl(fileHandle, FSCTL_GET_REPARSE_POINT,
NULL, 0, reparseInfo, sizeof(reparseBuffer), NULL, 0, reparseInfo, sizeof(reparseBuffer),
@ -496,11 +496,11 @@ BOOL ResolveLink(char * tLink, char *ret, DWORD * plen, DWORD Flags)
(PWCHAR)(reparseData + msReparseInfo->MountPointReparseBuffer.SubstituteNameOffset), (PWCHAR)(reparseData + msReparseInfo->MountPointReparseBuffer.SubstituteNameOffset),
(size_t)msReparseInfo->MountPointReparseBuffer.SubstituteNameLength); (size_t)msReparseInfo->MountPointReparseBuffer.SubstituteNameLength);
temp[msReparseInfo->MountPointReparseBuffer.SubstituteNameLength] = 0; temp[msReparseInfo->MountPointReparseBuffer.SubstituteNameLength] = 0;
sprintf_s(ret, *plen, "%S", &temp[4]); swprintf_s(ret, *plen, L"%ls", &temp[4]);
} }
else else
{ {
sprintf_s(ret, *plen, "%s", tLink); swprintf_s(ret, *plen, L"%ls", tLink);
return FALSE; return FALSE;
} }
@ -512,7 +512,7 @@ BOOL ResolveLink(char * tLink, char *ret, DWORD * plen, DWORD Flags)
} }
} }
else { else {
sprintf_s(ret, *plen, "%s", tLink); swprintf_s(ret, *plen, L"%ls", tLink);
} }
CloseHandle(fileHandle); CloseHandle(fileHandle);
@ -521,30 +521,30 @@ BOOL ResolveLink(char * tLink, char *ret, DWORD * plen, DWORD Flags)
char * get_inside_path(char * opath, BOOL bResolve, BOOL bMustExist) char * get_inside_path(char * opath, BOOL bResolve, BOOL bMustExist)
{ {
BOOL ResolveLink(char * tLink, char *ret, DWORD * plen, DWORD Flags);
char * ipath; char * ipath;
char * temp_name; char * temp_name;
char temp[1024]; wchar_t temp[1024];
DWORD templen = sizeof(temp); DWORD templen = 1024;
WIN32_FILE_ATTRIBUTE_DATA FileInfo; WIN32_FILE_ATTRIBUTE_DATA FileInfo;
wchar_t* opath_w = utf8_to_utf16(opath);
if (!GetFileAttributesEx(opath, GetFileExInfoStandard, &FileInfo) && bMustExist) if (!GetFileAttributesExW(opath_w, GetFileExInfoStandard, &FileInfo) && bMustExist)
{ {
free(opath_w);
return NULL; return NULL;
} }
if (bResolve) if (bResolve)
{ {
ResolveLink(opath, temp, &templen, FileInfo.dwFileAttributes); ResolveLink(opath_w, temp, &templen, FileInfo.dwFileAttributes);
ipath = xstrdup(temp); ipath = utf16_to_utf8(temp);
} }
else else
{ {
ipath = xstrdup(opath); ipath = xstrdup(opath);
} }
free(opath_w);
return ipath; return ipath;
} }

4
sftp.c
View File

@ -2393,7 +2393,7 @@ connect_to_server(char *path, char **args, int *in, int *out)
char fullCmd[MAX_PATH] = { 0 }; char fullCmd[MAX_PATH] = { 0 };
char ioArg[1024] = { 0 }; char ioArg[1024] = { 0 };
PROCESS_INFORMATION pi = { 0 }; PROCESS_INFORMATION pi = { 0 };
STARTUPINFO si = { 0 }; STARTUPINFOW si = { 0 };
debug3("Generating ssh-client command..."); debug3("Generating ssh-client command...");
fullCmd[0] = '\0'; fullCmd[0] = '\0';
@ -2428,7 +2428,7 @@ connect_to_server(char *path, char **args, int *in, int *out)
debug("Executing ssh client: \"%.500s\"...\n", fullCmd); debug("Executing ssh client: \"%.500s\"...\n", fullCmd);
if (CreateProcessA(NULL, fullCmd, NULL, NULL, TRUE, if (CreateProcessW(NULL, utf8_to_utf16(fullCmd), NULL, NULL, TRUE,
NORMAL_PRIORITY_CLASS, NULL, NORMAL_PRIORITY_CLASS, NULL,
NULL, &si, &pi) == TRUE) { NULL, &si, &pi) == TRUE) {
sshpid = pi.dwProcessId; sshpid = pi.dwProcessId;