Index: programs/start/Makefile.in =================================================================== RCS file: /home/wine/wine/programs/start/Makefile.in,v retrieving revision 1.4 diff -u -p -u -r1.4 Makefile.in --- programs/start/Makefile.in 14 Sep 2006 15:11:56 -0000 1.4 +++ programs/start/Makefile.in 25 Oct 2007 08:39:59 -0000 @@ -3,7 +3,7 @@ TOPOBJDIR = ../.. SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = start.exe -APPMODE = -mconsole +APPMODE = -mconsole -municode IMPORTS = shell32 user32 kernel32 C_SRCS = start.c Index: programs/start/start.c =================================================================== RCS file: /home/wine/wine/programs/start/start.c,v retrieving revision 1.7 diff -u -p -u -r1.7 start.c --- programs/start/start.c 16 Jul 2007 21:28:28 -0000 1.7 +++ programs/start/start.c 23 Nov 2007 12:48:30 -0000 @@ -3,6 +3,7 @@ * Compatible with Microsoft's "c:\windows\command\start.exe" * * Copyright 2003 Dan Kegel + * Copyright 2007 Lyutin Anatoly (Etersoft) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,40 +26,45 @@ #include #include +#include +#include + #include "resources.h" +WINE_DEFAULT_DEBUG_CHANNEL(start); + /** Output given message to stdout without formatting. */ -static void output(const char *message) +static void output(const WCHAR *message) { DWORD count; - WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), message, strlen(message), &count, NULL); -} + DWORD res; + int wlen = strlenW(message); -/** - Output given message, - followed by ": ", - followed by description of given GetLastError() value to stdout, - followed by a trailing newline, - then terminate. -*/ -static void fatal_error(const char *msg, DWORD error_code) -{ - LPVOID lpMsgBuf; - int status; + if (!wlen) return; - output(msg); - output(": "); - status = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code, 0, (LPTSTR) & lpMsgBuf, 0, NULL); - if (!status) { - output("FormatMessage failed\n"); - } else { - output(lpMsgBuf); - LocalFree((HLOCAL) lpMsgBuf); - output("\n"); + res = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), message, wlen, &count, NULL); + + /* If writing to console fails, assume its file + i/o so convert to OEM codepage and output */ + if (!res) + { + DWORD len; + char *mesA; + /* Convert to OEM, then output */ + len = WideCharToMultiByte( GetConsoleOutputCP(), 0, message, wlen, NULL, 0, NULL, NULL ); + mesA = HeapAlloc(GetProcessHeap(), 0, len*sizeof(char)); + if (!mesA) + { + WINE_ERR("Out of memory - could not allocate %dK buffer\n", len); + return; + } + + WideCharToMultiByte( GetConsoleOutputCP(), 0, message, wlen, mesA, len, NULL, NULL ); + WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), mesA, len, &count, FALSE); + HeapFree(GetProcessHeap(), 0, mesA); } - ExitProcess(1); } /** @@ -68,24 +74,47 @@ static void fatal_error(const char *msg, followed by a trailing newline, then terminate. */ + +static void fatal_error(const WCHAR *msg, DWORD error_code) +{ + LPVOID lpMsgBuf; + int status; + static const WCHAR colonsW[] = { ':', ' ', 0 }; + static const WCHAR newlineW[] = { '\n', 0 }; + + output(msg); + output(colonsW); + status = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code, 0, (LPWSTR) & lpMsgBuf, 0, NULL); + if (!status) + { + WINE_ERR("FormatMessage failed\n"); + } else + { + output(lpMsgBuf); + LocalFree((HLOCAL) lpMsgBuf); + output(newlineW); + } + ExitProcess(1); +} + static void fatal_string_error(int which, DWORD error_code) { - char msg[2048]; + WCHAR msg[2048]; - if (!LoadString(GetModuleHandle(NULL), which, - msg, sizeof(msg))) - fatal_error("LoadString failed", GetLastError()); + if (!LoadStringW(GetModuleHandle(NULL), which, + msg, sizeof(msg)/sizeof(WCHAR))) + WINE_ERR("LoadString failed, error %d\n", GetLastError()); fatal_error(msg, error_code); } static void fatal_string(int which) { - char msg[2048]; + WCHAR msg[2048]; - if (!LoadString(GetModuleHandle(NULL), which, - msg, sizeof(msg))) - fatal_error("LoadString failed", GetLastError()); + if (!LoadStringW(GetModuleHandle(NULL), which, + msg, sizeof(msg)/sizeof(WCHAR))) + WINE_ERR("LoadString failed, error %d\n", GetLastError()); output(msg); ExitProcess(1); @@ -101,39 +130,43 @@ static void license(void) fatal_string(STRING_LICENSE); } -static char *build_args( int argc, char **argv ) +static WCHAR *build_args( int argc, WCHAR **argvW ) { - int i, len = 1; - char *ret, *p; + int i, wlen = 1; + WCHAR *ret, *p; + static const WCHAR FormatQuotesW[] = { ' ', '\"', '%', 's', '\"', 0 }; + static const WCHAR FormatW[] = { ' ', '%', 's', 0 }; for (i = 0; i < argc; i++ ) { - len += strlen(argv[i]) + 1; - if (strchr(argv[i], ' ')) - len += 2; + wlen += strlenW(argvW[i]) + 1; + if (strchrW(argvW[i], ' ')) + wlen += 2; } - ret = HeapAlloc( GetProcessHeap(), 0, len ); + ret = HeapAlloc( GetProcessHeap(), 0, wlen*sizeof(WCHAR) ); ret[0] = 0; for (i = 0, p = ret; i < argc; i++ ) { - if (strchr(argv[i], ' ')) - p += sprintf(p, " \"%s\"", argv[i]); + if (strchrW(argvW[i], ' ')) + p += sprintfW(p, FormatQuotesW, argvW[i]); else - p += sprintf(p, " %s", argv[i]); + p += sprintfW(p, FormatW, argvW[i]); } return ret; } -int main(int argc, char *argv[]) +int wmain (int argc, WCHAR *argvW[]) { - SHELLEXECUTEINFO sei; - char *args; + SHELLEXECUTEINFOW sei; + WCHAR *args = NULL; int i; + static const WCHAR openW[] = { 'o', 'p', 'e', 'n', 0 }; + memset(&sei, 0, sizeof(sei)); sei.cbSize = sizeof(sei); - sei.lpVerb = "open"; + sei.lpVerb = openW; sei.nShow = SW_SHOWNORMAL; /* Dunno what these mean, but it looks like winMe's start uses them */ sei.fMask = SEE_MASK_FLAG_DDEWAIT| @@ -147,21 +180,21 @@ int main(int argc, char *argv[]) for (i=1; i