On Monday, 10 Nov 2014 14:46:49 +0100, Jonathan Vollebregt wrote:
I'd still have to use reg_print_error as is because it's there to get the error string from standard error codes like ERROR_INVALID_DATA not to actually format the output string (FORMAT_MESSAGE_FROM_SYSTEM vs FORMAT_MESSAGE_FROM_STRING)
Giving reg_message extra arguments is a good idea, but I'm not sure if we're supposed to have format specifiers in LoadString resources.
I'm not sure whether having output_vprintf is really an advantage over just calling reg_printf since it uses different format specifiers than printf and basically does the same thing (Minus the variable size issue of course)
Format specifiers are perfectly valid in resource strings. See programs/regsvr32/regsvr32.rc as one example.
Not having to deal with variable memory allocation is the obvious advantage of using output_vprintf(). My personal choice would be to convert static const WCHAR nonnumber[] and static const WCHAR unhandled[] to resource strings and using reg_message(). These messages really should be translated anyway.
That leaves the three static const WCHAR stubW[] arrays to consider. Personally, I would remove them. They serve no real purpose and native reg doesn't have anything like them.
As to the getting the error message from the system table, I came up with two possibilities.
static void __cdecl reg_printfW(const WCHAR* msg, ...) { __ms_va_list va_args;
__ms_va_start(va_args, msg); output_vprintf(msg, va_args); __ms_va_end(va_args); }
static void reg_print_error(LSTATUS error_code) { WCHAR *str, *buffer; int len, extra_char = 8; static const WCHAR error_string1[] = {'%','1','!','*','.','*','d','!',':',' ','%','3',0}; static const WCHAR error_string2[] = {'%','0','5','d',':',' ','%','s',0};
len = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, error_code, 0, (LPWSTR)&str, 0, NULL); if (len == 0 && GetLastError() != NO_ERROR) { WINE_FIXME("Could not format system string: le=%u\n", GetLastError()); return; } reg_printfW(error_string1, 0, 5, error_code, str); /* Option 1 - fully automated */ /* Option 2 */ buffer = HeapAlloc(GetProcessHeap(), 0, (len + extra_char) * sizeof(WCHAR)); if (buffer) { sprintfW(buffer, error_string2, error_code, str); output_write(buffer, strlenW(buffer)); HeapFree(GetProcessHeap(), 0, buffer); } LocalFree(str); }