Commit 8daef164 authored by Akihiro Sagawa's avatar Akihiro Sagawa Committed by Alexandre Julliard

cmd: Properly handle multibyte characters in batch files.

parent ed9e7455
...@@ -234,31 +234,53 @@ WCHAR *WCMD_fgets(WCHAR *buf, DWORD noChars, HANDLE h) ...@@ -234,31 +234,53 @@ WCHAR *WCMD_fgets(WCHAR *buf, DWORD noChars, HANDLE h)
{ {
DWORD charsRead; DWORD charsRead;
BOOL status; BOOL status;
LARGE_INTEGER filepos;
DWORD i; DWORD i;
/* We can't use the native f* functions because of the filename syntax differences /* We can't use the native f* functions because of the filename syntax differences
between DOS and Unix. Also need to lose the LF (or CRLF) from the line. */ between DOS and Unix. Also need to lose the LF (or CRLF) from the line. */
if (!WCMD_is_console_handle(h)) { if (!WCMD_is_console_handle(h)) {
/* Save current file position */ LARGE_INTEGER filepos;
filepos.QuadPart = 0; char *bufA;
SetFilePointerEx(h, filepos, &filepos, FILE_CURRENT); UINT cp;
} const char *p;
cp = GetConsoleCP();
bufA = HeapAlloc(GetProcessHeap(), 0, noChars);
if (!bufA) return NULL;
/* Save current file position */
filepos.QuadPart = 0;
SetFilePointerEx(h, filepos, &filepos, FILE_CURRENT);
status = ReadFile(h, bufA, noChars, &charsRead, NULL);
if (!status || charsRead == 0) {
HeapFree(GetProcessHeap(), 0, bufA);
return NULL;
}
status = WCMD_ReadFile(h, buf, noChars, &charsRead); /* Find first EOL */
if (!status || charsRead == 0) return NULL; for (p = bufA; p < (bufA + charsRead); p = CharNextExA(cp, p, 0)) {
if (*p == '\n' || *p == '\r')
break;
}
/* Find first EOL */ /* Sets file pointer to the start of the next line, if any */
for (i = 0; i < charsRead; i++) { filepos.QuadPart += p - bufA + 1 + (*p == '\r' ? 1 : 0);
if (buf[i] == '\n' || buf[i] == '\r') SetFilePointerEx(h, filepos, NULL, FILE_BEGIN);
break;
}
if (!WCMD_is_console_handle(h) && i != charsRead) { i = MultiByteToWideChar(cp, 0, bufA, p - bufA, buf, noChars);
/* Sets file pointer to the start of the next line, if any */ HeapFree(GetProcessHeap(), 0, bufA);
filepos.QuadPart += i + 1 + (buf[i] == '\r' ? 1 : 0); }
SetFilePointerEx(h, filepos, NULL, FILE_BEGIN); else {
status = WCMD_ReadFile(h, buf, noChars, &charsRead);
if (!status || charsRead == 0) return NULL;
/* Find first EOL */
for (i = 0; i < charsRead; i++) {
if (buf[i] == '\n' || buf[i] == '\r')
break;
}
} }
/* Truncate at EOL (or end of buffer) */ /* Truncate at EOL (or end of buffer) */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment