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,18 +234,45 @@ WCHAR *WCMD_fgets(WCHAR *buf, DWORD noChars, HANDLE h) ...@@ -234,18 +234,45 @@ 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)) {
LARGE_INTEGER filepos;
char *bufA;
UINT cp;
const char *p;
cp = GetConsoleCP();
bufA = HeapAlloc(GetProcessHeap(), 0, noChars);
if (!bufA) return NULL;
/* Save current file position */ /* Save current file position */
filepos.QuadPart = 0; filepos.QuadPart = 0;
SetFilePointerEx(h, filepos, &filepos, FILE_CURRENT); SetFilePointerEx(h, filepos, &filepos, FILE_CURRENT);
status = ReadFile(h, bufA, noChars, &charsRead, NULL);
if (!status || charsRead == 0) {
HeapFree(GetProcessHeap(), 0, bufA);
return NULL;
}
/* Find first EOL */
for (p = bufA; p < (bufA + charsRead); p = CharNextExA(cp, p, 0)) {
if (*p == '\n' || *p == '\r')
break;
} }
/* Sets file pointer to the start of the next line, if any */
filepos.QuadPart += p - bufA + 1 + (*p == '\r' ? 1 : 0);
SetFilePointerEx(h, filepos, NULL, FILE_BEGIN);
i = MultiByteToWideChar(cp, 0, bufA, p - bufA, buf, noChars);
HeapFree(GetProcessHeap(), 0, bufA);
}
else {
status = WCMD_ReadFile(h, buf, noChars, &charsRead); status = WCMD_ReadFile(h, buf, noChars, &charsRead);
if (!status || charsRead == 0) return NULL; if (!status || charsRead == 0) return NULL;
...@@ -254,11 +281,6 @@ WCHAR *WCMD_fgets(WCHAR *buf, DWORD noChars, HANDLE h) ...@@ -254,11 +281,6 @@ WCHAR *WCMD_fgets(WCHAR *buf, DWORD noChars, HANDLE h)
if (buf[i] == '\n' || buf[i] == '\r') if (buf[i] == '\n' || buf[i] == '\r')
break; break;
} }
if (!WCMD_is_console_handle(h) && i != charsRead) {
/* Sets file pointer to the start of the next line, if any */
filepos.QuadPart += i + 1 + (buf[i] == '\r' ? 1 : 0);
SetFilePointerEx(h, filepos, NULL, FILE_BEGIN);
} }
/* 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